HttpMessageNotReadableException:无法使用Spring for Android读取JSON:无法识别的字段

Fel*_*sso 11 spring android jackson

我正在开发和Android应用程序,它与我的服务器通信.这种沟通是通过Spring框架和Jackson完成的.我正在成功发送我的服务器请求,但我没有收到回复.这就是我所做的:

Android应用:

public Loja getLoja() {
        RestTemplate restTemplate = new RestTemplate();
        restTemplate.getMessageConverters().add(new MappingJacksonHttpMessageConverter());
        restTemplate.setRequestFactory(new HttpComponentsClientHttpRequestFactory());

        String url = BASE_URL + "/android/played.json";
        return restTemplate.getForObject(url, Loja.class);
    }
Run Code Online (Sandbox Code Playgroud)

Loja类(我有两个版本.一个在Android应用程序中,另一个在Server中.它们完全相同):

public class Loja {

    private String nome;
    private String xValue;
    private String yValue;
    private String andar;

    public Loja(String nome, String xValue, String yValue, String andar) {
        this.nome = nome;
        this.xValue = xValue;
        this.yValue = yValue;
        this.andar = andar;
    }

    public Loja() {
    }

    public String getAndar() {
        return andar;
    }

    public void setAndar(String andar) {
        this.andar = andar;
    }

    public String getNome() {
        return nome;
    }

    public void setNome(String nome) {
        this.nome = nome;
    }

    public String getxValue() {
        return xValue;
    }

    public void setxValue(String xValue) {
        this.xValue = xValue;
    }

    public String getyValue() {
        return yValue;
    }

    public void setyValue(String yValue) {
        this.yValue = yValue;
    }

}
Run Code Online (Sandbox Code Playgroud)

这是我的控制器:

@RequestMapping("/android/played")
    public ModelAndView getLoja() {
        System.out.println("Android Resquest.");

        Loja loja = new Loja("teste", "20", "30", "1");

        ModelAndView mav = new ModelAndView();
        mav.addObject("Loja", loja);
        return mav;
    }
Run Code Online (Sandbox Code Playgroud)

有了这些,我在Android应用程序中获得了followin异常:

