使用Spring MVC中的JAXB注释,使用Jackson反序列化时出现问题

6

我在调用服务时遇到了问题,无法让Jackson正确地将json反序列化为对象(具体来说,我们正在使用Jackson的JAXB注释功能,因为我们还希望服务使用XML)。我正在使用Spring MVC,并使用RestTemplate类调用服务。

这是我为我的junit设置MappingJacksonHttpMessageConverter的位置:

ObjectMapper jsonMapper = new ObjectMapper();
AnnotationIntrospector introspector = new JaxbAnnotationIntrospector();
jsonMapper.getDeserializationConfig().setAnnotationIntrospector(introspector);
jsonMapper.getSerializationConfig().setAnnotationIntrospector(introspector);
jsonMapper.getSerializationConfig().setSerializationInclusion(Inclusion.NON_NULL);
MappingJacksonHttpMessageConverter jacksonConverter = new MappingJacksonHttpMessageConverter();
jacksonConverter.setObjectMapper(jsonMapper);
List<HttpMessageConverter<?>> converters = new ArrayList<HttpMessageConverter<?>>();
converters.add(jacksonConverter);
template.setMessageConverters(converters);

我这样调用服务:

HttpHeaders requestHeaders = new HttpHeaders();
requestHeaders.set("Accept", "application/json");
HttpEntity<String> requestEntity = new HttpEntity<String>(requestHeaders);
ResponseEntity<NamedSystem> responseEntity = template.exchange(baseURL + "/{NamedSystemId}", 
        HttpMethod.GET, requestEntity, NamedSystem.class, orgId1);

我的NamedSystem类的设置如下:

@XmlRootElement(name = "NamedSystem", namespace = "http://schemas.abc.workplace.com/NamedSystem")
public class NamedSystem {
    private String id;
    private String name;
    private String description;
    private Set<NamedSystemAlias> aliases;
    private String href;

    @XmlAttribute(required = false, name = "id")
    public String getId() {
        return id;
    }


    public void setId(String id) {
        this.id = id;
    }


    @XmlAttribute(required = false, name = "name")
    public String getName() {
        return name;
    }


    public void setName(String name) {
        this.name = name;
    }


    @XmlAttribute(required = false, name = "description")
    public String getDescription() {
        return description;
    }


    public void setDescription(String description) {
        this.description = description;
    }


    @XmlElementWrapper(required = false, name = "aliases", namespace = "http://schemas.abc.workplace.com/NamedSystem")
    @XmlElement(required = false, name = "alias", namespace = "http://schemas.abc.workplace.com/NamedSystem")
    public Set<NamedSystemAlias> getAliases() {
        return aliases;
    }


    public void setAliases(Set<NamedSystemAlias> aliases) {
        this.aliases = aliases;
    }

    @XmlAttribute(required = true, name = "href")
    public String getHref() {
        return href;
    }


    public void setHref(String href) {
        this.href = href;
    }
}

这是导致错误的信息:
org.springframework.web.client.ResourceAccessException: I/O error: Unrecognized field "NamedSystem" (Class com.workplace.abc.named.NamedSystem), not marked as ignorable
 at [Source: sun.net.www.protocol.http.HttpURLConnection$HttpInputStream@c1429c; line: 1, column: 2]; nested exception is org.codehaus.jackson.map.JsonMappingException: Unrecognized field "NamedSystem" (Class com.workplace.abc.named.NamedSystem), not marked as ignorable
 at [Source: sun.net.www.protocol.http.HttpURLConnection$HttpInputStream@c1429c; line: 1, column: 2]
 at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:453)
....
Caused by: org.codehaus.jackson.map.JsonMappingException: Unrecognized field "NamedSystem" (Class com.workplace.abc.named.NamedSystem), not marked as ignorable
 at [Source: sun.net.www.protocol.http.HttpURLConnection$HttpInputStream@c1429c; line: 1, column: 2]
 at org.codehaus.jackson.map.JsonMappingException.from(JsonMappingException.java:159)
 at org.codehaus.jackson.map.deser.StdDeserializationContext.unknownFieldException(StdDeserializationContext.java:247)
 at org.codehaus.jackson.map.deser.StdDeserializer.reportUnknownProperty(StdDeserializer.java:366)
 at org.codehaus.jackson.map.deser.StdDeserializer.handleUnknownProperty(StdDeserializer.java:352)
 at org.codehaus.jackson.map.deser.BeanDeserializer.handleUnknownProperty(BeanDeserializer.java:543)
 at org.codehaus.jackson.map.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:402)
 at org.codehaus.jackson.map.deser.BeanDeserializer.deserialize(BeanDeserializer.java:287)
 at org.codehaus.jackson.map.ObjectMapper._readMapAndClose(ObjectMapper.java:1588)
 at org.codehaus.jackson.map.ObjectMapper.readValue(ObjectMapper.java:1172)
 at org.springframework.http.converter.json.MappingJacksonHttpMessageConverter.readInternal(MappingJacksonHttpMessageConverter.java:132)
 at org.springframework.http.converter.AbstractHttpMessageConverter.read(AbstractHttpMessageConverter.java:154)
 at org.springframework.web.client.HttpMessageConverterExtractor.extractData(HttpMessageConverterExtractor.java:74)
 at org.springframework.web.client.RestTemplate$ResponseEntityResponseExtractor.extractData(RestTemplate.java:619)
 at org.springframework.web.client.RestTemplate$ResponseEntityResponseExtractor.extractData(RestTemplate.java:1)
 at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:446)
 ... 32 more

看起来它无法识别根元素“NamedSystem”,以便进行反序列化。我该如何让它这样做?我已经看到使用相同JAXB注释的示例,并且它们可以正常工作,所以我不确定我的情况有什么不同或者如何强制正确地反序列化它。如果有人能提供任何帮助,我将不胜感激。


我应该注意,我也尝试了非常简单地添加转换器,例如:converters.add(new MappingJacksonHttpMessageConverter()); 并且获得了相同的结果(我认为我在发布中设置的方式是不必要但并不具有害性)。通过一些调试,我几乎百分之百确定问题不在序列化上。只是我需要找到一种让JSON解析器识别NamedSystem的方法。 - AHungerArtist
如果我能够摆脱Json中的NamedSystem部分,问题也可能得到解决。 - AHungerArtist
1个回答

2

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接