在RestEasy中访问Jackson Object Mapper

时间:2011-12-14 01:08:04

标签: json jackson resteasy

我被要求美化默认的Jackson JSON来自RestEasy端点。我做了一些关于Jackson的研究并编写了一些独立的代码,以便能够抑制空值,自定义数据格式等。现在的挑战是在RestEasy的JSON序列化中注入此代码。

从论坛帖子来看,这在Spring中是微不足道的,但在RestEasy中似乎并非如此。我编写了一个ContextResolver并在web.xml(在Tomcat上)的上下文params中配置为resteasy.provider,但是这阻止了在Tomcat上加载webapp。

现在我正在尝试扩展javax.ws.rs.core.Application并提供一个ContextResolver但没有任何进展。这是直截了当,有没有人这样做过?非常感谢任何帮助。

6 个答案:

答案 0 :(得分:15)

好的,我想通了,我可以通过编写基于Jackson FAQ: JAX-RS的自定义JacksonJsonProvider来实现这一点。代码如下:

@Provider
public class QBOJacksonJsonProvider extends JacksonJsonProvider {
    public static final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";

    @Override
    public void writeTo(Object value, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap<String,Object> httpHeaders, OutputStream entityStream) throws IOException, WebApplicationException {
        Log.info(getClass(), "In custom JSON provider");
        //get the Object Mapper
        ObjectMapper mapper = locateMapper(type, mediaType);
        // Suppress null properties in JSON output
        mapper.getSerializationConfig().setSerializationInclusion(org.codehaus.jackson.map.annotate.JsonSerialize.Inclusion.NON_NULL);
        // Set human readable date format
        SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT);
        mapper.getSerializationConfig().setDateFormat(sdf);

        super.writeTo(value, type, genericType, annotations, mediaType, httpHeaders, entityStream);
    }
}

答案 1 :(得分:14)

我找到了修改Jackson SerializationConfig的更好方法 - 您可以使用JAX-RS ContextResolver拦截ObjectMapper创建。

@Provider
@Produces(Array(MediaType.APPLICATION_JSON))
class JacksonConfig extends ContextResolver[ObjectMapper] {

  val mapper = new ObjectMapper()
  mapper.getSerializationConfig.setSerializationInclusion(Inclusion.NON_NULL)

  def getContext(objectType: Class[_]) = mapper
}

您需要通过以下方式之一注册RESTEasy:

  • 将其作为javax.ws.rs.core.Application实现的类或实例返回
  • 将其列为resteasy.providers的提供商
  • 让RESTEasy在您的WAR文件中自动扫描它。请参阅配置指南
  • 通过ResteasyProviderFactory.getInstance()手动添加它.registerProvider(Class)或registerProviderInstance(Object)

参考:RESTEasy docs

参考:Nicklas Karlsson on the JBoss forums

请注意,这适用于RESTEasy 2.3.2,它作为JBoss 7.1.1.Final中的模块提供,但似乎不适用于RESTEasy 3.0-beta5。

答案 2 :(得分:2)

杰克逊ObjectMapper的提供者应该是标准的JAX-RS方式(与泽西合作),所以它似乎也是与RESTeasy一起使用的方式。

答案 3 :(得分:2)

如果你正在使用Jackson2提供商,你需要做一些与之前的答案略有不同的事情。此示例将默认打印输出

@Provider
public class JSONProvider extends ResteasyJackson2Provider {

  @Override
  public void writeTo(Object value, Class<?> type, Type genericType, Annotation[]  annotations, MediaType json, MultivaluedMap<String, Object> headers, OutputStream body) throws IOException {

    ObjectMapper mapper = locateMapper(type, json);
    mapper.enable(SerializationFeature.INDENT_OUTPUT);

    super.writeTo(value, type, genericType, annotations, json, headers, body);
  }

}

并在web-xml中注册,如果您没有自动注册,请将其添加到您的resteasy.providers context-param

答案 4 :(得分:1)

我已经做了很多工作将其注册到我的应用程序中,即使在我使用Spring Boot并且没有web.xml时也遵循了使用context-param的提示,

自定义提供商

package com.mageddo;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.jboss.resteasy.plugins.providers.jackson.ResteasyJackson2Provider;

import javax.ws.rs.Consumes;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.ext.Provider;

@Provider
@Consumes({"application/json", "application/*+json", "text/json"})
@Produces({"application/json", "application/*+json", "text/json"})
public class CustomJacksonJsonProvider extends ResteasyJackson2Provider {

    private ObjectMapper objectMapper = new ObjectMapper(); // my own object mapper

    @Override
    public ObjectMapper locateMapper(Class<?> type, MediaType mediaType) {
        return objectMapper;
    }
}

在应用程序上注册

META-INF / services / javax.ws.rs.ext.Providers

com.mageddo.CustomJacksonJsonProvider
org.jboss.resteasy.plugins.providers.jackson.UnrecognizedPropertyExceptionHandler

答案 5 :(得分:0)

  

如果您使用的是Jackson 2.2.x提供商,Resteasy提供了一个   漂亮的打印注释与JAXB提供程序中的相似:

org.jboss.resteasy.annotations.providers.jackson.Formatted
     

以下是一个例子:

@GET
@Produces("application/json")
@Path("/formatted/{id}")
@Formatted
public Product getFormattedProduct()
{
    return new Product(333, "robot");
}
     

如上所示,@ Formatted注释将启用   潜在的Jackson选项“SerializationFeature.INDENT_OUTPUT”。

©RESTEasy User Guide

这不是一个全局解决方案,但您也可以在类上添加注释。