03-21 22:13:06.197: E/AndroidRuntime(25342): java.lang.RuntimeException: An error occured while executing doInBackground()
03-21 22:13:06.197: E/AndroidRuntime(25342):    at android.os.AsyncTask$3.done(AsyncTask.java:299)
03-21 22:13:06.197: E/AndroidRuntime(25342):    at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
03-21 22:13:06.197: E/AndroidRuntime(25342):    at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
03-21 22:13:06.197: E/AndroidRuntime(25342):    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
03-21 22:13:06.197: E/AndroidRuntime(25342):    at java.util.concurrent.FutureTask.run(FutureTask.java:137)
03-21 22:13:06.197: E/AndroidRuntime(25342):    at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
03-21 22:13:06.197: E/AndroidRuntime(25342):    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
03-21 22:13:06.197: E/AndroidRuntime(25342):    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
03-21 22:13:06.197: E/AndroidRuntime(25342):    at java.lang.Thread.run(Thread.java:856)
03-21 22:13:06.197: E/AndroidRuntime(25342): Caused by: org.springframework.http.converter.HttpMessageNotReadableException: Could not read JSON: Unrecognized field "Loja" (Class com.example.androidspring.Loja), not marked as ignorable
03-21 22:13:06.197: E/AndroidRuntime(25342):  at [Source: org.apache.http.conn.EofSensorInputStream@422e3c58; line: 1, column: 10] (through reference chain: com.example.androidspring.Loja["Loja"]); nested exception is org.codehaus.jackson.map.exc.UnrecognizedPropertyException: Unrecognized field "Loja" (Class com.example.androidspring.Loja), not marked as ignorable
03-21 22:13:06.197: E/AndroidRuntime(25342):  at [Source: org.apache.http.conn.EofSensorInputStream@422e3c58; line: 1, column: 10] (through reference chain: com.example.androidspring.Loja["Loja"])
03-21 22:13:06.197: E/AndroidRuntime(25342):    at org.springframework.http.converter.json.MappingJacksonHttpMessageConverter.readInternal(MappingJacksonHttpMessageConverter.java:125)
03-21 22:13:06.197: E/AndroidRuntime(25342):    at org.springframework.http.converter.AbstractHttpMessageConverter.read(AbstractHttpMessageConverter.java:147)
03-21 22:13:06.197: E/AndroidRuntime(25342):    at org.springframework.web.client.HttpMessageConverterExtractor.extractData(HttpMessageConverterExtractor.java:76)
03-21 22:13:06.197: E/AndroidRuntime(25342):    at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:484)
03-21 22:13:06.197: E/AndroidRuntime(25342):    at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:439)
03-21 22:13:06.197: E/AndroidRuntime(25342):    at org.springframework.web.client.RestTemplate.getForObject(RestTemplate.java:237)
03-21 22:13:06.197: E/AndroidRuntime(25342):    at com.example.androidspring.MainActivity.getLoja(MainActivity.java:59)
03-21 22:13:06.197: E/AndroidRuntime(25342):    at com.example.androidspring.MainActivity$DownloadFilesTask.doInBackground(MainActivity.java:72)
03-21 22:13:06.197: E/AndroidRuntime(25342):    at com.example.androidspring.MainActivity$DownloadFilesTask.doInBackground(MainActivity.java:1)
03-21 22:13:06.197: E/AndroidRuntime(25342):    at android.os.AsyncTask$2.call(AsyncTask.java:287)
03-21 22:13:06.197: E/AndroidRuntime(25342):    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
03-21 22:13:06.197: E/AndroidRuntime(25342):    ... 5 more
03-21 22:13:06.197: E/AndroidRuntime(25342): Caused by: org.codehaus.jackson.map.exc.UnrecognizedPropertyException: Unrecognized field "Loja" (Class com.example.androidspring.Loja), not marked as ignorable
03-21 22:13:06.197: E/AndroidRuntime(25342):  at [Source: org.apache.http.conn.EofSensorInputStream@422e3c58; line: 1, column: 10] (through reference chain: com.example.androidspring.Loja["Loja"])
03-21 22:13:06.197: E/AndroidRuntime(25342):    at org.codehaus.jackson.map.deser.StdDeserializationContext.unknownFieldException(StdDeserializationContext.java:267)
03-21 22:13:06.197: E/AndroidRuntime(25342):    at org.codehaus.jackson.map.deser.std.StdDeserializer.reportUnknownProperty(StdDeserializer.java:649)
03-21 22:13:06.197: E/AndroidRuntime(25342):    at org.codehaus.jackson.map.deser.std.StdDeserializer.handleUnknownProperty(StdDeserializer.java:635)
03-21 22:13:06.197: E/AndroidRuntime(25342):    at org.codehaus.jackson.map.deser.BeanDeserializer.handleUnknownProperty(BeanDeserializer.java:1355)
03-21 22:13:06.197: E/AndroidRuntime(25342):    at org.codehaus.jackson.map.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:717)
03-21 22:13:06.197: E/AndroidRuntime(25342):    at org.codehaus.jackson.map.deser.BeanDeserializer.deserialize(BeanDeserializer.java:580)
03-21 22:13:06.197: E/AndroidRuntime(25342):    at org.codehaus.jackson.map.ObjectMapper._readMapAndClose(ObjectMapper.java:2723)
03-21 22:13:06.197: E/AndroidRuntime(25342):    at org.codehaus.jackson.map.ObjectMapper.readValue(ObjectMapper.java:1914)
03-21 22:13:06.197: E/AndroidRuntime(25342):    at org.springframework.http.converter.json.MappingJacksonHttpMessageConverter.readInternal(MappingJacksonHttpMessageConverter.java:122)
03-21 22:13:06.197: E/AndroidRuntime(25342):    ... 15 more
Run Code Online (Sandbox Code Playgroud)

由于我的不满,它不承认我的Loja课程.但它们完全一样!还有什么呢?

nic*_*ild 11

异常似乎表明,虽然Jackson映射器试图Loja从返回的json 创建一个,但它遇到了一个带有Loja键的json字段,它不知道如何处理(因为Lojajava对象中没有字段)名为"Loja"),所以失败了.这似乎是合乎逻辑的,因为看起来服务器正在有效地返回这个json结构:

{"Loja":{"nome":"teste","xValue":"20","yValue":"30","andar":"1"}}
Run Code Online (Sandbox Code Playgroud)

因此,您有两个主要选项.

  1. 更改传递给的对象getForObject()
  2. 更改从服务器返回的json.

对于第一个,您可以让您的客户端进行包含a 的getForObject()传递.ObjectLoja

像这个类的东西:

class MyObj {
    private Loja Loja;

    public void setLoja(Loja loja) {
        this.Loja = loja;
    }

    public Loja getLoja() {
        return this.Loja;
    }
}
Run Code Online (Sandbox Code Playgroud)

与此通话一起使用:

restTemplate.getForObject(url, MyObj.class);
Run Code Online (Sandbox Code Playgroud)

或者,您可以让服务器将Loja对象字段作为模型的一部分返回,或者更好的是,返回Loja您创建的对象的实例.Spring非常聪明,可以利用Jackson将你的POJO变成你期望的正确的json模型.

@RequestMapping("/android/played")
public Loja getLoja() {
    System.out.println("Android Resquest.");

    return new Loja("teste", "20", "30", "1");
}
Run Code Online (Sandbox Code Playgroud)

哪个会产生这个json:

{"nome":"teste","xValue":"20","yValue":"30","andar":"1"}
Run Code Online (Sandbox Code Playgroud)

您的getForObject()方法在客户端可以通过当前的方式读取.