RESTful Java客户端将JSON响应转换为对象

时间:2019-07-18 16:01:14

标签: java json rest web-services jersey

已编辑:

我正在尝试将我从REST API服务获得的JSON响应转换为应用程序内的对象。我使用Jersey执行“ GET”请求以还原服务。

让我们说我有以下两个API调用,每个API都有其对应的JSON响应:

首次调用:获取具有代码值的特定myEntity对象:https://www.test.com/webservice/entity/get?code=BOBS-JC6L(GET)

响应

{
  "isOk": 1,
  "isAuthError": 0,
  "error": false,
  "myEntity":{
        "id": "123",
        "code": "BOBS-JC6L",
        "type": "ZZZ",
        "value": "15.00", 
    }
}

第二次呼叫:获取所有myEntity对象:https://www.test.com/webservice/entity/get-all(获取)

响应

{
  "isOk": 1,
  "isAuthError": 0,
  "error": false,
  "myEntities": [
    {
        "id": "123",
        "code": "BOBS-JC6L",
        "type": "ZZZ",
        "value": "15.00",      
    },
    {
        "id": "456",
        "code": "BOBS-JC7L",
        "type": "CCC",
        "value": "32.00",
    }
    {...}
  ]
}

因此,在两种情况下,基本对象(类型MyEntity)都作为嵌套元素包含在JSON中。我正在尝试将JSON结构映射到POJO对象。

所以我创建了以下POJO类:

MyEntity POJO(这是基本的嵌套元素类):

import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.Date;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;

import javax.xml.bind.annotation.XmlRootElement;

public class MyEntity {

    private int id;
    private String code;
    private String type;
    private BigDecimal value;

    public MyEntity(){

    }

    public MyEntity(String code, String type, BigDecimal value){
        this.code = code;
        this.type = type;
        this.value = value;
    }

    ....

}

然后有一个用于第一个API调用响应的类(我们得到一个MyEntity对象):

@XmlRootElement
public class GetSingleMyEntityResponse {

    private int isOk;
    private int isAuthError;
    private boolean error;
    private MyEntity myEntity;

    ...

}

第二个API调用响应的另一个类(我们获得了多个嵌套的MyEntity对象):

@XmlRootElement
public class GetMultipleMyEntityResponse {

    private int isOk;
    private int isAuthError;
    private boolean error;
    private List<MyEntity> myEntities;

    ...

}

在我的代码中,我首先尝试获取单个myEntity对象,调用:https://www.test.com/webservice/entity/get?code=BOBS-JC6L

try {

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

      WebResource webResource1 = client
              .resource("https://www.test.com/webservice/entity/get?code=MESM-ZB2NEJ");

      Builder builder = webResource1.accept(MediaType.APPLICATION_JSON) //
              .header("content-type", MediaType.APPLICATION_JSON);

      ClientResponse response = builder.get(ClientResponse.class);

      // Status 200 is successful.
      if (response.getStatus() != 200) {
          System.out.println("Failed with HTTP Error code: " + response.getStatus());
          String error = response.getEntity(String.class);
          System.out.println("Error: " + error);
          return;
      }

      System.out.println("\n\nOutput from Server .... \n");

      GetSingleMyEntityResponse vResp = (GetSingleMyEntityResponse) response.getEntity(GetSingleMyEntityResponse.class);
      MyEntity v = vResp.getMyEntity();

      if(v.getId()>0) {
          System.out.println("Id .... " + v.getId());
          System.out.println("Code .... " + v.getCode());
          System.out.println("Type .... " + v.getType());      
          System.out.println("Value .... " + v.getValue());
      }
    } catch (Exception e) {
        e.printStackTrace();
}

这有效,我能够获取MyEntity对象:

Output from Server .... 

Id .... 123
Code .... BOBS-JC6L
Type .... ZZZ
Value .... 15.00

我还试图从以下位置映射多个MyEntity对象: https://www.test.com/webservice/entity/get-all

