Android 作为客户端,服务器使用 Spring 注释,以 JSON 格式通信,在服务器接收时出错
Android as a Client, Server using Spring annotation,communication in JSON format,error while receiving in server
我想开发 android 应用程序,该应用程序连接到使用 Spring 开发的服务器,它们应该以 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.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)
让我给你看代码
in 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.Let 中接收它,我告诉你代码:
@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 格式接收这个?
你应该在服务器端创建一个看起来像这样的class
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 configuration or XML 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);
但是如果你想让整个事情变得更好,那么你应该使用 Retrofit 库和 Gson:
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
}
您必须使用 gson.jar(导入 com.google.gson.JsonObject)中可用的 JsonObject 而不是 JSONObject
我想开发 android 应用程序,该应用程序连接到使用 Spring 开发的服务器,它们应该以 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.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)
让我给你看代码
in 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.Let 中接收它,我告诉你代码:
@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 格式接收这个?
你应该在服务器端创建一个看起来像这样的class
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 configuration or XML 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);
但是如果你想让整个事情变得更好,那么你应该使用 Retrofit 库和 Gson:
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
}
您必须使用 gson.jar(导入 com.google.gson.JsonObject)中可用的 JsonObject 而不是 JSONObject