【问题标题】:Handle JSON Response that comes without 'root' element with RestEasy使用 RestEasy 处理没有“根”元素的 JSON 响应
【发布时间】:2020-10-05 20:34:51
【问题描述】:

我调用一些 Web 服务(用 Ruby 构建)并获得如下 JSON 响应:

{ "error_code": "02", "message": "参数无效", “字段名称”:“标题” }

为了在 Java 中对响应对象进行建模,我尝试使用:

导入 javax.xml.bind.annotation.XmlRootElement; @XmlRootElement(name = "响应") 公共类响应{ 私有字符串错误代码; 私人字符串消息; 私有字符串字段名; 公共字符串 getError_code() { 返回错误代码; } 公共无效 setError_code(字符串错误代码){ this.error_code = error_code; } 公共字符串 getMessage() { 返回消息; } 公共无效setMessage(字符串消息){ this.message = 消息; } 公共字符串 getField_name() { 返回字段名; } 公共无效 setField_name(字符串字段名){ this.field_name = field_name; } }

...为了在我的 WS 客户端中读取 WS 调用的响应,我尝试:

响应响应 = responseWs.readEntity(Response.class);

...但我得到以下异常:

org.jboss.resteasy.plugins.providers.jaxb.JAXBUnmarshalException:javax.xml.bind.UnmarshalException - 有关联的例外: [com.sun.istack.internal.SAXParseException2; columnNumber: 0 意外元素...预期元素是

那是因为我的代码试图处理这样的 JSON 响应对象(带有一些“根”元素):

{ “回复”: { "error_code": "02", "message": "参数无效", “字段名称”:“标题” } }

有人知道我该如何解决这种情况吗?

谢谢

【问题讨论】:

    标签: java json rest resteasy


    【解决方案1】:

    对我来说,这个 sn-p 解决了这个问题:

    String responseAsString = responseWs.readEntity(String.class);
    ObjectMapper mapper = new ObjectMapper();
    JsonNode pathNode = mapper.readTree(responseAsString);
    Response response = mapper.convertValue(pathNode, Response.class);
    

    【讨论】:

    • 有没有可能你给我看一个使用 xml 而不是 json 的 sn-p?
    【解决方案2】:

    来自您发布的代码 sn-p

    响应响应 = responseWs.readEntity(Response.class);

    我建议为您的实体对象使用其他名称。 Response 类也被 jaxrs 框架本身使用。

    我假设您正在使用RestEasyClient 调用此(外部)服务来接收 JSON。如果了解来自该服务的响应是 JSON 格式,则可以使用 JSON (jackson) marshaller/unmarshaller 而不是 JAXB。假设您的类路径上已经有“resteasy-client”依赖项。这个依赖的maven形式如下:

    <dependency>
        <groupId>org.jboss.resteasy</groupId>
        <artifactId>resteasy-client</artifactId>
        <version>3.0.19.Final</version>
    </dependency>
    
    
    1. 将 DTO 的名称更改为 ExternalServiceResponse
    2. 在执行 GET 请求时,您明确指定响应媒体类型
    Response response = target.request(MediaType.APPLICATION_JSON).get();
    ExternalServiceResponse result = response.readEntity(ExternalServiceResponse.class)
    
    1. 最后我不明白为什么需要在 DTO 上指定 @XmlRootElement 注释
    public class ExternalServiceResponse implements Serializeable {
    
        private String error_code;
        private String message;
        private String field_name;
    
        public String getError_code() {
            return error_code;
        }
        public void setError_code(String error_code) {
            this.error_code = error_code;
        }
    
        public String getMessage() {
            return message;
        }
        public void setMessage(String message) {
            this.message = message;
        }
    
        public String getField_name() {
            return field_name;
        }
        public void setField_name(String field_name) {
            this.field_name = field_name;
        }
    
    }
    

    【讨论】:

      【解决方案3】:

      您应该在哪里配置 JAXB(属性文件或配置方法) jaxbUnmarshaller.setProperty(UnmarshallerProperties.JSON_INCLUDE_ROOT, false)

      【讨论】:

      • 我使用 RestEasy。 “UnmarshallerProperties”的包名是什么?谢谢!
      • org.eclipse.persistence.jaxb.UnmarshallerProperties
      • 任何其他选择,只要我们现在更愿意避免使用 Glassfish 库
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-09-01
      • 2013-04-23
      • 1970-01-01
      • 1970-01-01
      • 2016-03-26
      相关资源
      最近更新 更多