我被要求美化默认的Jackson JSON来自RestEasy端点。我做了一些关于Jackson的研究并编写了一些独立的代码,以便能够抑制空值,自定义数据格式等。现在的挑战是在RestEasy的JSON序列化中注入此代码。
从论坛帖子来看,这在Spring中是微不足道的,但在RestEasy中似乎并非如此。我编写了一个ContextResolver并在web.xml(在Tomcat上)的上下文params中配置为resteasy.provider,但是这阻止了在Tomcat上加载webapp。
现在我正在尝试扩展javax.ws.rs.core.Application并提供一个ContextResolver但没有任何进展。这是直截了当,有没有人这样做过?非常感谢任何帮助。
答案 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:
参考: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”。
这不是一个全局解决方案,但您也可以在类上添加注释。