org.codehaus.jackson.map.exc.UnrecognizedPropertyException:无法识别的字段" errorMessages" (类ReasonDTO),未标记为可忽略

时间:2014-03-30 04:21:19

标签: json

我正在尝试将返回的JSON从REST服务调用解析回DTO对象,以便可以在客户端使用它。客户端代码如下所示:

@Test
public void retrieveAllReasonsUsingJSONandGet() throws Exception {
    List<Object> providers = new ArrayList<Object>();
    providers.add(new org.codehaus.jackson.jaxrs.JacksonJsonProvider());

    WebClient client = WebClient.create(endpointUrl + "/retrieveall", providers);

    Response r = client.accept(MediaType.APPLICATION_JSON).type(MediaType.APPLICATION_JSON).get();
    assertEquals(Response.Status.OK.getStatusCode(), r.getStatus());

    MappingJsonFactory factory = new MappingJsonFactory();
    JsonParser parser = factory.createJsonParser((InputStream)r.getEntity());
    TypeReference<List<ReasonDTO>> ref = new TypeReference<List<ReasonDTO>>() {} ;
    List<ReasonDTO> allReasons = (List<ReasonDTO>) parser.readValueAs(ref);

    assertEquals(43, allReasons.size());
} // retrieveAllReasonsUsingJSONandGet

返回的JSON的一个节(其中有43个)看起来像:

{
    "reasonCode": "...",
    "reason": "...",
    "hasError": false,
    "errorMessages": [],
    "hasWarning": false,
    "warningMessages": []
},

DTO对象看起来像(忽略XML的东西,因为使用JAX-WS传回相同的DTO,因此它们也需要作为XML进行编组/解组):

public class ReasonDTO {
    private String reasonCode;
    private String reason;
    private boolean hasError = false;
    @XmlElementWrapper(name = "errorMessages")
    @XmlElement(name = "errorMessage")
    private List<String> errorMessages = new ArrayList<String>();
    private boolean hasWarning = false;
    @XmlElementWrapper(name = "warningMessages")
    @XmlElement(name = "warningMessage")
    private List<String> warningMessages = new ArrayList<String>();

抛出的完整异常是:

org.codehaus.jackson.map.exc.UnrecognizedPropertyException: Unrecognized field "errorMessages" (Class ReasonDTO), not marked as ignorable
 at [Source: sun.net.www.protocol.http.HttpURLConnection$HttpInputStream@29b429b4; line: 1, column: 91] (through reference chain: ReasonDTO["errorMessages"])
    at org.codehaus.jackson.map.exc.UnrecognizedPropertyException.from(UnrecognizedPropertyException.java:53)
    at org.codehaus.jackson.map.deser.StdDeserializationContext.unknownFieldException(StdDeserializationContext.java:248)
    at org.codehaus.jackson.map.deser.StdDeserializer.reportUnknownProperty(StdDeserializer.java:542)
    at org.codehaus.jackson.map.deser.StdDeserializer.handleUnknownProperty(StdDeserializer.java:528)
    at org.codehaus.jackson.map.deser.BeanDeserializer.handleUnknownProperty(BeanDeserializer.java:671)
    at org.codehaus.jackson.map.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:519)
    at org.codehaus.jackson.map.deser.BeanDeserializer.deserialize(BeanDeserializer.java:350)
    at org.codehaus.jackson.map.deser.CollectionDeserializer.deserialize(CollectionDeserializer.java:116)
    at org.codehaus.jackson.map.deser.CollectionDeserializer.deserialize(CollectionDeserializer.java:93)
    at org.codehaus.jackson.map.deser.CollectionDeserializer.deserialize(CollectionDeserializer.java:25)
    at org.codehaus.jackson.map.ObjectMapper._readValue(ObjectMapper.java:1961)
    at org.codehaus.jackson.map.ObjectMapper.readValue(ObjectMapper.java:852)
    at org.codehaus.jackson.JsonParser.readValueAs(JsonParser.java:1118)
    at TE_ReasonREST_ServiceTester.retrieveAllReasonsUsingJSONandPost(TE_ReasonREST_ServiceTester.java:73)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:48)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:600)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)

错误消息似乎在说&#34; errorMessages&#34;在DTO中找不到该字段,但我的存在。我读过的其他帖子建议使用

@JsonIgnoreProperties

但我不想忽略errorMessage,因为如果有一些存在,则表示存在问题。

有关我的问题可能是什么以及我应该在哪里寻找解决方案的任何想法?

非常感谢。

1 个答案:

答案 0 :(得分:4)

我解决了它:

@JsonDeserialize(as=ArrayList.class, contentAs=String.class)
@XmlElementWrapper(name = "warningMessages")
@XmlElement(name = "warningMessage")
private List<String> warningMessages = new ArrayList<String>();

@JsonDeserialize(as = ArrayList.class,contentAs = String.class)

编辑 -

package com.company.client.hibernate.helper;

import java.util.ArrayList;
import java.util.List;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;

import org.codehaus.jackson.map.annotate.JsonDeserialize;

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class ResultDTO {
    private boolean hasError = false; 
    @JsonDeserialize(as=ArrayList.class, contentAs=String.class) 
    @XmlElementWrapper(name = "errorMessages") 
    @XmlElement(name = "errorMessage") 
    private List<String> errorMessages = new ArrayList<String>(); 
    private boolean hasWarning = false; 
    @JsonDeserialize(as=ArrayList.class, contentAs=String.class) 
    @XmlElementWrapper(name = "warningMessages") 
    @XmlElement(name = "warningMessage") 
    private List<String> warningMessages = new ArrayList<String>(); 

    public boolean isHasError() { 
        return hasError; 
    }
    public void setHasError(boolean hasError) { 
        this.hasError = hasError; 
    }
    public List<String> getErrorMessages() { 
        return this.errorMessages; 
    }
    public void addErrorMessage(String errorMessage) { 
        this.errorMessages.add(errorMessage); 
    }
    public boolean isHasWarning() { 
        return this.hasWarning; 
    }
    public void setHasWarning(boolean hasWarning) { 
        this.hasWarning = hasWarning; 
    }
    public List<String> getWarningMessages() { 
        return this.warningMessages; 
    }
    public void addWarningMessage(String warningMessage) { 
        this.warningMessages.add(warningMessage); 
    }  
}