使用 RestEasy 处理没有“根”元素的 JSON 响应

Posted

技术标签:

【中文标题】使用 RestEasy 处理没有“根”元素的 JSON 响应【英文标题】:Handle JSON Response that comes without 'root' element with RestEasy 【发布时间】: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": "参数无效", “字段名称”:“标题”

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

谢谢

【问题讨论】:

【参考方案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>

    将 DTO 的名称更改为 ExternalServiceResponse 在执行 GET 请求时,您明确指定响应媒体类型
Response response = target.request(MediaType.APPLICATION_JSON).get();
ExternalServiceResponse result = response.readEntity(ExternalServiceResponse.class)
    最后我不明白为什么需要在 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 库

以上是关于使用 RestEasy 处理没有“根”元素的 JSON 响应的主要内容,如果未能解决你的问题,请参考以下文章

Vue.js处理边界情况

CORS angular js + restEasy on POST

RESTEasy中的通用异常处理ExceptionMapper

处理对安全受限的 RestEasy 支持的 rest api 2.x 的 PreFlight 请求

RestEasy JAVAX 异步注意事项

impress.js中文API文档