【问题标题】:Java REST client without schema没有架构的 Java REST 客户端
【发布时间】:2008-12-11 15:15:14
【问题描述】:

目标

雅虎 HotJobs 的 Java 客户端 Resumé Search REST API

背景

我习惯于为 SOAP API 编写 Web 服务客户端,其中wsimport 生成代理存根,而您正在运行。但这是一个 REST API,对我来说是新的。

详情

进展

我查看了问题 Rest clients for Java?,但那里的自动化解决方案假定您同时提供服务器和客户端,并在 POJO 上调用 JAXB 以生成架构和 REST API。

使用JerseyJAX-RS 实现),我已经能够发出手动 HTTP 请求:

import com.sun.jersey.api.client.*;

...

ClientConfig clientConfig = new DefaultClientConfig();
Client client = Client.create(clientConfig);

WebResource webResource = client.resource("https://hj.yahooapis.com/v1/HJAuthTokens");
webResource.accept("application/xml");

// body is a hard-coded string, with replacements for the variable bits
String response = webResource.post(String.class, body);

// parse response into a org.w3c.dom.Document
// interface with Document via XPATH, or write my own POJO mappings

响应可能如下所示:

<?xml version="1.0" encoding="utf-8"?>   
<Response>   
    <ResponseCode>0</ResponseCode>   
    <ResponseMessage>Login successful</ResponseMessage>
    <Token>NTlEMTdFNjk3Qjg4NUJBNDA3MkJFOTI3NzJEMTdDNDU7bG9jYWxob3N0LmVnbGJwLmNvcnAueWFob28uY29tO0pVNWpzRGRhN3VhSS4yQVRqRi4wWE5jTWl0RHVVYzQyX3luYWd1TjIxaGx6U0lhTXN3LS07NjY2MzM1OzIzNDY3NTsxMjA5MDE2OTE5OzZCM1RBMVNudHdLbl9VdFFKMFEydWctLQ==</Token>   
</Response>  

或者,它可能看起来像:

<?xml version="1.0" encoding="utf-8"?>   
<yahoo:error xmlns:yahoo="http://www.yahooapis.com/v1/base.rng" xml:lang="en-US">   
    <yahoo:description>description</yahoo:description>   
    <yahoo:detail>   
        <ErrorCode>errorCode</ErrorCode>   
    </yahoo:detail>   
</yahoo:error>  

问题

  • 有没有一种方法可以自动生成POJOs,它可以在没有正式模式的情况下进行编组/解组?
  • 我是否应该尝试手动生成这些 POJO,并带有 JAXB 注释?
  • 是否有一些我应该利用的工具,这样我就不必手动完成所有这些操作?

【问题讨论】:

    标签: java xml jaxb jax-rs


    【解决方案1】:

    有趣的是,他们提供了一个 HTTP URL 作为架构的命名空间 URI,但实际上并没有将他们的架构保存在那里。这可能是他们的疏忽,通过电子邮件或讨论列表发布可能会更正。

    一种方法是创建您自己的架构,但这似乎需要做很多工作却收效甚微。鉴于消息是如此简单,我想知道您是否甚至需要一个 POJO 来包装它们?为什么不使用 XPath 提取所需数据的处理程序?


    编辑:过去的爆炸,但我看到评论,重新阅读问题,并意识到第一句话很难理解。所以,澄清一下:

    如果您要编写一个可公开访问的 Web 服务,一个非常好的习惯是让您的架构文档在您用于架构命名空间 URI 的同一 URL 上可用——或者更好的是,将该 URL 设为完整文档的链接(W3C XSD 命名空间本身就是一个很好的例子:http://www.w3.org/2001/XMLSchema)。

    【讨论】:

    • 我正在编写他们的 API 支持以查看是否确实存在模式。 XPath 似乎只是一个脆弱的解决方案;我怎么知道没有我的 XPath 无法处理的新 XML 数据包?
    • 如果您不知道新元素是什么而不管技术如何,您将如何处理它们?如果您假设某些版本是健全的(即,他们将构建其数据以实现合理的兼容性,因为您的 XPath 仍然可以工作),那怎么不能解决问题?
    • 我最终使用 XML Spy 从示例数据包中生成模式,然后为使用 JAXB 的数据包生成映射。有几次我不得不将新模式添加到示例数据包中,然后重新生成模式和 JAXB 绑定。
    【解决方案2】:

    我建议手动编写 bean,并且仅在必要时使用 JAXB 注释进行注释。对于大多数访问器/突变器(getter/setter),您不必这样做;默认情况下会考虑所有公共 bean 访问器和字段,名称是使用 bean 约定派生的,默认是使用元素而不是属性(因此需要对属性进行注释)。

    如果您非常喜欢 W3C Schema,您当然也可以手动编写模式,使用 JAXB 生成 bean。并且只需使用生成的代码,而不是模式,来进行数据绑定。

    至于 POJO:这很简单。比如:

    @XmlRootElement("Response")
    class Response {
      public int responseCode;
      public String responseMessage;
      public String token; // or perhaps byte[] works for automated base64?
    }
    

    对于其他人也是如此。或者,如果您喜欢它们并且不介意更多冗长,请使用 getter/setter。这些只是数据容器,不用太花哨。

    如果您必须从内容中自动检测类型,请考虑使用 Stax 解析器查看根元素,然后使用 JAXB Unmarshaller 进行绑定,处理指向该根元素的 XMLStreamReader。这样你就可以传递不同的对象类型来绑定。

    最后:发送/接收请求:普通的旧 HttpURLConnection 适用于 GET 和 POST 请求(例如,使用 URL.openConnection() 构建)。如果需要,Jakarta HttpClient 具有更多功能。因此,您通常并不需要单独的 REST 客户端——它们可能会派上用场,但通常构建在简单的 http 客户端部分之上。

    【讨论】:

      【解决方案3】:

      我发现 HTTP4E 对于进行 REST 调用非常有用。这是一个很棒的 Eclipse 插件,它有选项卡、语法着色、自动建议、代码生成、REST HTTP 调用重放等。它在 HTTP 调试、HTTP 篡改、黑客攻击方面做得很好。我玩得很开心。

      http://www.ywebb.com/

      【讨论】:

        【解决方案4】:

        jcabi-http 尝试JdkRequest(我是一名开发人员)。它是这样工作的:

        String body = new JdkRequest("http://www.google.com")
          .header("User-Agent", "it's me")
          .fetch()
          .body()
        

        查看这篇博文了解更多详情:http://www.yegor256.com/2014/04/11/jcabi-http-intro.html

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-10-10
          • 1970-01-01
          • 2015-12-25
          • 2012-11-20
          相关资源
          最近更新 更多