提问者:小点点

ResEasy,如何防止JAXB注释的POJO编组到JSON


我从一个使用和产生JSON输出的服务开始。我使用resteasy-jackson-Provider进行(de)编组,它从类描述中获取信息。过了一会儿,我被要求将XML添加为MediaType。所以我用JAXB注释注释了我的DTO,并添加了resteasy-jaxb-Provider。结果,我观察到生成的JSON输出来自不同于原始格式的JAXB注释。

我在RestEasy版本3.0.4上。如上所述,我使用以下提供程序

  1. 放松-杰克逊-提供者
  2. resteasy-axb提供者。
  3. resteasy-jettison-Provider,因为我将RestEasy集成到Spring中,并且这个提供程序是一个传递依赖项。

我意识到这个问题,当我

>

  • 使用XmlElementWrapper用于列表和何时
  • 我编写了一个自定义的XmlAdapter它序列化了一个复杂的数据结构Map

    org.codehaus.jackson.map. exc.Un可识别的属性异常:无法识别的字段客户(类x.y.z.OptionalParametersMapType),在[源:org.apache.catalina.connector.CoyoteInputStream@77119553;行:1,列:131]处未标记为可忽略(通过引用链:x.y.z.Request["可选"]-

    那么,如何防止RestEasy使用JAXB注释编组JSON?

    这是请求类:

    @XmlAccessorType(XmlAccessType.FIELD)
    @XmlRootElement(name = "domainRecommendationRequest")
    public class Request {
    
        @XmlJavaTypeAdapter(OptionalParametersXmlAdapter.class)
        private Map<String, List<String>> optional = new HashMap<>();
    
    }
    

    这是XmlAdapter:

    @Override
    public class OptionalParametersXmlAdapter extends XmlAdapter<OptionalParametersMapType, Map<String, List<String>>> {
    
        public OptionalParametersMapType marshal(Map<String, List<String>> v) throws Exception {
            OptionalParametersMapType result = new OptionalParametersMapType();
            List<OptionalParameterItemType> optionalParameterItemTypes = new ArrayList<>();
    
            Set<String> keySet = v.keySet();
    
            for (String parameterName : keySet) {
                OptionalParameterItemType item = new OptionalParameterItemType();
                item.name = parameterName;
                item.values = v.get(parameterName);
                optionalParameterItemTypes.add(item);
            }
    
            result.parameter = optionalParameterItemTypes;
    
            return result;
        }
    }
    

    这是地图的包装:

    public class OptionalParametersMapType {
        public List<OptionalParameterItemType> parameter = new ArrayList<>();
    
    }
    

    这是实际的地图条目:

    public class OptionalParameterItemType {
    
        @XmlAttribute
        public String name;
    
        @XmlElementWrapper(name = "values")
        @XmlElement(name = "value")
        public List<String> values = new ArrayList<>();
    }
    

    这就是我在JSON请求中所期望的:

    {"optional":{"customer":["Mike"]}}
    

    如你所见,我确实打算在XML中采用不同的格式。


  • 共1个答案

    匿名用户

    问题是resteasy-jackson-Provider依赖于jackson-module-jaxb-注解,它用于将JAXB注解/注解类映射到JSON。现在在正常显式使用ObjectMapper时,为了使用这个模块,我们需要显式注册这个模块,例如(参见此处)

    ObjectMapper objectMapper = new ObjectMapper();
    JaxbAnnotationModule module = new JaxbAnnotationModule();
    objectMapper.registerModule(module);
    
    -- OR --
    
    AnnotationIntrospector introspector = new JaxbAnnotationIntrospector();
    objectMapper.setAnnotationIntrospector(introspector);
    

    话虽如此,似乎(没有任何事实证实,但看起来很可能)当为您的序列化创建ObjectMapper时,当注意到JAXB注释时,模块会自动注册。

    我不知道我们可以使用任何可能的注释来阻止这种情况,但解决此问题的一种方法是为ObjectMapper创建一个ContextResolver,我们不注册JAXB模块。

    @Provider
    public class ObjectMapperContextResolver 
                      implements ContextResolver<ObjectMapper> {
        @Override
        public ObjectMapper getContext(Class<?> type) {
            return new ObjectMapper();
        }  
    }
    

    一旦我们将其注册到我们的JAXRS应用程序中,它将成为用于获取ObjectMapper的上下文解析器。我们可以进一步配置ObjectMapper,但这只是一个示例。测试它,它按预期工作。