【问题标题】:Android as a Client, Server using Spring annotation,communication in JSON format,error while receiving in serverAndroid 作为客户端,服务器使用 Spring 注解,以 JSON 格式通信,服务器接收时出错
【发布时间】:2015-07-21 15:05:48
【问题描述】:

我想开发一个连接到使用Spring开发的服务器的android应用程序,它们应该以JSON格式进行通信。

但是当我使用 JSON 对象向服务器发送请求并尝试接收它时,它显示错误

java.lang.UnsupportedOperationException: JsonObject
at com.google.gson.JsonElement.getAsString(JsonElement.java:191)
at org.magnum.dataup.VendorController.addRestaurantWebView(VendorController.java:79)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:215)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:749)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:689)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:83)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:938)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:870)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:961)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:863)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:646)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:837)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.springframework.boot.actuate.trace.WebRequestTraceFilter.doFilter(WebRequestTraceFilter.java:115)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.springframework.boot.actuate.autoconfigure.EndpointWebMvcAutoConfiguration$ApplicationContextFilterConfiguration$1.doFilterInternal(EndpointWebMvcAutoConfiguration.java:137)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:108)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:77)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:108)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.springframework.boot.actuate.autoconfigure.MetricFilterAutoConfiguration$MetricsFilter.doFilterInternal(MetricFilterAutoConfiguration.java:85)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:108)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:501)
at org.apache.catalina.valves.RemoteIpValve.invoke(RemoteIpValve.java:683)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1040)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:607)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1721)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1679)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)

让我给你看代码

在Android中以json格式发送数据:

StringBuilder builder = new StringBuilder();
        try {
            Log.i("imIn","PostMethod");
            //Looper.prepare();
            HttpClient client = new DefaultHttpClient();
            HttpConnectionParams.setConnectionTimeout(client.getParams(),10000);
            HttpResponse response;

          JSONObject userDetails = new JSONObject();
            userDetails.put("username","Yoyo");
            userDetails.put("password","honey");
            userDetails.put("id","1");
            HttpPost poost = new HttpPost("http://10.0.3.2:8080/vendorWithJSON");


            Log.i("imIn","Posting:"+userDetails.toString());

            StringEntity stringEntity = new StringEntity(userDetails.toString());
            stringEntity.setContentType(new BasicHeader(HTTP.CONTENT_TYPE,"application/JSON"));
            poost.setEntity(stringEntity);
            response = client.execute(poost);



            StatusLine statusLine = response.getStatusLine();
            int statusCode = statusLine.getStatusCode();
            if (statusCode == 200) {
                Log.i("imIn","StatusCode200");
                HttpEntity entity = response.getEntity();
                InputStream content = entity.getContent();
                BufferedReader reader = new BufferedReader(new InputStreamReader(content));
                String line;
                while ((line = reader.readLine()) != null) {
                    Log.i("imIn","while");
                    builder.append(line);
                }

            } else {
                //Log.e(ParseJSON.class.toString(), "Failed to download file");
                Log.e("", "Failed to download file");

            }


        } catch (Exception e){
            e.printStackTrace();
        }
        //Looper.loop();
        return builder.toString();

在服务器端接收 Json 对象代码是:

 @RequestMapping(value = "/vendorWithJSON",method = RequestMethod.POST,consumes="application/json")
        @ResponseBody
        public String addRestaurantWebView(JsonObject userDetails){
            logger.debug ("DetailsIGot:"+userDetails.getAsString());
            return "{\"ans\":\"true\"}";

        }

我希望在控制台的服务器端它应该打印:

{"id":"1","password":"honey","username":"Yoyo"}

但它显示如上所示的错误。我是 android 和 Spring 的新手,所以我对 @RequestMapping、@ResponseBody 等不太了解,谁能告诉我应该怎么做??

AFTER_EDIT:如果要发送的响应是ArrayList<SomeObject> 格式,如何在 android 中接收它。让我给你看代码:

    @RequestMapping(value = "/receiveall",method = RequestMethod.GET)
    public  @ResponseBody ArrayList<TotalProducts> watchall(@RequestBody                   String vendorDetails) throws UnknownHostException {
    Logger logger = LoggerFactory.getLogger("Vendor");
    ArrayList<TotalProducts> totproducts=new ArrayList<TotalProducts>();

    Mongo mongo = null;
    DB db=null;
    DBCollection table=null;
    String userName="";
    mongo = new Mongo("localhost", 27017);

    db = mongo.getDB("Vendor_Database");
    table = db.getCollection("Total_Products");

    DBCursor cursor = table.find();
    BasicDBObject obj = null;
    while (cursor.hasNext()) {
        obj = (BasicDBObject) cursor.next();

        TotalProducts product=new TotalProducts();
        product.setBrandName(obj.getString("productname"));
        product.setBrandName(obj.getString("brandname"));
        product.setCategory(obj.getString("category"));
        product.setCollection_type(obj.getString("collection_type"));
        product.setMrp(Integer.parseInt(obj.getString("mrp")));
        product.setDiscount(Integer.parseInt(obj.getString("discount")));

        totproducts.add(product);
    }
        return totproducts;

} 

