I was working with a web application using the Spring framework version 3.0.2 along with Hibernate (NetBeans 6.9.1). Later I came to know that there was one of bugs that was causing problems in uploading multiple files. Therefore, I upgraded the Spring version to (3.2.0).
With the earlier version 3.0.2, AJAX was working fine with Jackson 1.9.8 (its download page) but with the later version (3.2.0), everything works fine but AJAX calls alert an error everywhere in the JavaScript code.
Google chrome shows this error
There is a simple scenario at one place when one of the countries is selected in the country select box, the corresponding state list is retrieved from the Spring controller along with DAO. The method which is mapped with a URL in the Spring controller is as follows,Failed to load resource: the server responded with a status of 406 (Not Acceptable)
This method is invoked when a country is selected in the country select box. The getStateSelectBox() method is defined in one of DAO classes as follows,Code:@RequestMapping(value="ajax/GetStateList", method=RequestMethod.GET) public @ResponseBody List<Object[]> getStateSelectBox(HttpServletRequest request) { return cityService.getStateSelectBox(request.getParameter("countryId")); }
The foreach loop is just for the sake of demonstration, it displays all the states along with their id that correspond to the countryId supplied by the AJAX request but the List is not returned to JSP.Code:@Service @Transactional(readOnly = true, propagation=Propagation.REQUIRES_NEW) public final class CityDAO implements CityService { private SessionFactory sessionFactory; public void setSessionFactory(SessionFactory sessionFactory) { this.sessionFactory = sessionFactory; } @SuppressWarnings("unchecked") public List<Object[]> getStateSelectBox(String id) { List<Object[]> list = sessionFactory.getCurrentSession() .createQuery("select s.stateId, s.stateName from StateTable s where countryId.countryId=:id order by s.stateId") .setParameter("id", Long.parseLong(id)).list(); for(Object[]o:list) { System.out.println(o[0]+" : "+o[1]); } return list; } }
The JavaScript code used to send this AJAX request alerts an error. It appears that there are some problems with JSON mapping. The same thing was working with the earlier version of the Spring framework (3.0.2). I'm not sure why does this cause problems with the higher version of Spring which is 3.2.0. Is there anything with the Spring version 3.2.0 which I might be missing?
If you needed to see the JavaScript code, the full JavaScript code to achieve this would be as follows - jQuery library 1.6
To be sure, the Jackson library is on the classpath and I'm not getting any error or exception on the server side. The AJAX request succeeds and it goes to the DAO via Spring and the list of type List<Object[]> is retrieved from the database but it is not a response of JSON to JSP (which could/should be mapped to a JavaScript array). presumably, it appears that there is something missing with JSON mapping which was however not the case with the earlier version of Spring.Code:function getStates(countryId) { if(countryId==""||countryId==null||countryId==undefined||isNaN(countryId)) { var str="<select id='cmbStates' name='cmbStates' onchange='errorMessage(this.value);' class='validate[required] text-input'><option value=''>Select</option></select>"; $('#stateList').html(str); alert("Please select an appropriate option."); return; } var div=document.createElement("div"); div.id="temp"; document.body.appendChild(div); $.ajax({ datatype:"json", type: "GET", contentType: "application/json", url: "/wagafashion/ajax/GetStateList.htm", data: "countryId=" + countryId+"&t="+new Date().getTime(), success: function(response) { if(typeof response==='object'&&response instanceof Array) { var str="<select id='cmbState' name='cmbState' onchange='errorMessage(this.value);' class='validate[required] text-input'><option value=''>Select</option>"; var l=response.length; for(var i=0;i<l;i++) { str+="<option value='"+response[i][0]+"'>"+$('#temp').text(response[i][1]).html()+"</option>"; } str+="</select>"; $('#stateList').html(str); // select box is written to #stateList div $('#temp').remove(); } }, error: function(e) { alert('Error: ' + e); } }); }
I have tried to parse List<Object[]> in both of the frameworks, 3.0.2 and 3.2.0 such as
The file temp.json contains the following string.Code:List<Object[]> list = cityService.getStateSelectBox(request.getParameter("countryId")); ObjectMapper objectMapper=new ObjectMapper(); try { objectMapper.writeValue(new File("E:/Project/SpringHibernet/wagafashionLatest/temp.json"), list); } catch (IOException ex){}
In both the cases (with both frameworks). So, it appears that the JSON response should be same in both the cases.[[21,"Gujarat"],[22,"Maharashtra"],[23,"Kerala"],[24,"New Delhi"]]
The temp.json file can also be deserialized as follows.
It works fine and the foreach loop iterates over the List of type List<Object[]>. So, the problem might be caused by the Spring framework itself. What else is required, I'm not sure. Why is it not mapped by Jackson? Is there any configuration setting that I may be missing?Code:try { ObjectMapper mapper=new ObjectMapper(); List<Object[]> list = mapper.readValue(new File("E:/Project/SpringHibernet/wagafashionLatest/temp.json"), new TypeReference<List<Object[]>>() {}); for(Object[]o:list) { System.out.println(o[0]+" : "+o[1]); } } catch (IOException ex) { }
The following is the entire dispatcher-servlet.xml file.
Code:<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> <context:component-scan base-package="controller" /> <context:component-scan base-package="validatorbeans" /> <mvc:annotation-driven /> <bean id="jacksonMessageConverter" class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"/> <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"> <property name="messageConverters"> <list> <ref bean="jacksonMessageConverter"/> </list> </property> <property name="requireSession" value="false"/> </bean> I have tried to add the above portion but to no avail. <bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" /> <bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"> <property name="mappings"> <props> <prop key="index.htm">indexController</prop> </props> </property> </bean> <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver" p:prefix="/WEB-INF/jsp/" p:suffix=".jsp" /> <bean name="indexController" class="org.springframework.web.servlet.mvc.ParameterizableViewController" p:viewName="index" /> </beans>


Reply With Quote
