如何在Restlet中注册Jackson Jdk8模块
How to register Jackson Jdk8 module in Restlet
是否可以在Restlet org.restlet.ext.jackson
扩展包中注册jackson-datatype-jdk8
模块?我需要利用新的 Optional
功能。我的猜测是它应该可以通过转换器服务访问 (getConverterService()
),但是我在文档中找不到任何内容可以准确地说明如何设置模块。
我最终从各种来源拼凑出一个适用于 Restlet 2.3 的答案。我的猜测是,这将针对 Restlet 3 进行重构,并且不适用于 < 2.3 的版本,因此请注意,此解决方案的保质期很可能有限。
第一步是创建一个自定义 Jackson 转换器来实现您的任何自定义要求:
public class CustomJacksonConverter extends JacksonConverter {
@Override
protected <T> JacksonRepresentation<T> create(MediaType mediaType, T source) {
ObjectMapper mapper = createMapper();
JacksonRepresentation<T> jr = new JacksonRepresentation<T>(mediaType, source);
jr.setObjectMapper(mapper);
return jr;
}
@Override
protected <T> JacksonRepresentation<T> create(Representation source, Class<T> objectClass) {
ObjectMapper mapper = createMapper();
JacksonRepresentation<T> jr = new JacksonRepresentation<T>(source, objectClass);
jr.setObjectMapper(mapper);
return jr;
}
private ObjectMapper createMapper() {
JsonFactory jsonFactory = new JsonFactory();
jsonFactory.configure(JsonGenerator.Feature.AUTO_CLOSE_TARGET, false);
ObjectMapper mapper = new ObjectMapper(jsonFactory);
mapper.registerModule(new Jdk8Module());
return mapper;
}
}
然后您需要创建一种方法,用您的新转换器替换默认的 Jackson 转换器:
static void replaceConverter(
Class<? extends ConverterHelper> converterClass,
ConverterHelper newConverter) {
ConverterHelper oldConverter = null;
List<ConverterHelper> converters = Engine.getInstance().getRegisteredConverters();
for (ConverterHelper converter : converters) {
if (converter.getClass().equals(converterClass)) {
converters.remove(converter);
oldConverter = converter;
break;
}
}
converters.add(newConverter);
}
您现在可以替换入站根中的转换器:
replaceConverter(JacksonConverter.class, new CustomJacksonConverter());
@tarka 开场不错,但给我流式传输错误;我提出一些 [影响较小] 的改进:
public class CustomJacksonConverter extends JacksonConverter {
@Override
protected <T> JacksonRepresentation<T> create(MediaType mediaType, T source) {
return new CustomJacksonRepresentation<>(mediaType, source);
}
@Override
protected <T> JacksonRepresentation<T> create(Representation source, Class<T> objectClass) {
return new CustomJacksonRepresentation<>(source, objectClass);
}
}
然后...
public class CustomJacksonRepresentation<T> extends JacksonRepresentation<T> {
public CustomJacksonRepresentation(MediaType mediaType, T object) {
super(mediaType, object);
}
public CustomJacksonRepresentation(Representation representation, Class<T> objectClass) {
super(representation, objectClass);
}
public CustomJacksonRepresentation(T object) {
super(object);
}
@Override
protected ObjectMapper createObjectMapper() {
ObjectMapper mapper = super.createObjectMapper();
mapper.registerModule(new Jdk8Module());
return mapper;
}
}
并以与@tarka 相同的方式更换转换器
是否可以在Restlet org.restlet.ext.jackson
扩展包中注册jackson-datatype-jdk8
模块?我需要利用新的 Optional
功能。我的猜测是它应该可以通过转换器服务访问 (getConverterService()
),但是我在文档中找不到任何内容可以准确地说明如何设置模块。
我最终从各种来源拼凑出一个适用于 Restlet 2.3 的答案。我的猜测是,这将针对 Restlet 3 进行重构,并且不适用于 < 2.3 的版本,因此请注意,此解决方案的保质期很可能有限。
第一步是创建一个自定义 Jackson 转换器来实现您的任何自定义要求:
public class CustomJacksonConverter extends JacksonConverter {
@Override
protected <T> JacksonRepresentation<T> create(MediaType mediaType, T source) {
ObjectMapper mapper = createMapper();
JacksonRepresentation<T> jr = new JacksonRepresentation<T>(mediaType, source);
jr.setObjectMapper(mapper);
return jr;
}
@Override
protected <T> JacksonRepresentation<T> create(Representation source, Class<T> objectClass) {
ObjectMapper mapper = createMapper();
JacksonRepresentation<T> jr = new JacksonRepresentation<T>(source, objectClass);
jr.setObjectMapper(mapper);
return jr;
}
private ObjectMapper createMapper() {
JsonFactory jsonFactory = new JsonFactory();
jsonFactory.configure(JsonGenerator.Feature.AUTO_CLOSE_TARGET, false);
ObjectMapper mapper = new ObjectMapper(jsonFactory);
mapper.registerModule(new Jdk8Module());
return mapper;
}
}
然后您需要创建一种方法,用您的新转换器替换默认的 Jackson 转换器:
static void replaceConverter(
Class<? extends ConverterHelper> converterClass,
ConverterHelper newConverter) {
ConverterHelper oldConverter = null;
List<ConverterHelper> converters = Engine.getInstance().getRegisteredConverters();
for (ConverterHelper converter : converters) {
if (converter.getClass().equals(converterClass)) {
converters.remove(converter);
oldConverter = converter;
break;
}
}
converters.add(newConverter);
}
您现在可以替换入站根中的转换器:
replaceConverter(JacksonConverter.class, new CustomJacksonConverter());
@tarka 开场不错,但给我流式传输错误;我提出一些 [影响较小] 的改进:
public class CustomJacksonConverter extends JacksonConverter {
@Override
protected <T> JacksonRepresentation<T> create(MediaType mediaType, T source) {
return new CustomJacksonRepresentation<>(mediaType, source);
}
@Override
protected <T> JacksonRepresentation<T> create(Representation source, Class<T> objectClass) {
return new CustomJacksonRepresentation<>(source, objectClass);
}
}
然后...
public class CustomJacksonRepresentation<T> extends JacksonRepresentation<T> {
public CustomJacksonRepresentation(MediaType mediaType, T object) {
super(mediaType, object);
}
public CustomJacksonRepresentation(Representation representation, Class<T> objectClass) {
super(representation, objectClass);
}
public CustomJacksonRepresentation(T object) {
super(object);
}
@Override
protected ObjectMapper createObjectMapper() {
ObjectMapper mapper = super.createObjectMapper();
mapper.registerModule(new Jdk8Module());
return mapper;
}
}
并以与@tarka 相同的方式更换转换器