在Jboss EAP 7.2.0.GA中处理JSON序列化

JF *_*ier 4 java jboss json jax-rs

在我的Jboss中,我尝试使用JAX-RS实现REST服务。它应该返回某些对象的JSON序列化版本

 @GET
  @Produces({ MediaType.APPLICATION_JSON })
  public BlacklistDTO getByName(
      @QueryParam("gav") final List<String> gavStringList)
  {
     ...
  }
Run Code Online (Sandbox Code Playgroud)

对象的某些部分未正确序列化(结果为空)。如何处理/自定义Jboss生成JSON的方式?

Ari*_*era 6

您可以自定义实用程序的配置,以对JSON(通常包括在EAP中的Jackson)进行序列化/反序列化,并向Jackson配置/注册模块,以指示如何在复杂对象上执行此工作。

如果您使用的是CDI + Resteasy + Jackson,则可以执行以下操作:

  1. 提供一个JAX-RS定制Json Provider,您可以在其中使用定制配置来配置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;
    }
    }
    
    Run Code Online (Sandbox Code Playgroud)
  2. 如果您使用的是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;
    }
    }
    
    Run Code Online (Sandbox Code Playgroud)
  3. 检查您的提供者是否已由Jax-rs / Resteasy注册:

如果您的杰克逊配置未注册,请尝试在web.xml中的上下文中添加以下行:

<context-param>

  <param-name>resteasy.providers</param-name>

  <param-value>your.package.CustomJsonProvider</param-value>

</context-param>
Run Code Online (Sandbox Code Playgroud)

有时,需要配置为服务提供者,添加文件“ META-INF / services / javax.ws.rs.ext.Providers”(或在WEB-INF中,具体取决于您使用war,ear,jar的包装类型等等)的内容:

your.package.CustomJsonProvider
Run Code Online (Sandbox Code Playgroud)

换句话说,您可以返回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;
    }
}
Run Code Online (Sandbox Code Playgroud)

例如。使用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();
Run Code Online (Sandbox Code Playgroud)

例如。使用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();
Run Code Online (Sandbox Code Playgroud)

希望能帮助到你。