在Android应用程序上使用restful服务

时间:2016-07-29 07:11:33

标签: java android json rest resttemplate

我有自己的宁静网络应用程序(弹簧启动),它生成JSON数据,我想获取JSON数据并在我的Android应用程序上显示它。但是我得到一个NullPointerException和JsonMappingException。任何帮助将不胜感激。

Web App Controller:

@RestController
@RequestMapping("/")
public class IndexController {
    private ProductService productService;

    @Autowired
    public void setProductService(ProductService productService) {
        this.productService = productService;
    }

    @RequestMapping(method = RequestMethod.GET , produces = MediaType.APPLICATION_JSON_VALUE)
    public Iterable<Product> getAllProducts(){

        return    productService.listAllProducts();


    }

}

由网络应用程序生成的JSON数据(它继续通过流式传输api获取推文):

[{"productId":758916869776478208,"description":"LYS Türkiye 688’si ve 857.si Ömer Özyer’den  Fethiye’nin Altın Kızları #haber #sondakika @habermatik aracılığıyla","name":"erkanilik48","location":"fethiye gazetesi sahibi"},{"productId":758916869961101316,"description":"I'm at Balıkesir in Balıkesir, Türkiye","name":"onplaka","location":"Bursa-Balıkesır"},{"productId":758917112295362560,"description":"Erdoğan'sız Türkiye diyorlar anket yaptım bakalım ahali nasıl Türkiye istiyor anket süresi 10 dakika .","name":"TakipGalaxi","location":"New York , LITTLE ITALY"},{"productId":758917117353668610,"description":"RT @TATARKENAN23: AğlarkenSeni Türkiye ye götüreceğiz denildiğinde susan çocuklar varHalep için DÛA bekliyoruz","name":"NecmeddinLd","location":null}]

Android应用程序MainActivity:

 @Override
    protected void onStart() {
        super.onStart();
        new HttpRequestTask().execute();


    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        if (id == R.id.action_refresh) {
            new HttpRequestTask().execute();
            return true;
        }

        return super.onOptionsItemSelected(item);
    }


    private class HttpRequestTask extends AsyncTask<Void, Void, Greeting> {
        @Override
        protected Greeting doInBackground(Void... params) {
            try {
                final String url = "blabla";
                RestTemplate restTemplate = new RestTemplate();
                restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
                Greeting  greeting;
                greeting = restTemplate.getForObject(url, Greeting.class);
                return greeting;
            } catch (Exception e) {
                Log.e("MainActivity", e.getMessage(), e);
            }

            return null;
        }

        @Override
        protected void onPostExecute(Greeting greeting) {
            TextView text1 = (TextView) findViewById(R.id.textView);
            TextView text2 = (TextView) findViewById(R.id.textView2);
            TextView text3 = (TextView) findViewById(R.id.textView3);
            TextView text4 = (TextView) findViewById(R.id.textView4);

            assert text1 != null;
            text1.setText((int) greeting.getProductId());
            assert text2 != null;
            text2.setText(greeting.getDescription());
            assert text3 != null;
            text3.setText(greeting.getName());
            assert text4 != null;
            text4.setText(greeting.getLocation());


        }

    }
}

CONSOLE LOG:

                                                                        [ 07-29 06:50:00.665  2886: 2932 D/         ]
                                                                           HostConnection::get() New Host Connection established 0xae552980, tid 2932
    07-29 06:50:00.706 2886-2932/org.hello.tweetconsumer I/OpenGLRenderer: 

Initialized EGL, version 1.4
07-29 06:50:00.740 2886-2932/org.hello.tweetconsumer W/EGL_emulation: eglSurfaceAttrib not implemented
07-29 06:50:00.740 2886-2932/org.hello.tweetconsumer W/OpenGLRenderer: Failed to set EGL_SWAP_BEHAVIOR on surface 0xaaac9420, error=EGL_SUCCESS
07-29 06:50:02.663 2886-2931/org.hello.tweetconsumer E/MainActivity: Could not read JSON: Can not deserialize instance of org.hello.tweetconsumer.Greeting out of START_ARRAY token
                                                                      at [Source: buffer(com.android.okhttp.internal.http.HttpConnection$ChunkedSource@a143f53).inputStream(); line: 1, column: 1]; nested exception is com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of org.hello.tweetconsumer.Greeting out of START_ARRAY token
                                                                      at [Source: buffer(com.android.okhttp.internal.http.HttpConnection$ChunkedSource@a143f53).inputStream(); line: 1, column: 1]
                                                                     org.springframework.http.converter.HttpMessageNotReadableException: Could not read JSON: Can not deserialize instance of org.hello.tweetconsumer.Greeting out of START_ARRAY token
                                                                      at [Source: buffer(com.android.okhttp.internal.http.HttpConnection$ChunkedSource@a143f53).inputStream(); line: 1, column: 1]; nested exception is com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of org.hello.tweetconsumer.Greeting out of START_ARRAY token
                                                                      at [Source: buffer(com.android.okhttp.internal.http.HttpConnection$ChunkedSource@a143f53).inputStream(); line: 1, column: 1]
                                                                         at org.springframework.http.converter.json.MappingJackson2HttpMessageConverter.readInternal(MappingJackson2HttpMessageConverter.java:126)
                                                                         at org.springframework.http.converter.AbstractHttpMessageConverter.read(AbstractHttpMessageConverter.java:147)
                                                                         at org.springframework.web.client.HttpMessageConverterExtractor.extractData(HttpMessageConverterExtractor.java:76)
                                                                         at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:484)
                                                                         at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:439)
                                                                         at org.springframework.web.client.RestTemplate.getForObject(RestTemplate.java:237)
                                                                         at org.hello.tweetconsumer.MainActivity$HttpRequestTask.doInBackground(MainActivity.java:90)
                                                                         at org.hello.tweetconsumer.MainActivity$HttpRequestTask.doInBackground(MainActivity.java:82)
                                                                         at android.os.AsyncTask$2.call(AsyncTask.java:295)
                                                                         at java.util.concurrent.FutureTask.run(FutureTask.java:237)
                                                                         at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234)
                                                                         at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
                                                                         at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
                                                                         at java.lang.Thread.run(Thread.java:818)
                                                                      Caused by: com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of org.hello.tweetconsumer.Greeting out of START_ARRAY token
                                                                      at [Source: buffer(com.android.okhttp.internal.http.HttpConnection$ChunkedSource@a143f53).inputStream(); line: 1, column: 1]
                                                                         at com.fasterxml.jackson.databind.DeserializationContext.mappingException(DeserializationContext.java:691)
                                                                         at com.fasterxml.jackson.databind.DeserializationContext.mappingException(DeserializationContext.java:685)
                                                                         at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromArray(BeanDeserializerBase.java:1215)
                                                                         at com.fasterxml.jackson.databind.deser.BeanDeserializer._deserializeOther(BeanDeserializer.java:151)
                                                                         at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:126)
                                                                         at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:2993)
                                                                         at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2158)
                                                                         at org.springframework.http.converter.json.MappingJackson2HttpMessageConverter.readInternal(MappingJackson2HttpMessageConverter.java:123)
                                                                            ... 13 more
