Rest easy 3 + Jackson + Tomcat + XML 响应

Posted

技术标签:

【中文标题】Rest easy 3 + Jackson + Tomcat + XML 响应【英文标题】:Rest easy 3 + Jackson + Tomcat + XML response 【发布时间】:2016-08-30 06:42:23 【问题描述】:

为了获得 json 响应,reseasy 定义了一种与 Jackson 集成的方法。 使用 reseasy-jackson-provider 和 resteasy-jackson2-provider。

Jackson 也可用于从 XML 反序列化反序列化。即使用 jackson-jaxrs-xml-provider 和 jackson-dataformat-xml。但是使用这些并产生 XML 响应失败了

org.jboss.resteasy.core.NoMessageBodyWriterFoundFailure: Could not find MessageBodyWriter for response object of type: someclass of media type: application/xml

使用的依赖项

        <dependency>
            <groupId>org.jboss.resteasy</groupId>
            <artifactId>resteasy-jaxrs</artifactId>
            <version>$resteasy.version</version>
        </dependency>
        <dependency>
            <groupId>org.jboss.resteasy</groupId>
            <artifactId>resteasy-validator-provider-11</artifactId>
            <version>$resteasy.version</version>
        </dependency>
        <dependency>
            <groupId>org.jboss.resteasy</groupId>
            <artifactId>resteasy-servlet-initializer</artifactId>
            <version>$resteasy.version</version>
        </dependency>
        <dependency>
            <groupId>org.jboss.resteasy</groupId>
            <artifactId>resteasy-jackson2-provider</artifactId>
            <version>$resteasy.version</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.jaxrs</groupId>
            <artifactId>jackson-jaxrs-xml-provider</artifactId>
            <version>$jackson.version</version>
        </dependency>

资源

@GET
@Path("/foo/id")
@Produces(MediaType.APPLICATION_XML)
public Foo getFoo(@PathParam("id") int id);

【问题讨论】:

问题是什么?你能制定出来吗? 问题是如何使用jackson从resteasy获取xml响应 目前在 resteady-jackson2-provider jar 中有一个名为 Jackson2JsonInterceptor 的编写器拦截器。我觉得 xml 需要类似的一个才能使其工作。 【参考方案1】:

JAXB 是将 Java 类映射到 XML 和 XML 模式的注解框架。要在 Resteasy 中使用 JAXB,您需要将 resteasy-jaxb-provider 添加到您的依赖项中

<dependency>
    <groupId>org.jboss.resteasy</groupId>
    <artifactId>resteasy-jaxb-provider</artifactId>
    <version>$resteasy.version</version>
</dependency> 

然后,将 xml 注释添加到您的响应类。例如:

@XmlRootElement(name="user") 
class User 
    int id;
    String name;      

    @XmlElement(name="id")
    public int getId() 
        return id;
    

    public void setId(int id) 
        this.id = id;
    

    @XmlElement(name="name")
    public String getName() 
        return name;
    

    public void setName(String name) 
        this.name = name;
    

更新: 由于 Resteasy 没有基于 Jackson 的内置 xml 提供程序,如果您不喜欢 JAXB 注解,您也可以编写自己的处理程序。 使用以下依赖项,因为在 Jackson 2.1 之后不推荐使用 jackson-jaxrs-xml-provider

<dependency>
  <groupId>com.fasterxml.jackson.dataformat</groupId>
  <artifactId>jackson-dataformat-xml</artifactId>
  <version>jackson-version</version>
</dependency>

在您的项目中,实现javax.ws.rs.ext.MessageBodyWriter 接口。示例代码:

@Provider
@Produces("application/xml")
public class XMLMarshaller implements MessageBodyWriter<Object> 

    @Override
    public boolean isWriteable(Class<?> type, Type genericType,
            Annotation[] annotations, MediaType mediaType)             
        return true;
    

    @Override
    public long getSize(Object obj, Class<?> type, Type genericType,
            Annotation[] annotations, MediaType mediaType)             
        return -1;
    

    @Override
    public void writeTo(Object obj, Class<?> type, Type genericType,
            Annotation[] annotations, MediaType mediaType,
            MultivaluedMap<String, Object> httpHeaders,
            OutputStream entityStream) throws IOException,
            WebApplicationException 

        ObjectMapper xmlMapper = new XmlMapper();
        xmlMapper.writeValue(entityStream, obj);            
        

JAX-RS 运行时会查看每个作者的@Produces 注解并调用MessageBodyWriter.isWriteable() 方法;那么您的自定义 MessageBodyWriter 将被选中来完成这项工作

【讨论】:

有没有办法在不向我的模型类添加注释的情况下实现它。有了杰克逊,这是可能的,我能够轻松地返回 json。也试图用杰克逊返回 xml。 @jathinsanghvi 目前 Resteasy 没有内置的处理程序或提供程序允许您自动将 Java 对象转换为 XML(default_providers)。即便如此,您也可以通过实现 javax.ws.rs.ext.MessageBodyWriter 接口和 Jackson xml 组件来编写自己的处理程序 好吧,这看起来很简单……一定要试试。我正在考虑实现 com.fasterxml.jackson.jaxrs.xml.JacksonJaxbXMLProvider。实现类类似于 org.jboss.resteasy.plugins.providers.jackson.ResteasyJackson2Provider。然后可以在更通用的上下文中使用它。 jackson-jaxrs-xml-provider 似乎没有被弃用。【参考方案2】:

创建 https://issues.jboss.org/browse/RESTEASY-1352

让我们看看它是否会进入轻松的工件。

【讨论】:

【参考方案3】:

除了放

    <dependency>
        <groupId>com.fasterxml.jackson.jaxrs</groupId>
        <artifactId>jackson-jaxrs-xml-provider</artifactId>
        <version>$jackson.version</version>
    </dependency>

到您的 POM 文件中,删除所有 JAXB (@Xml*) 注释。 JAXB 注释将触发默认提供程序。

用 Thorntail 和 Jackson 2.9 测试。

【讨论】:

以上是关于Rest easy 3 + Jackson + Tomcat + XML 响应的主要内容,如果未能解决你的问题,请参考以下文章

让SpringBoot的jackson支持JavaBean嵌套的protobuf

使用 Proguard 处理 Jackson 库后混淆时出错

尝试通过 Spring Boot Rest 使用 Jackson 验证 JSON

Spring Boot 忽略 Rest Controller 中的 Jackson 注释

com.fasterxml.jackson.databind.exc.InvalidDefinitionException 对于用户实体上的一些 REST 操作

Jackson 在 Spring Boot Rest 应用程序中将日期更改为一天。