简体   繁体   English

如何通过Jersey2.0或更高版本创建RESTful Web服务客户端

[英]How to create RESTful web service client by Jersey2.0 or above

There seems to be many examples about creating RESTful clients by Jersey 1.x, but not Jersey 2.0 or above . 似乎有很多关于Jersey 1.x创建RESTful客户端的例子, 但不是Jersey 2.0或更高版本 I referred to other questions and the Jersey's web site, but I still cannot create a client for REST due to the differences between Jersey 2.0 and the previous one. 我提到了其他问题和Jersey的网站,但由于Jersey 2.0和之前的版本之间存在差异,我仍然无法为REST创建客户端。 So I'd like to ask some advice. 所以我想问一些建议。

So far, my coding is like this. 到目前为止,我的编码是这样的。

ClientConfig config = new ClientConfig();
Client client = ClientBuilder.newClient(config);
WebTarget target =  client.target("http://localhost:8080/CustomerBack2211/webresources/entities.customer");

Invocation.Builder invocationBuilder = target.request(MediaType.TEXT_XML_TYPE);
Response response = invocationBuilder.get();
System.out.println(response.getStatus());
System.out.println(response.readEntity(String.class));

This produces 406 error. 这会产生406错误。

However, when I tried to test RESTful service by Glassfish server, the test works properly, and the server side class has its @GET methods having @Produces({"application/xml", "application/json"}). 但是,当我尝试通过Glassfish服务器测试RESTful服务时,测试工作正常,服务器端类的@GET方法有@Produces({“application / xml”,“application / json”})。 So I don't see why the coding above produces 406 error on a Java application. 所以我不明白为什么上面的代码在Java应用程序上产生406错误。

(ie the client side has @GET methods in the following way) (即客户端以下列方式具有@GET方法)

@GET
@Path("{id}")
@Produces({"application/xml", "application/json"})
public Customer find(@PathParam("id") Integer id) {
    return super.find(id);
}

@GET
@Override
@Produces({ "application/xml"})
public List<Customer> findAll() {
    return super.findAll();
}

Does any of you see what I'm doing wrong, or could you please suggest an example of a RESTful client? 你们有没有看到我做错了什么,或者你能否建议一个RESTful客户端的例子? Any advice will be helpful...thanks in advance! 任何建议都会有所帮助......在此先感谢!


In addition, I'd appreciate if you would offer information about how to invoke methods like GET, PUT and DELETE with appropriate parameters . 另外,如果您提供有关如何使用适当的参数调用GET,PUT和DELETE等方法的信息,我将不胜感激。 I just needed to put an ID number (ie integer values) when I was testing the server side class on Glassfish RESTful test. 当我在Glassfish RESTful测试中测试服务器端类时,我只需要输入一个ID号(即整数值)。 However, it seems that I need to set "Class" and/or "Entity" values as arguments, but I cannot see any information associated with them on the Jersey website. 但是,似乎我需要将“Class”和/或“Entity”值设置为参数,但我在Jersey网站上看不到与它们相关的任何信息。

For the first block of code: 对于第一个代码块:

406 means Not Acceptable . 406表示不可接受

Look at your request() method target.request(MediaType.TEXT_XML_TYPE) . 查看您的request()方法target.request(MediaType.TEXT_XML_TYPE) From the Javadoc of request() if states 来自request()的Javadoc request()如果状态

Invocation.Builder request(MediaType... acceptedResponseTypes)

Start building a request to the targeted web resource and define the accepted response media types. 开始构建对目标Web资源的请求,并定义接受的响应媒体类型。 Invoking this method is identical to: 调用此方法与以下内容相同:

webTarget.request().accept(types);

So basically, in your request, you are saying that you will only Accept: text/plain . 所以基本上,在你的请求中,你说你只会Accept: text/plain Now look at your resource methods. 现在看看你的资源方法。 Look at the @Produces . 看看@Produces None of them "produce" text/plain . 他们都没有“产生” text/plain It's all json or xml. 这都是json或xml。 That's why you get the exception. 这就是你得到例外的原因。 Change the accept to application/xml (or MediaType.APPLICATION_XML ) on the client side, and you should no longer get this error. 在客户端将accept更改为application/xml (或MediaType.APPLICATION_XML ),您不应再出现此错误。

For the second question: I'm assuming you mean why does it work when you test it from the browser. 对于第二个问题:我假设你的意思是为什么它在浏览器中测试时有效。

If you send a request from the browser by simply typing in the url, it will send out the request with many Accept types. 如果您只需输入网址就可以从浏览器发送请求,它将发送包含许多Accept类型的请求。 If you have firebug (for FireFox) or the developer tools (for Chrome), if you send out a request, you will see a header similar to 如果你有firebug(对于FireFox)或开发者工具(对于Chrome),如果你发出请求,你会看到类似于

Accept text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8

You can see application/xml in there. 你可以在那里看到application/xml Even if application/xml wasn't there, the wild card */* is there, so basically almost all media types are acceptable as a return type when working in the browser. 即使application/xml不存在,外卡*/*也存在,因此在浏览器中工作时基本上几乎所有媒体类型都可以作为返回类型。

For your last question: 对于你的上一个问题:

Look at the API for SyncInvoker , which Invocation.Builder extends from. 查看Invocation.Builder扩展自的SyncInvoker API。 You will see different overrloaded put and post methods, most of which, as you mentioned accept an Entity . 您将看到不同的重载putpost方法,其中大部分都是如您所提到的那样接受Entity

There are a few different ways to build an Entity , all of which use one of the static methods. 构建Entity有几种不同的方法,所有这些方法都使用静态方法之一。 Here are some 这里有一些

  • Entity.entity( body, mediaType ) Entity.entity(body,mediaType)
  • Entity.json( body ) Entity.json(正文)
  • Entity.xml( body ) Entity.xml(正文)

And many more (see the Entity link above). 还有更多(参见上面的实体链接)。 But all of these static method return an Entity . 但所有这些静态方法都返回一个Entity So we could do something like 所以我们可以做点什么

// resource method
@POST
@Consumes(MediaType.APPLICATION_XML)
public Response getResponse(Customer customer) { ... }

// some model class
@XmlRootElement
public class Customer { ... }

// client request
Customer customer = new Customer();
Response response = target.request().post(Entity.xml(customer));

Internally, the Customer will get converted to XML. 在内部, Customer将转换为XML。 If you used Entity.json is would get converted to JSON, BUT you need to make sure you have a JSON provider dependency. 如果您使用Entity.json将转换为JSON, 您需要确保您具有JSON提供程序依赖项。 Jersey will not come with one by default. 泽西岛默认不会带一个。 See more at Support for Common Media Type Representations 有关常见媒体类型表示的更多信息,请参阅


Also note, with your method find , when you try and make a request to the method, the request should end with an integer value, as that's the type specified for the {id} path parameter. 另请注意,使用您的方法find ,当您尝试向方法发出请求时,请求应以整数值结束,因为这是为{id} path参数指定的类型。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM