您可以自定义实用程序的配置以序列化/反序列化 JSON(通常是 EAP 中包含的 Jackson),并将模块配置/注册到 Jackson,以指示如何对复杂对象执行此工作。
如果您使用 CDI + Resteasy + Jackson,您可以这样做:
-
提供一个 JAX-RS 自定义 Json 提供程序,您可以在其中使用自定义配置配置您的 Jackson ObjectMapper。例如。
@Provider
@Produces(MediaType.APPLICATION_JSON)
public class CustomJsonProvider implements ContextResolver<ObjectMapper> {
private final ObjectMapper mapper;
public CustomJsonProvider() {
ObjectMapper mapperCdi = null;
//if you are using CDI and you have your own Custom Object Mapper...
BeanManager bm = CDI.current().getBeanManager();
Set<Bean<?>> sBeans = bm.getBeans(ObjectMapper.class);
if (sBeans != null && !sBeans.isEmpty()) {
@SuppressWarnings("unchecked")
Bean<ObjectMapper> bean = (Bean<ObjectMapper>) sBeans.iterator().next();
CreationalContext<ObjectMapper> ctx = bm.createCreationalContext(bean);
mapperCdi = (ObjectMapper) bm.getReference(bean, ObjectMapper.class, ctx);
}
if (mapperCdi != null) {
mapper = mapperCdi;
}else {
//if you are not using CDI, you can create your own Custom Object Mapper or get it from a factory e.g you can do here AppConfig.getObjectMapperInstance() or create a new one
mapper = new ObjectMapper();
//eg. configuration of Hibernate 5 - Jackson Module
Hibernate5Module h5m = new Hibernate5Module();
h5m.configure(Hibernate5Module.Feature.SERIALIZE_IDENTIFIER_FOR_LAZY_NOT_LOADED_OBJECTS, true);
mapper.registerModule((com.fasterxml.jackson.databind.Module) h5m);
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, true);
mapper.setSerializationInclusion(Include.NON_NULL);
//eg. custom Jackson SimpleModule registration
SimpleModule module = new SimpleModule("PaginationModule") {
private static final long serialVersionUID = 1L;
@Override
public void setupModule(SetupContext context) {
context.addAbstractTypeResolver(
new SimpleAbstractTypeResolver().addMapping(Slice.class, SliceClientImpl.class));
context.addAbstractTypeResolver(
new SimpleAbstractTypeResolver().addMapping(Page.class, PageClientImpl.class));
}
};
mapper.registerModule(module);
}
}
@Override
public ObjectMapper getContext(Class<?> objectType) {
return mapper;
}
}
-
如果您使用 CDI,请定义您的“生产者”方法 (@Produce) 和 Jackson ObjectMapper 工厂:
@ApplicationScoped
public class AppConfig {
private static ObjectMapper objectMapper;
// Jackson Object Mapper
@Produces
public ObjectMapper createMapper() {
return AppConfig.getObjectMapperInstance();
}
public static ObjectMapper getObjectMapperInstance() {
if (objectMapper == null) {
objectMapper = new ObjectMapper();
//eg. configuration of Hibernate 5 - Jackson Module
//Hibernate5Module h5m = new Hibernate5Module();
//h5m.configure(Hibernate5Module.Feature.SERIALIZE_IDENTIFIER_FOR_LAZY_NOT_LOADED_OBJECTS, true);
//objectMapper.registerModule((com.fasterxml.jackson.databind.Module) h5m);
//eg. configuration of Joda - Jackson Module
objectMapper.registerModule(new JodaModule());
objectMapper.setTimeZone(TimeZone.getDefault());
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
objectMapper.setSerializationInclusion(Include.NON_NULL);
//eg. custom Jackson SimpleModule registration
SimpleModule module = new SimpleModule("PaginationModule") {
private static final long serialVersionUID = 1L;
@Override
public void setupModule(SetupContext context) {
context.addAbstractTypeResolver(
new SimpleAbstractTypeResolver().addMapping(Slice.class, SliceClientImpl.class));
context.addAbstractTypeResolver(
new SimpleAbstractTypeResolver().addMapping(Page.class, PageClientImpl.class));
}
};
objectMapper.registerModule(module);
}
return objectMapper;
}
}
检查您的提供程序是否已由 Jax-rs / Resteasy 注册:
如果您的 jackson 配置未注册,请尝试在 web.xml 的上下文中添加以下行:
<context-param>
<param-name>resteasy.providers</param-name>
<param-value>your.package.CustomJsonProvider</param-value>
</context-param>
有时,需要配置为Service Provider,添加一个文件“META-INF/services/javax.ws.rs.ext.Providers”(或者在WEB-INF中根据你使用war的打包类型,耳朵、罐子等)与此内容:
your.package.CustomJsonProvider
以另一种方式,您可以返回一个 String(或一个 Response 对象),将您的 ObjectMapper(或处理 JSON 格式的实用程序)注入您的 Service 并创建/在 return 语句之前序列化您的对象。
例如。使用 Json-b
@Path("/myservice")
public class MyService {
@POST
@Produces(MediaType.APPLICATION_JSON)
@Path("/resources")
public Response createJson(@FormParam("name") String name, @FormParam("surname") String surname) {
Response response;
User u = new User(name, surname);
Jsonb jsonb = JsonbBuilder.create();
String jsonString = jsonb.toJson(u);
response = Response.ok(jsonString).build();
return response;
}
}
例如。使用 json-b 以编程方式创建自定义 json
// Create Json and serialize
JsonObject json = Json.createObjectBuilder()
.add("name", "Falco")
.add("age", BigDecimal.valueOf(3))
.add("biteable", Boolean.FALSE).build(); String result = json.toString();
例如。使用 Jackson 以编程方式创建自定义 json
ObjectMapper mapper = new ObjectMapper();
ArrayNode arrayNode = mapper.createArrayNode();
ObjectNode objectNode1 = mapper.createObjectNode();
objectNode1.put("name", "Anna");
objectNode1.put("surname", "T");
arrayNode.add(objectNode1);
ObjectNode objectNode2 = mapper.createObjectNode();
objectNode2.put("name", "John");
objectNode2.put("surname", "X");
arrayNode.add(objectNode2);
String json = arrayNode.toString();
希望对你有帮助。