json 在 RestEasy 中访问 Jackson 对象映射器
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8498413/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Accessing Hymanson Object Mapper in RestEasy
提问by codegeek
I've been asked to beautify default Hymanson JSON coming out of a RestEasy endpoint. I did some research on Hymanson and wrote some standalone code to be able to suppress nulls, customize data formats etc. Now the challenge is injecting this code in RestEasy's JSON serialization.
我被要求美化来自 RestEasy 端点的默认 Hymanson JSON。我对 Hymanson 进行了一些研究,并编写了一些独立的代码,以便能够抑制空值、自定义数据格式等。现在的挑战是在 RestEasy 的 JSON 序列化中注入这些代码。
Judging from the forum posts this is trivial in Spring, however doesn't seem to be the case in RestEasy. I wrote a ContextResolver and configured as resteasy.provider in context params in web.xml (on Tomcat) but that prevents the webapp from loading on Tomcat.
从论坛帖子来看,这在 Spring 中是微不足道的,但在 RestEasy 中似乎并非如此。我编写了一个 ContextResolver 并在 web.xml(在 Tomcat 上)的上下文参数中配置为 resteasy.provider,但这会阻止 webapp 在 Tomcat 上加载。
Now I'm trying to extend javax.ws.rs.core.Application and provide a ContextResolver but making no progress. Is this straight forward, has anyone done this? Any help is greatly appreciated.
现在我正在尝试扩展 javax.ws.rs.core.Application 并提供一个 ContextResolver 但没有任何进展。这是直接的吗,有人这样做过吗?任何帮助是极大的赞赏。
回答by codegeek
Ok,I figured it out, I was able to do this by writing a custom HymansonJsonProvider based on the Hymanson FAQ: JAX-RS.The code is as follows:
好的,我想通了,我可以通过根据Hymanson FAQ: JAX-RS编写自定义 HymansonJsonProvider 来做到这一点。代码如下:
@Provider
public class QBOHymansonJsonProvider extends HymansonJsonProvider {
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.Hymanson.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);
}
}
回答by James Baxter
I found a nicer way of modifying the Hymanson SerializationConfig - you can intercept the ObjectMapper creation by using a JAX-RS ContextResolver.
我找到了一种更好的修改 Hymanson SerializationConfig 的方法 - 您可以使用 JAX-RS ContextResolver 拦截 ObjectMapper 创建。
@Provider
@Produces(Array(MediaType.APPLICATION_JSON))
class HymansonConfig extends ContextResolver[ObjectMapper] {
val mapper = new ObjectMapper()
mapper.getSerializationConfig.setSerializationInclusion(Inclusion.NON_NULL)
def getContext(objectType: Class[_]) = mapper
}
You will need to register with RESTEasy in one of the following ways:
您需要通过以下方式之一向 RESTEasy 注册:
- Return it as a class or instance from a javax.ws.rs.core.Application implementation
- List it as a provider with resteasy.providers
- Let RESTEasy automatically scan for it within your WAR file. See Configuration Guide
- Manually add it via ResteasyProviderFactory.getInstance().registerProvider(Class) or registerProviderInstance(Object)
- 从 javax.ws.rs.core.Application 实现将其作为类或实例返回
- 使用 resteasy.providers 将其列为提供者
- 让 RESTEasy 在您的 WAR 文件中自动扫描它。参见配置指南
- 通过 ResteasyProviderFactory.getInstance().registerProvider(Class) 或 registerProviderInstance(Object) 手动添加
Reference: RESTEasy docs
参考:RESTEasy 文档
Reference: Nicklas Karlsson on the JBoss forums
参考:JBoss 论坛上的 Nicklas Karlsson
Please note that this works with RESTEasy 2.3.2 which ships as a module in JBoss 7.1.1.Final, but does not appear to work with RESTEasy 3.0-beta5.
请注意,这适用于作为 JBoss 7.1.1.Final 中的模块提供的 RESTEasy 2.3.2,但似乎不适用于 RESTEasy 3.0-beta5。
回答by Tadhg
If you're using the Hymanson2 provider you need to do something slightly different from the previous answer. This example will pretty-print the output by default
如果您使用的是 Hymanson2 提供程序,您需要做一些与之前的答案略有不同的事情。此示例将默认打印输出
@Provider
public class JSONProvider extends ResteasyHymanson2Provider {
@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);
}
}
and to register it in your web-xml, if you don't have autoregister on, add it to your resteasy.providers context-param
并在您的 web-xml 中注册它,如果您没有自动注册,请将其添加到您的 resteasy.providers 上下文参数中
回答by StaxMan
Provider for Hymanson ObjectMappershould be standard JAX-RS way of doing this (works with Jersey), so it seems like the way to go with RESTeasy as well.
Hymanson 的提供程序ObjectMapper应该是标准的 JAX-RS 方式(与 Jersey 一起使用),所以它似乎也是 RESTeasy 的方式。
回答by deFreitas
I had a lot of work to register it in my application even following the tip to use context-param once I'm using spring boot and have not web.xml, here what I did
我有很多工作要在我的应用程序中注册它,即使我在使用 spring boot 并且没有 web.xml 时按照提示使用上下文参数,这里我做了什么
Custom provider
自定义提供程序
package com.mageddo;
import com.fasterxml.Hymanson.databind.ObjectMapper;
import org.jboss.resteasy.plugins.providers.Hymanson.ResteasyHymanson2Provider;
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 CustomHymansonJsonProvider extends ResteasyHymanson2Provider {
private ObjectMapper objectMapper = new ObjectMapper(); // my own object mapper
@Override
public ObjectMapper locateMapper(Class<?> type, MediaType mediaType) {
return objectMapper;
}
}
Registering on application
申请注册
META-INF/services/javax.ws.rs.ext.Providers
META-INF/services/javax.ws.rs.ext.Providers
com.mageddo.CustomHymansonJsonProvider
org.jboss.resteasy.plugins.providers.Hymanson.UnrecognizedPropertyExceptionHandler
回答by Vsevolod Golovanov
If you are using the Hymanson 2.2.x provider, Resteasy has provided a pretty-printing annotation simliar with the one in JAXB provider:
org.jboss.resteasy.annotations.providers.Hymanson.FormattedHere is an example:
@GET @Produces("application/json") @Path("/formatted/{id}") @Formatted public Product getFormattedProduct() { return new Product(333, "robot"); }As the example shown above, the @Formatted annotation will enable the underlying Hymanson option "SerializationFeature.INDENT_OUTPUT".
如果您使用的是 Hymanson 2.2.x 提供程序,Resteasy 提供了一个与 JAXB 提供程序中的注释类似的漂亮打印注释:
org.jboss.resteasy.annotations.providers.Hymanson.Formatted下面是一个例子:
@GET @Produces("application/json") @Path("/formatted/{id}") @Formatted public Product getFormattedProduct() { return new Product(333, "robot"); }如上例所示,@Formatted 注释将启用底层 Hymanson 选项“SerializationFeature.INDENT_OUTPUT”。
This is not a global solution, but you can put the annotation on classes too.
这不是全局解决方案,但您也可以将注释放在类上。

