Jaxb 在泽西岛使用Gson代替Jackson
我有一个使用和生成JSON对象的RESTful服务,我希望Jersey使用Gson而不是JacksonJaxb 在泽西岛使用Gson代替Jackson,jaxb,jersey,jax-rs,jackson,gson,Jaxb,Jersey,Jax Rs,Jackson,Gson,我有一个使用和生成JSON对象的RESTful服务,我希望Jersey使用Gson而不是Jackson 如何做到这一点…?您需要编写和的自定义实现(可能在同一个类中)并向Jersey注册(如果您使用包扫描,@Provider注释就足够了)——非常像这样: @Provider @使用({MediaType.APPLICATION_JSON,“text/JSON”}) @产生({MediaType.APPLICATION_JSON,“text/JSON”}) 类GsonJsonProvider实现
如何做到这一点…?您需要编写和的自定义实现(可能在同一个类中)并向Jersey注册(如果您使用包扫描,
@Provider
注释就足够了)——非常像这样:
@Provider
@使用({MediaType.APPLICATION_JSON,“text/JSON”})
@产生({MediaType.APPLICATION_JSON,“text/JSON”})
类GsonJsonProvider实现
MessageBodyReader,
MessageBodyWriter{。。。
您可以在这里找到一个完全有效的示例:
将会有一个工作实现,但是会有一些新的成就-比如GsonUtil
只用于公开
内容
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import javax.ws.rs.Consumes;
import javax.ws.rs.Produces;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.ext.MessageBodyReader;
import javax.ws.rs.ext.MessageBodyWriter;
import javax.ws.rs.ext.Provider;
@Provider
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public class GsonJerseyProvider implements MessageBodyWriter<Object>,
MessageBodyReader<Object> {
private static final String UTF_8 = "UTF-8";
@Override
public boolean isReadable(Class<?> type, Type genericType,
java.lang.annotation.Annotation[] annotations, MediaType mediaType) {
return true;
}
@Override
public Object readFrom(Class<Object> type, Type genericType,
Annotation[] annotations, MediaType mediaType,
MultivaluedMap<String, String> httpHeaders, InputStream entityStream)
throws IOException {
InputStreamReader streamReader = new InputStreamReader(entityStream,
UTF_8);
try {
return GsonUtil.getInstance().fromJson(streamReader, genericType);
} catch (com.google.gson.JsonSyntaxException e) {
// Log exception
} finally {
streamReader.close();
}
return null;
}
@Override
public boolean isWriteable(Class<?> type, Type genericType,
Annotation[] annotations, MediaType mediaType) {
return true;
}
@Override
public long getSize(Object object, Class<?> type, Type genericType,
Annotation[] annotations, MediaType mediaType) {
return -1;
}
@Override
public void writeTo(Object object, Class<?> type, Type genericType,
Annotation[] annotations, MediaType mediaType,
MultivaluedMap<String, Object> httpHeaders,
OutputStream entityStream) throws IOException,
WebApplicationException {
OutputStreamWriter writer = new OutputStreamWriter(entityStream, UTF_8);
try {
GsonUtil.getInstance().toJson(object, genericType, writer);
} finally {
writer.close();
}
}
}
import java.io.IOException;
导入java.io.InputStream;
导入java.io.InputStreamReader;
导入java.io.OutputStream;
导入java.io.OutputStreamWriter;
导入java.lang.annotation.annotation;
导入java.lang.reflect.Type;
导入javax.ws.rs.Consumes;
导入javax.ws.rs.products;
导入javax.ws.rs.WebApplicationException;
导入javax.ws.rs.core.MediaType;
导入javax.ws.rs.core.MultivaluedMap;
导入javax.ws.rs.ext.MessageBodyReader;
导入javax.ws.rs.ext.MessageBodyWriter;
导入javax.ws.rs.ext.Provider;
@提供者
@产生(MediaType.APPLICATION_JSON)
@使用(MediaType.APPLICATION_JSON)
公共类GsonJerseyProvider实现MessageBodyWriter,
MessageBodyReader{
私有静态最终字符串UTF_8=“UTF-8”;
@凌驾
公共布尔值可读取(类类型、类型genericType、,
java.lang.annotation.annotation[]注释,MediaType(MediaType){
返回true;
}
@凌驾
公共对象读取自(类类型、类型genericType、,
注释[]注释,MediaType MediaType,
多值映射HttpHeader,InputStream entityStream)
抛出IOException{
InputStreamReader streamReader=新的InputStreamReader(entityStream,
UTF_8);
试一试{
从JSON(streamReader,genericType)返回GsonUtil.getInstance();
}catch(com.google.gson.JsonSyntaxException e){
//日志异常
}最后{
streamReader.close();
}
返回null;
}
@凌驾
公共布尔值可写(类类型、类型genericType、,
注释[]注释,MediaType(MediaType){
返回true;
}
@凌驾
公共长getSize(对象、类类型、类型genericType、,
注释[]注释,MediaType(MediaType){
返回-1;
}
@凌驾
public void writeTo(对象、类类型、类型genericType、,
注释[]注释,MediaType MediaType,
多值MAP HttpHeader,
OutputStream entityStream)引发IOException,
WebApplicationException{
OutputStreamWriter writer=新的OutputStreamWriter(entityStream,UTF_8);
试一试{
GsonUtil.getInstance().toJson(对象、genericType、编写器);
}最后{
writer.close();
}
}
}
您应该解决在pom中添加此依赖项的问题
<dependency>
<groupId>org.zalando.phrs</groupId>
<artifactId>jersey-media-json-gson</artifactId>
<version>0.1</version>
</dependency>
org.zalando.phrs
Payara 4
我很难让我的自定义Gson@Provider
使用嵌入GlassFish/Payara中的Jersey。在这种情况下,您必须将属性Jersey.config.server.DisableOxyJSON
设置为true
例如:
@ApplicationPath("/api")
public class MyApplication extends Application {
@Override
public Map<String, Object> getProperties() {
Map<String, Object> props = new HashMap<>();
props.put("jersey.config.server.disableMoxyJson", true);
return props;
}
}
帕亚拉5号
Payara 5支持API,因此继续使用Gson是没有意义的。我建议迁移到JSON-B。我已经有了这样的提供者,但出于某种原因,它仍然使用Jackson(如果有帮助的话,我使用Glassfish 3.1.1)。如何向Jersey注册您的GsonProvider?您的服务器是否在启动时输出类似于找到的提供程序类:your.Provider.class.name
?您的提供程序是否被调用,并且可能返回一些告诉Jersey它不兼容的内容?请尝试在提供程序类中的所有方法上添加断点。IMHO与Gson相比,这更容易如果你不能或不想注释你的模型类(与Jackson相比),那么更容易控制JSON的结构/格式。原因有很多:首先,根据最近的基准测试,Jackson的速度较慢。其次,它强制您对类进行注释,而不是简单地使用POJO。第三,Gson序列化了整个对象,而不仅仅是公共字段(在良好的设计实践中,您会得到许多重要的非公共字段)@StaxMan原因之一可能是Jackson ObjectMapper导致JDK 1中的核心转储。8@MosheBixenshpaner请链接到慢度——我没有看到任何。Gson一直在改进(2.1是不错的),但仍然落后于我所看到的一切。Jackson absolute不需要注释(另外,可以使用混合注释来避免注释值类)大多数情况下。最后:Jackson不需要公共字段;但是getter或更改默认可见性——我不同意默认情况下序列化所有私有字段是一种很好的做法;但是如果需要的话,Jackson是完全可以做到的。@StaxMan See一直在使用它,效果很好,但是……为什么type.equals(genericType)呢
?似乎您总是可以使用Type
,因为gson支持它,并且比类拥有更多的信息。您是对的-应该使用genericType
而不是equals检查-如果您愿意,您可以在github上创建一个pull请求。我还将使用我的测试用例测试它,然后编辑我的答案。感谢@sargue更新GsonJerseyProvider-我在这里更新了复制和粘贴解决方案-您可以在github链接下直接找到一个运行示例。github中不再存在项目
@ApplicationPath("/api")
public class MyApplication extends Application {
@Override
public Map<String, Object> getProperties() {
Map<String, Object> props = new HashMap<>();
props.put("jersey.config.server.disableMoxyJson", true);
return props;
}
}
new ClientConfig()
.register(MyGsonProvider.class)
.property("jersey.config.client.disableMoxyJson", true);