在RestEasy中访问Jackson Object Mapper

cod*_*eek 27 json resteasy jackson

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

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

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

cod*_*eek 15

好吧,我想通了,我能够通过编写一个基于杰克逊常见问题解答的自定义JacksonJsonProvider来实现这一点:JAX-RS.代码如下:

@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);
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 你是如何"注册"这个提供者的? (9认同)
  • @DanielSerodio可以在web.xml中完成`<context-param> <param-name> resteasy.providers </ param-name> <param-value> com.package.JsonProvider </ param-value> </ context-param >` (5认同)

Jam*_*ter 15

我发现了一种修改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
}
Run Code Online (Sandbox Code Playgroud)

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

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

参考:RESTEasy文档

参考:JBoss论坛上的Nicklas Karlsson

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


Tad*_*dhg 6

如果您使用的是 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);
  }

}
Run Code Online (Sandbox Code Playgroud)

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

  • 但这样映射器配置将在每次序列化时更改。如何一次性配置mapper?例如,如果我需要注册杰克逊模块。我不想在每个 http 请求上重新注册它。 (3认同)

Sta*_*Man 2

Jackson 的提供者ObjectMapper应该是执行此操作的标准 JAX-RS 方式(与 Jersey 一起使用),因此它似乎也是与 RESTeasy 一起使用的方式。