I want to develop android app which is connected to server which is developed using Spring,and they should communicate in JSON format.
But When I send request to server with JSON object and try to receive it,it is showing error
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)
let me show you code
in Android for sending data in json format:
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();
On server side to receive Json Object Code is:
@RequestMapping(value = "/vendorWithJSON",method = RequestMethod.POST,consumes="application/json")
@ResponseBody
public String addRestaurantWebView(JsonObject userDetails){
logger.debug ("DetailsIGot:"+userDetails.getAsString());
return "{\"ans\":\"true\"}";
}
i expect at server side in console it should print:
{"id":"1","password":"honey","username":"Yoyo"}
but it is showing errors as shown above .I am totally new in android and Spring so i dont know too much about @RequestMapping,@ResponseBody etc,can anybody please tell me what i should do ??
AFTER_EDIT: What if Response to be send is in ArrayList<SomeObject>
format,how to receive it in android.Let me show you code:
@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;
}
How to receive this in ArrayList format ?
You should create on server side a class that looks like this
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
}
And then do
@RequestMapping(value = "/vendorWithJSON",method = RequestMethod.POST,consumes="application/json")
@ResponseBody
public String addRestaurantWebView(@RequestBody UserDetails userDetails) //change this line
{
...
If you didn't set the automatic JSON mapper in Spring Framework (not needed in Boot, it is done automatically), then you need to either use Java configuration or XML configuration to add the JSON message converter bean.
If you add the automatic jSON mapper, you can also make your reply be a POJO rather than just a mere manual string (prone to errors!)
return "{\"ans\":\"true\"}";
Would be
public class DummyResponse {
private boolean ans;
public DummyResponse() {}
public DummyResponse(boolean ans) { this.ans = ans; }
//getter, setter
}
and
public DummyResponse addRestaurantWebView(@RequestBody UserDetails userDetails) {
...
return new DummyResponse(true);
}
EDIT: If you don't want to use any new libraries, it would be the following:
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
}
But if you get a library for JSON parsing (like GSON or Jackson, i'll use GSON) then it'd be the following:
while ((line = reader.readLine()) != null) {
Log.i("imIn","while");
builder.append(line);
}
DummyResponse dummyResponse = new Gson().fromJson(builder.toString(), DummyResponse.class);
But if you want to make this whole thing so much better, then you should use Retrofit library with 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
}