How to create a RESTful web service client from Jersey2.0 or higher
There seem to be many examples of creating RESTful Jersey 1.x clients , but not Jersey 2.0 or higher . I have mentioned other questions and the Jersey website, but I still cannot create a client for REST due to the differences between Jersey 2.0 and the previous one. So I would like to ask some advice.
So far my coding has been 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 results in a 406 error.
However, when I tried to test the RESTful service with the Glassfish server, the test works correctly and the server side class has its @GET methods with @Produces ({"application / xml", "application / json"}). So I don't understand why the above coding generates a 406 error for a Java application.
(i.e. the client side has @GET methods as follows)
@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();
}
Can any of you see what I am doing wrong, or can you provide an example RESTful client? Any advice would be helpful ... thanks in advance!
Also, I would appreciate it if you could provide information on how to call methods such as GET, PUT, and DELETE with appropriate parameters . I just needed to provide an identification number (i.e. Integer values) when I tested the server side class in a Glassfish RESTful test. However, it seems to me that I need to set the class and / or "Entity" values as arguments, but I don't see any information related to them on the Jersey website.
source to share
For the first block of code:
Take a look at your request()
method target.request(MediaType.TEXT_XML_TYPE)
. From Javadoc request()
if states
Invocation.Builder request(MediaType... acceptedResponseTypes)
Begin creating a request to the target web resource and defining the accepted response message types. The call to this method is identical:
webTarget.request().accept(types);
So, in your request, you say that you will only Accept: text/plain
. Now take a look at your resource methods. Take a look at @Produces
. None of them "produce" text/plain
. It's all json or xml. This is why you are getting an exception. Change accept to application/xml
(or MediaType.APPLICATION_XML
) client side and you won't get this error again.
For the second question: I assume you mean why it works when you test it in a browser.
If you send a request from a browser by just typing in the url, it will send a request with many types Accept
. If you have firebug (for FireFox) or developer tools (for Chrome), if you submit a request, you will see a header similar to
Accept text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
You can see here application/xml
. Even if application/xml
it wasn't there, there is a wild card */*
, so almost all media types are valid as a return type when running in a browser.
For your last question:
Look at the API for SyncInvoker
that Invocation.Builder
extends from. You will see various overloaded methods put
and post
most of which, as you said, accept Entity
.
There are several different creation methods Entity
that use one of the static methods. Here are some
- Entity.entity (body, mediaType)
- Entity.json (body)
- Entity.xml (body)
And a lot more (see Entity link above). But all these static methods return 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, Customer
converted to XML. If you used Entity.json
will be converted to JSON, BUT , you need to make sure you have a dependency on the JSON provider. Jersey won't go with the default one. See more in Support for generic media type representations
Also note that when using a method find
, when you try to make a request to the method, the request must end with an integer value like the one specified for the path parameter {id}
.
source to share