0

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
1
  • Declare the parameter in the controller as a String instead of a JSON. Commented Oct 14, 2013 at 14:54

3 Answers 3

2

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

Sign up to request clarification or add additional context in comments.

8 Comments

This should be changed where in the ajax request ? what about the controller should changes be made there?
The controller looks ok although I'd have expected it to be some dumb object you were populating rather than net.sf.json.JSONObject.
if i populate an object how do i assign the data to that object?
This should be part of Springs JSON translation in 3.2.
Could you ask the new errors as a different question, just so it's easier to follow and you'd get more response from other SO users.
|
0

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);

Comments

0

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;    

     }   

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.