如何以 ArrayList 格式接收这个?

【问题讨论】:

  • 使用toString 而不是getAsString
  • @EpicPandaForce no..还是同样的错误
  • 哦,我仔细研究了一下,现在发现问题了
  • 我很困惑你是使用Jackson2HttpMessageConverter还是Gson的东西
  • @EpicPandaForce 我正在使用 gson,嘿,但是thanx,我的问题通过制作解决了:@RequestMapping(value = "/vendorWithJSON",method = RequestMethod.POST,consumes="application/json") public @ResponseBody String addRestaurantWebView(@RequestBody String userDetails){}

标签: android spring-annotations jsonobject


【解决方案1】:

你应该在服务器端创建一个像这样的类

public class UserDetails {
    private String id;
    private String password;
    private String username;

    public String getId() { return id; }
    public void setId(String id) { this.id = id; }
    ... // other two getter setter
}

然后做

 @RequestMapping(value = "/vendorWithJSON",method = RequestMethod.POST,consumes="application/json")
    @ResponseBody
    public String addRestaurantWebView(@RequestBody UserDetails userDetails) //change this line
    {
    ...

如果您没有在 Spring Framework 中设置自动 JSON 映射器(在 Boot 中不需要,它会自动完成),那么您需要使用 Java configurationXML configuration 来添加 JSON 消息转换器 bean。

如果您添加自动 jSON 映射器,您还可以让您的回复成为 POJO 而不仅仅是手动字符串(容易出错!)

        return "{\"ans\":\"true\"}";

public class DummyResponse {
     private boolean ans;

     public DummyResponse() {}

     public DummyResponse(boolean ans) { this.ans = ans; }

     //getter, setter
}

public DummyResponse addRestaurantWebView(@RequestBody UserDetails userDetails) {
     ...
     return new DummyResponse(true);
}

编辑:如果您不想使用任何新库,则如下:

        if (statusCode == 200) {
            Log.i("imIn","StatusCode200");
            HttpEntity entity = response.getEntity();
            InputStream content = entity.getContent();
            BufferedReader reader = new BufferedReader(new InputStreamReader(content));
            String line;
            while ((line = reader.readLine()) != null) {
                Log.i("imIn","while");
                builder.append(line);
            }
            JSONObject jsonObject = new JSONObject(builder.toString());
            //this is JSON
       }

但如果你有一个用于 JSON 解析的库(如 GSON 或 Jackson,我将使用 GSON),那么它会是以下内容:

            while ((line = reader.readLine()) != null) {
                Log.i("imIn","while");
                builder.append(line);
            }
            DummyResponse dummyResponse = new Gson().fromJson(builder.toString(), DummyResponse.class);

但是如果你想让整个事情变得更好,那么你应该使用带有 GsonRetrofit 库:

public interface RetrofitService {
    @POST("/vendorWithJSON")
    public DummyResponse postVendorWithJson(@Body UserDetails userDetails);
}

  public class UserDetails {
      private String username;
      private String password;
      private String id;

      //getters, setters
  }

        UserDetails userDetails = new UserDetails();
        userDetails.setUsername("Yoyo");
        userDetails.setPassword("honey");
        userDetails.setId("1");

        RestAdapter restAdapter = new RestAdapter.Builder()
            .setEndpoint("http://10.0.3.2:8080")
            .setConverter(new GsonConverter(new Gson()))
            .build();
        RetrofitService service = restAdapter.create(RetrofitService.class);
        try {
            DummyResponse dummyResponse = service.postVendorWithJson(userDetails);
            return dummyResponse;
        } catch(RetrofitError error) {
            //handle if unsuccessful
        }

【讨论】:

  • 嘿,谢谢,我的问题解决了:@RequestMapping(value = "/vendorWithJSON",method = RequestMethod.POST,consumes="application/json") public @ResponseBody String addRestaurantWebView(@RequestBody String userDetails){}
  • **但是我也尝试了这段代码,它真的很有帮助**你能告诉我如何在 Android 中接收 java 对象(这里是 DummyResponse)吗?谢谢。
  • 回答了问题
  • 嗨,我尝试使用“Retrofit”..它工作得很好。
  • 很高兴听到这个消息! :)
【解决方案2】:

您必须使用 gson.jar (import com.google.gson.JsonObject) 中提供的 JsonObject 而不是 JSONObject

you can find jar file here

【讨论】:

  • 嘿thanx,目前我在android中使用JSONObject,在服务器端使用JsonObject,但我会试试你说的!!!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-07-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-05
  • 2013-12-14
  • 1970-01-01
相关资源
最近更新 更多