Reputation: 5654
I have a javascript array which i populate with elements the array structure is :
var citizens1 = [{"startLat":null,"startLng":null,"socialSecurityNumber":null}];
The array gets data however i need to push this data to the server for processing. The array holds 500 records. Instead of making 500 Web Service request to the server i convert the array data to JSON string and pass all the data to the server where i process all the records at once thus making one ajax call.
I am not sure if i am passing the data correctly to the server. I am experiencing errors. Under is my code:
Javascript
citizens1.push({startLat:marker[index].getPosition().lat(),startLng:marker[index].getPosition().lng(),socialSecurityNumber:global_citizens[index].socialSecurityNumber});
if(citizens1.length == 500){
console.log('500 records saved');
window.clearTimeout( timerHandle);
for(var i = 0; i < citizens1.length ; i++){
var myJsonString = JSON.stringify(citizens1);
//console.log(myJsonString);
//console.log(citizens1[i].lat +',' +citizens1[i].lng+','+citizens1[i].socialSecurityNumber);
$.ajax({
type:'POST',
url:'logMovement.htm',
contentType: "application/json; charset=utf-8",
async: false,
cache: false,
data:myJsonString,
dataType: 'json',
success:function(data){
if (data == false){
console.log('error occured in logging data');
}
}
});
}
citizens1 = [];
}
Controller
@RequestMapping(value="logMovement.htm", method={RequestMethod.POST},produces = "application/json; charset=utf-8")
public @ResponseBody Movement logMovement(@RequestBody Movement movement)throws Exception{
logger.info("About to log movement");
JSONObject jsonObj = JSONObject.fromObject(movement);
ObjectMapper mapper = new ObjectMapper();
List<Movement> move = mapper.readValue(jsonObj.toString(), new TypeReference<Movement>(){});
logger.info(move);
return null;
/*if((!lat.equals(null)) || (!(lat == null)) || (!(lat.length() == 0))){
double dLat = Double.parseDouble(lat);
double dLng = Double.parseDouble(lng);
int iSocialSecurityNumber = Integer.parseInt(socialSecurityNumber);
this.markerManager.logMovement(dLat, dLng, iSocialSecurityNumber);
}*/
}
Movement Class
public class Movement implements Serializable{
private List<Integer>socialSecurityNumber;
private List<Double> startLat;
private List<Double> startLng;
/**
* @param socialSecurityNumber
* @param startLat
* @param startLng
*/
public Movement(){}
public Movement(List<Integer> socialSecurityNumber, List<Double> startLat,
List<Double> startLng) {
super();
this.socialSecurityNumber = socialSecurityNumber;
this.startLat = startLat;
this.startLng = startLng;
}
//getters and setters
Sample of Json Data Posted to Server
I am seeing the first rows is 'null' i am not sure if this is causing the problem
[{"startLat":null,"startLng":null,"socialSecurityNumber":null},{"startLat":10.537749449700717,"startLng":-61.44420048947677,"socialSecurityNumber":198501012},{"startLat":10.537208514171011,"startLng":-61.443589321013235,"socialSecurityNumber":198501012},{"startLat":10.536667622323245,"startLng":-61.44297811322531,"socialSecurityNumber":198501012},{"startLat":10.536131483465244,"startLng":-61.442362603115384,"socialSecurityNumber":198501012},{"startLat":10.53566878133931,"startLng":-61.44168979108997,"socialSecurityNumber":198501012},{"startLat":10.535227295591238,"startLng":-61.441000943386825,"socialSecurityNumber":198501012},{"startLat":10.170058041417015,"startLng":-61.67893982108137,"socialSecurityNumber":194302025}
Error
I was looking at this SO question which dealt with the issue Required JSON parameter is not present in jQuery Datatables
org.springframework.http.converter.HttpMessageNotReadableException: Could not read JSON: Can not deserialize instance of com.crimetrack.business.Movement out of START_ARRAY token
org.springframework.http.converter.HttpMessageNotReadableException: Could not read JSON: Can not deserialize instance of com.crimetrack.business.Movement out of START_ARRAY token
at [Source: org.apache.catalina.connector.CoyoteInputStream@72f1db9d; line: 1, column: 1]; nested exception is org.codehaus.jackson.map.JsonMappingException: Can not deserialize instance of com.crimetrack.business.Movement out of START_ARRAY token
at [Source: org.apache.catalina.connector.CoyoteInputStream@72f1db9d; line: 1, column: 1]
at org.springframework.http.converter.json.MappingJacksonHttpMessageConverter.readInternal(MappingJacksonHttpMessageConverter.java:127)
at org.springframework.http.converter.AbstractHttpMessageConverter.read(AbstractHttpMessageConverter.java:153)
at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodArgumentResolver.readWithMessageConverters(AbstractMessageConverterMethodArgumentResolver.java:120)
at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodArgumentResolver.readWithMessageConverters(AbstractMessageConverterMethodArgumentResolver.java:91)
at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.resolveArgument(RequestResponseBodyMethodProcessor.java:71)
at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:75)
at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:156)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:117)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:96)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:617)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:578)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:923)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:852)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:882)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:789)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:647)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1008)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Caused by: org.codehaus.jackson.map.JsonMappingException: Can not deserialize instance of com.crimetrack.business.Movement out of START_ARRAY token
at [Source: org.apache.catalina.connector.CoyoteInputStream@72f1db9d; line: 1, column: 1]
at org.codehaus.jackson.map.JsonMappingException.from(JsonMappingException.java:159)
at org.codehaus.jackson.map.deser.StdDeserializationContext.mappingException(StdDeserializationContext.java:131)
at org.codehaus.jackson.map.deser.BeanDeserializer.deserializeUsingCreator(BeanDeserializer.java:397)
at org.codehaus.jackson.map.deser.BeanDeserializer.deserialize(BeanDeserializer.java:296)
at org.codehaus.jackson.map.ObjectMapper._readMapAndClose(ObjectMapper.java:1282)
at org.codehaus.jackson.map.ObjectMapper.readValue(ObjectMapper.java:941)
at org.springframework.http.converter.json.MappingJacksonHttpMessageConverter.readInternal(MappingJacksonHttpMessageConverter.java:124)
... 33 more
Upvotes: 0
Views: 4583
Reputation: 5654
I made some adjustments to the movement class and the controller and this provided me with the solution. Under is the code for those whom may be interested in solving this error:
Movement.java
It is very important to have the default constructor. If this is not there json will throw errors related to application/json; charset=utf-8 not supported http 415 unsupported media.
public class Movement implements Serializable{
private int socialSecurityNumber;
private double startLat;
private double startLng;
/**
* @param socialSecurityNumber
* @param startLat
* @param startLng
*/
public Movement(){}
/**
* @param socialSecurityNumber
* @param startLat
* @param startLng
*/
public Movement(int socialSecurityNumber, double startLat, double startLng) {
super();
this.socialSecurityNumber = socialSecurityNumber;
this.startLat = startLat;
this.startLng = startLng;
}
//getters and setters
Controller
Since its an array of data it is important to define the @RequestBody
to use a List. Also declaring a JSONArray is important to hold the list. Once that have been done you can 'get' the data based on its type. Under is the code.
@RequestMapping(value="logMovement.htm", method = {RequestMethod.POST},consumes = "application/json")
public @ResponseBody Movement logMovement(@RequestBody List<Movement> movement)throws Exception{
logger.info("About to log movement");
JSONArray nameArray =(JSONArray) JSONSerializer.toJSON(movement);
System.out.println(nameArray.size());
for(Object js : nameArray){
JSONObject json = (JSONObject)js;
//System.out.println(json.get("socialSecurityNumber"));
if((!json.get("startLat").equals(null))){
this.markerManager.logMovement(json.getDouble("startLat"),json.getDouble("startLng"), json.getInt("socialSecurityNumber"));
}
}
return null;
}
Upvotes: 0
Reputation: 157
you can write response in the controller like this
hope this "ll be helpful
//get "hie" string from the service class, String is in JSON format
String hie = svc.getHierarchysvc();
response.setContentType("application/json");
PrintWriter out = response.getWriter();
out.write(hie);
Upvotes: 0
Reputation: 20063
Your JSON is invalid, the values on the left hand side of the colon need to be Strings.
[
{
"lat": null,
"lng": null,
"socialSecurityNumber": null
}
]
Also, you appear to be using the wrong annotation, @RequestBody
is used to parse the contents of the JSON rather than @RequestParam
which is used to get variables from a paramter like
?var=1&newvar=2
Also, in your javascript, change data:{'myData':myJsonString }
to just data:myJsonString,
You should make a dumb object to populate, check out this tutorial at the bottom of the page where they populate a dumb Person object hmkcode.com/spring-mvc-json-json-to-java
Upvotes: 2