try {

            Client client = Client.create();

            WebResource webResource = client
               .resource("https://www.test.com/webservice/entity/get-all");

            ClientResponse response = webResource.accept("application/json")
                       .get(ClientResponse.class);

            if (response.getStatus() != 200) {
               throw new RuntimeException("Failed : HTTP error code : "
                + response.getStatus());
            }

            String output = response.getEntity(String.class);

            GetMultipleMyEntityResponse vResp = (GetMultipleMyEntityResponse) response.getEntity(GetMultipleMyEntityResponse.class);
            List<MyEntity> vRespList = new ArrayList<>();
            vRespList = vResp.getMyEntities();

            if(vRespList.size()>0) {

                for(MyEntity v:vRespList) {
                    System.out.println("Id .... " + v.getId());
                    System.out.println("Code .... " + v.getCode());
                    System.out.println("Type .... " + v.getType());      
                    System.out.println("Value .... " + v.getValue());
                }

            }

          } catch (Exception e) {

            e.printStackTrace();

}

但是,似乎GetMultipleMyEntityResponse POJO类不适用于它,我正在得到:

j

avax.ws.rs.WebApplicationException: HTTP 400 Bad Request
    at com.sun.jersey.core.provider.jaxb.AbstractRootElementProvider.readFrom(AbstractRootElementProvider.java:113)
    at com.sun.jersey.api.client.ClientResponse.getEntity(ClientResponse.java:553)
    at com.sun.jersey.api.client.ClientResponse.getEntity(ClientResponse.java:506)
    at com.mspos.mesmo.JerseyClientGet.main(JerseyClientGet.java:97)
Caused by: javax.xml.bind.UnmarshalException: Error creating JSON-based XMLStreamReader
 - with linked exception:
[javax.xml.stream.XMLStreamException: java.io.IOException: stream is closed]
    at com.sun.jersey.json.impl.BaseJSONUnmarshaller.createXmlStreamReader(BaseJSONUnmarshaller.java:116)
    at com.sun.jersey.json.impl.BaseJSONUnmarshaller.unmarshalJAXBElementFromJSON(BaseJSONUnmarshaller.java:108)
    at com.sun.jersey.json.impl.BaseJSONUnmarshaller.unmarshalFromJSON(BaseJSONUnmarshaller.java:97)
    at com.sun.jersey.json.impl.provider.entity.JSONRootElementProvider.readFrom(JSONRootElementProvider.java:125)
    at com.sun.jersey.core.provider.jaxb.AbstractRootElementProvider.readFrom(AbstractRootElementProvider.java:111)
    ... 3 more
Caused by: javax.xml.stream.XMLStreamException: java.io.IOException: stream is closed
    at com.sun.jersey.json.impl.Stax2JsonFactory.ensureNonEmptyReader(Stax2JsonFactory.java:173)
    at com.sun.jersey.json.impl.Stax2JsonFactory.createReader(Stax2JsonFactory.java:117)
    at com.sun.jersey.json.impl.Stax2JsonFactory.createReader(Stax2JsonFactory.java:111)
    at com.sun.jersey.json.impl.BaseJSONUnmarshaller.createXmlStreamReader(BaseJSONUnmarshaller.java:113)
    ... 7 more
Caused by: java.io.IOException: stream is closed
    at sun.net.www.protocol.http.HttpURLConnection$HttpInputStream.ensureOpen(Unknown Source)
    at sun.net.www.protocol.http.HttpURLConnection$HttpInputStream.read(Unknown Source)
    at sun.nio.cs.StreamDecoder.readBytes(Unknown Source)
    at sun.nio.cs.StreamDecoder.implRead(Unknown Source)
    at sun.nio.cs.StreamDecoder.read(Unknown Source)
    at java.io.InputStreamReader.read(Unknown Source)
    at java.io.BufferedReader.fill(Unknown Source)
    at java.io.BufferedReader.read(Unknown Source)
    at com.sun.jersey.json.impl.Stax2JsonFactory.ensureNonEmptyReader(Stax2JsonFactory.java:167)
    ... 10 more

我想念什么的任何想法吗?

1 个答案:

答案 0 :(得分:0)

您要致电response.getEntity()两次。只能调用一次。