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

标签 java json rest web-services jersey

编辑:

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

假设我有以下两个 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 (GET)

回应:

{
  "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

我想念什么有什么想法吗?

最佳答案

您正在调用 response.getEntity() 两次。仅调用一次。

关于java - RESTful Java 客户端将 JSON 响应转换为对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57098575/

相关文章:

Java时间忽略夏令时规则

c# - 在不使用反射的情况下在 C# 中反序列化 JSON 字符串

python - pymongo类型错误: document must be an instance of dict, bson.son.SON,bson.raw_bson.RawBSONDocument

GitHub API 单一提交不获取所有文件

C# Web API 帮助文档 IHttpActionResult

java - ElasticsearchRepository 动态索引名称

java - 自 12 :00 am December 31, 1989 Java 以来的秒数

java - 无法在场景之间传递属性 JAvaFX

php - 使用递归函数使用php数组为树结构数据创建json数据

java - 在 REST 调用中将 JSON 转换为资源