没有架构的 Java REST 客户端
目标
Yahoo HotJobs 简历搜索 REST API 的 Java 客户端。
背景
我习惯于为 SOAP API 编写 Web 服务客户端,其中 wsimport 生成代理存根,然后您就可以开始运行了。 但这是一个 REST API,对我来说是新的。
详细信息
- REST API
- 否 WADL
- 无正式 XML 架构(XSD 或 DTD 文件)。 有示例 XML 请求/响应对。
- 没有提供示例代码
进度
我查看了问题 Rest clients for Java?,但是那里有自动化解决方案假设您同时提供服务器和客户端,并在 POJO 上调用 JAXB 来生成架构和 REST API。
使用 Jersey (JAX-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>
问题
Goal
Java client for Yahoo's HotJobs Resumé Search REST API.
Background
I'm used to writing web-service clients for SOAP APIs, where wsimport generates proxy stubs and you're off and running. But this is a REST API, which is new to me.
Details
- REST API
- No WADL
- No formal XML schema (XSD or DTD files). There are example XML request/response pairs.
- No example code provided
Progress
I looked at question Rest clients for Java?, but the automated solutions there assume you are providing both the server and the client, with JAXB invoked on POJOs to generate a schema and a REST API.
Using Jersey (a JAX-RS implementation), I have been able to make a manual HTTP request:
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
The response can look like:
<?xml version="1.0" encoding="utf-8"?>
<Response>
<ResponseCode>0</ResponseCode>
<ResponseMessage>Login successful</ResponseMessage>
<Token>NTlEMTdFNjk3Qjg4NUJBNDA3MkJFOTI3NzJEMTdDNDU7bG9jYWxob3N0LmVnbGJwLmNvcnAueWFob28uY29tO0pVNWpzRGRhN3VhSS4yQVRqRi4wWE5jTWl0RHVVYzQyX3luYWd1TjIxaGx6U0lhTXN3LS07NjY2MzM1OzIzNDY3NTsxMjA5MDE2OTE5OzZCM1RBMVNudHdLbl9VdFFKMFEydWctLQ==</Token>
</Response>
Or, it can look like:
<?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>
Questions
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
有趣的是,他们提供了一个 HTTP URL 作为模式的命名空间 URI,但实际上并不在那里保存他们的模式。 这可能是他们的疏忽,可以通过电子邮件或讨论列表发布来纠正。
一种方法是创建自己的模式,但这似乎是大量工作却收效甚微。 鉴于消息如此简单,我想知道您是否需要 POJO 来包装它们? 为什么不直接使用一个处理程序来使用 XPath 提取所需的数据呢?
编辑:来自过去的爆炸,但我看到了评论,重读了问题,并意识到第一句话很难理解。 因此,澄清一下:
如果您要编写一个可公开访问的 Web 服务,一个非常好的习惯是让您的架构文档在您用于架构的命名空间 URI 的同一 URL 上可用——或者更好的是,让该 URL 为完整文档的链接(W3C XSD 命名空间本身就是一个很好的示例:http://www.w3. org/2001/XMLSchema)。
It's interesting that they provide an HTTP URL as the namespace URI for the schema, but don't actually save their schema there. That could be an oversight on their part, which an email or discussion-list posting could correct.
One approach is to create your own schema, but this seems like a lot of work for little return. Given how simple the messages are, I wonder if you even need a POJO to wrap them? Why not just have a handler that extracts the data you need using XPath?
Edit: blast from the past, but I saw the comment, reread the question, and realized that the first sentence was hard to understand. So, clarification:
One very good habit, if you're going to write a publicly accessible web service, is to make your schema document available at the same URL that you use for the schema's namespace URI -- or better, have that URL be a link to complete documentation (the W3C XSD namespace is itself a good example: http://www.w3.org/2001/XMLSchema).
我建议手动编写 bean,并且仅在必要时使用 JAXB 注释进行注释。 对于大多数访问器/修改器(getter/setter),您不必这样做; 默认情况下,考虑所有公共 bean 访问器和字段,名称是使用 bean 约定派生的,默认情况下是使用元素而不是属性(因此需要对属性进行注释)。
或者,如果您非常喜欢 W3C Schema,您当然可以手动编写 schema,使用 JAXB 生成 bean。 只需使用生成的代码(而不是架构)进行数据绑定。
至于 POJO:那可以非常简单。 类似于:
对于其他的也类似。 或者,如果您喜欢并且不介意更冗长的话,可以使用 getter/setter。 这些只是数据容器,不需要太花哨。
如果您必须从内容中自动检测类型,请考虑使用 Stax 解析器来查看根元素,然后使用 JAXB Unmarshaller 进行绑定,将指向该根元素的 XMLStreamReader 传递给 XMLStreamReader。 这样你就可以传递不同的对象类型来绑定。
最后:发送/接收请求:普通的旧 HttpURLConnection 对于 GET 和 POST 请求可以正常工作(例如使用 URL.openConnection() 进行构造)。 如果需要的话,Jakarta HttpClient 有更多功能。 因此,通常您并不真正需要单独的 REST 客户端——它们可能会派上用场,但通常构建在简单的 http 客户端部分上。
I would suggest writing beans by hand, and only annotating with JAXB annotations if you have to. For most accessors/mutators (getters/setters) you do not have to; by default all public bean accessors and fields are considered, name is derived using bean convention, and default is to use elements instead of attributes (so attributes need to be annotated).
Alternatively you can of course write schema by hand, generate beans using JAXB, if you like W3C Schema a lot. And just use resulting code, not schema, for data binding.
As to POJO: that can be very simple. Something like:
and similarly for other ones. Or, use getters/setters if you like them and don't mind bit more verbosity. These are just data containers, no need to get too fancy.
And if you must auto-detect type from content, consider using Stax parser to see what the root element, and then bind using JAXB Unmarshaller, handing XMLStreamReader that points to that root element. That way you can pass different object type to bind to.
And finally: sending/receiving requests: plain old HttpURLConnection works ok for GET and POST requests (construct using, say, URL.openConnection()). Jakarta HttpClient has more features if need be. So oftentimes you don't really need a separate REST client -- they may come in handy, but generally build on simple http client pieces.
我发现 HTTP4E 对于进行 REST 调用非常有用。 它是一个很棒的 Eclipse 插件,它有选项卡、语法着色、自动建议、代码生成、REST HTTP 调用重放等。它在 HTTP 调试、HTTP 篡改、黑客攻击方面做得很好。 我玩得很开心。
http://www.ywebb.com/
I find HTTP4E very useful for making REST calls. It is an awesome Eclipse plugin, it has tabs, syntax coloring, auto suggest, code generation, REST HTTP call replay, etc.. It does a great job of HTTP debugging, HTTP tampering, hacking. I am having so much fun with it.
http://www.ywebb.com/
尝试来自 jcabi-http 的
JdkRequest
(我是开发人员)。 它是这样工作的:查看此博客文章了解更多详细信息:http ://www.yegor256.com/2014/04/11/jcabi-http-intro.html
Try
JdkRequest
from jcabi-http (I'm a developer). This is how it works:Check this blog post for more details: http://www.yegor256.com/2014/04/11/jcabi-http-intro.html