07-29 06:50:02.664 2886-2886/org.hello.tweetconsumer D/AndroidRuntime: Shutting down VM


                                                                       --------- beginning of crash
07-29 06:50:02.665 2886-2886/org.hello.tweetconsumer E/AndroidRuntime: FATAL EXCEPTION: main
                                                                       Process: org.hello.tweetconsumer, PID: 2886
                                                                       java.lang.NullPointerException: Attempt to invoke virtual method 'long org.hello.tweetconsumer.Greeting.getProductId()' on a null object reference
                                                                           at org.hello.tweetconsumer.MainActivity$HttpRequestTask.onPostExecute(MainActivity.java:107)
                                                                           at org.hello.tweetconsumer.MainActivity$HttpRequestTask.onPostExecute(MainActivity.java:82)
                                                                           at android.os.AsyncTask.finish(AsyncTask.java:651)
                                                                           at android.os.AsyncTask.-wrap1(AsyncTask.java)
                                                                           at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:668)
                                                                           at android.os.Handler.dispatchMessage(Handler.java:102)
                                                                           at android.os.Looper.loop(Looper.java:148)
                                                                           at android.app.ActivityThread.main(ActivityThread.java:5417)
                                                                           at java.lang.reflect.Method.invoke(Native Method)
                                                                           at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
                                                                           at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

3 个答案:

答案 0 :(得分:0)

如果您的目的是将Iterable映射为问候语,那么您期待收集问候语而不是唯一问候语。

所以你必须替换它:

Greeting

由此:

Greeting[]

您的代码应该是这样的:

   private class HttpRequestTask extends AsyncTask<Void, Void, Greeting[]> {
    @Override
    protected Greeting[] doInBackground(Void... params) {
        try {
            final String url = "blabla";
            RestTemplate restTemplate = new RestTemplate();
            restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
            Greeting[]  greeting;
            greeting = restTemplate.getForObject(url, Greeting[].class);
            return greeting;
        } catch (Exception e) {
            Log.e("MainActivity", e.getMessage(), e);
        }

        return null;
    }

    @Override
    protected void onPostExecute(Greeting[] greeting) {
        TextView text1 = (TextView) findViewById(R.id.textView);
        TextView text2 = (TextView) findViewById(R.id.textView2);
        TextView text3 = (TextView) findViewById(R.id.textView3);
        TextView text4 = (TextView) findViewById(R.id.textView4);

        assert text1 != null;
        text1.setText((int) greeting[0].getProductId());
        assert text2 != null;
        text2.setText(greeting[0].getDescription());
        assert text3 != null;
        text3.setText(greeting[0].getName());
        assert text4 != null;
        text4.setText(greeting[0].getLocation());


    }

}

另外,尝试通过ResponseEntity更改服务的返回类型,如下所示:

 @RequestMapping(method = RequestMethod.GET , produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<Iterable<Product>> getAllProducts(){

    return new ResponseEntity<Iterable<Product>>(productService.listAllProducts(), HttpStatus.OK);
}

答案 1 :(得分:0)

检查完日志后,似乎API在异步任务中的postExecute上返回了null对象。

@Override
    protected void onPostExecute(Greeting greeting) {

     if(greeting != null) {

        TextView text1 = (TextView) findViewById(R.id.textView);
        TextView text2 = (TextView) findViewById(R.id.textView2);
        TextView text3 = (TextView) findViewById(R.id.textView3);
        TextView text4 = (TextView) findViewById(R.id.textView4);

        assert text1 != null;
        text1.setText((int) greeting.getProductId());
        assert text2 != null;
        text2.setText(greeting.getDescription());
        assert text3 != null;
        text3.setText(greeting.getName());
        assert text4 != null;
        text4.setText(greeting.getLocation());
       } else {
         // Show logs or Toast
     }

    }

关于JsonMappingException希望下面的链接可以帮助你:

JSON: JsonMappingException while try to deserialize object with null values

答案 2 :(得分:0)

我将问候语更改为问候语[],并将我的返回类型List<Product>改为Iterable<Product>,现在它的工作权限已全部