Java – a rest service that accepts and returns objects How to write client?

I have announced two rest web services A simple return of an object Others accept one object and return another

@XmlRootElement
public class Order {

   private String id;

   private String description;

   public Order() {
   }

   @XmlElement
   public String getId() {
          return id;
   }
   @XmlElement
   public String getDescription() {
          return description;
   }

    // Other setters and methods
}

Web service is defined as

@Path("/orders")
public class OrdeRSService {
// Return the list of orders for applications with json or xml formats
@Path("/oneOrder")
@GET
@Produces({MediaType.APPLICATION_JSON})
public  Order getOrder_json() {
  System.out.println("inside getOrder_json");
  Order o1 = OrderDao.instance.getOrderFromId("1");
  System.out.println("about to return one order");
  return o1;
}

@Path("/writeAndIncrementOrder")
@GET
@Produces({MediaType.APPLICATION_JSON})
@Consumes({MediaType.APPLICATION_JSON})
public  Order writeAndIncrementOrder(Order input) {
  System.out.println("inside writeAndIncrementOrder");
  Order o1 = new Order();
  o1.setId(input.getId()+1000);
  o1.setDescription(input.getDescription()+"10000");
  System.out.println("about to return one order");
  return o1;
 }

I can write client code to call a web service that does not accept anything but returns an object The client code is as follows

import java.net.URI;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Invocation.Builder;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriBuilder;
import org.glassfish.jersey.client.ClientConfig;

public class Test {

public static void main(String[] args) {

WebTarget target2 = client.target(getBaseURI()).path("rest").path("orders");
String o2 = target2.path("oneOrder").request().accept(MediaType.APPLICATION_JSON).get(String.class);
        System.out.println(o2);
}

private static URI getBaseURI() {
    return UriBuilder.fromUri("http://localhost:8090/FirstRESTProject").build();
  }

But I don't understand how to call other accepted services and return objects I have tried different solutions on the Internet, but nothing is useful to me. Some solutions are only applicable to sending objects, and some are only applicable to receiving objects But no one does these two jobs on the same phone

The editor replied as suggested below that I have registered Jackson JAXB jsonprovider Class, but the automatic conversion to order object did not happen

String o2 = target2.path("oneOrder").request().accept(MediaType.APPLICATION_JSON).get(String.class);

        client.register(JacksonJaxbJsonProvider.class);
        Order o4 = target2.path("oneOrder").request().accept(MediaType.APPLICATION_JSON).get(Order.class);

In the above program, I successfully get the string as {"Id": "1", "description": "this is the first command"} but get the direct object and throw an error. Messagebodyreader does not find media type = Application / JSON, type = class shopping cart. om. Order,genericType = class shopping. cart. om. Order.

Solution

If you take the time to understand the webtarget API and the different types returned from calling the webtarget method, you should better understand how to make a call This may be a bit confusing because almost all examples use method linking because it is a very convenient way, but in doing so, you miss all the actual classes involved in creating and sending requests Let's break it down

WebTarget. Path() returns only webtarget Nothing interesting

> WebTarget. Request() returns invocation Builder > Invocation. Builder. accept(..) Return to invocation Builder > Invocation. Builder. Get() calls syncinvoker of its superclass Get(), which is the actual request and returns a type according to the parameter get (class ReturnType) provided by us

Get (string. Class) is using to deserialize the response stream into a sting type response This is not a problem, because JSON is essentially just a string However, if you want to decompose JSON into POJO, you need a messagebodyreader, which can know how to decompose JSON into your POJO type Jackson provides a messagebodyreader, which relies on Jackson jaxrs JSON provider

<dependency>
  <groupId>com.fasterxml.jackson.jaxrs</groupId>
  <artifactId>jackson-jaxrs-json-provider</artifactId>
  <version>2.4.0</version>
</dependency>

Most implementations will provide a wrapper for this module, such as Jersey media Jackson in Jersey or resteasy Jackson provider in resteasy But they are still using the basic Jackson - jaxrs - JSON - provider

Having said that, once you have this module on the classpath, it should be registered automatically, so messagebodyreader will be available If not, you can explicitly register with the client, such as client register(JacksonJaxbJsonProvider.class). Once you configure Jackson support, you can simply do something

MyPojo myPojo = client.target(..).path(...).request().accept(..).get(MyPojo.class);

For publishing / sending data, you can view different invocations again Builder method for example

Invocation.Builder builder = target.request();

If we want to publish, please check the different post methods available We can use

>Response post (entity entity) – our request may look like

Response response = builder.post(Entity.json(myPojo));

You will notice entity All post methods accept an entity, which is how the request knows what the entity type should be. The client will call the corresponding messagebodywriter and set the corresponding header > < T > t post (entity entity, class < T > responsetype) – there is also an overload. We can specify the type to be ungrouped instead of returning a response We can do it

MyPojo myPojo = builder.post(Entity.json(myPojo),MyPojo.class)

Please note that using response, we call its readentity (pojotype class) method reading from the response of the entity This advantage is that the response object contains a lot of useful information that we can use, such as title, etc Personally, I always get a response

Response response = builder.get();
    MyPojo pojo = response.readEntity(MyPojo.class);

In addition, for the specific code you display, you are most likely to make it a @ post method Remember that @ get is mainly used to retrieve data, put for updating and post for creating This is a good rule of thumb to stick to when you first start So you can change the way

@Path("orders")
public class OrdersResource  {

    @POST
    @Produces(MediaType.APPLICATION_JSON)
    @Consumes({MediaType.APPLICATION_JSON})
    public Response createOrder(@Context UriInfo uriInfo,Order input) {
       Order order = orderService.createOrder(input);
       URI uri = uriInfo.getAbsolutePathBuilder().path(order.getId()).build();
       return Response.create(uri).entity(order).build();
    }
}

Then you can do it

WebTarget target = client.target(BASE).path("orders");
Response response = target.request().accept(...).post(Entity.json(order));
Order order = response.readEntity(Order.class);
The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>