1

我正在使用 Spring 框架版本 3.0.2 和 Hibernate (NetBeans 6.9.1) 处理 Web 应用程序。后来我知道有一个错误导致上传多个文件时出现问题,正如我之前的一个问题中提到的那样。

我已经完成了获得解决方案的努力,但未能成功。因此,我将 Spring 版本升级到3.2.0

在较早的版本 (3.0.2) 中,AJAX 在Jackson 1.9.8(其下载页面)中运行良好,但在较新的版本 (3.2.0) 中,一切正常,但 AJAX 调用在 JavaScript 代码中的任何地方都会提示错误。

有一种场景,当在国家选择框中选择一个国家时,从 Spring 控制器中连同 DAO 一起检索相应的状态列表。在 Spring 控制器中映射到 URL 的方法如下,

@RequestMapping(value="ajax/GetStateList", method=RequestMethod.GET)
public @ResponseBody List<Object[]> getStateSelectBox(HttpServletRequest request)
{
    return cityService.getStateSelectBox(request.getParameter("countryId"));
}   

在国家选择框中选择国家时调用该方法。该getStateSelectBox()方法在 DAO 类之一中定义如下,

@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;
   }
}

foreach循环只是为了演示,它显示了所有状态及其 id,这些状态对应于countryIdAJAX 请求提供的但List不返回给 JSP。

用于发送此 AJAX 请求的 JavaScript 代码会发出错误警报。JSON映射似乎存在一些问题。同样的事情也适用于早期版本的 Spring 框架 (3.0.2)。我不确定为什么这会导致更高版本的 Spring 3.2.0 出现问题。Spring 3.2.0 版有什么我可能会丢失的吗?


如果您需要查看 JavaScript 代码,实现此目的的完整 JavaScript 代码如下所示。

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

可以肯定的是,Jackson 库位于类路径中,我在服务器端没有收到任何错误或异常。AJAX 请求成功,它通过 Spring 进入 DAO,并List<Object[]>从数据库中检索类型列表,但它不是 JSON 对 JSP 的响应(可以/应该映射到 JavaScript 数组)。据推测,JSON 映射似乎缺少某些东西,但早期版本的 Spring 并非如此。


编辑:

我尝试List<Object[]>在 3.0.2 和 3.2.0 这两个框架中进行解析,例如

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){}

该文件temp.json包含以下字符串。

[[21,"Gujarat"],[22,"Maharashtra"],[23,"Kerala"],[24,"New Delhi"]]

在这两种情况下(使用两个框架)。因此,在这两种情况下,JSON 响应似乎应该是相同的。

temp.json文件也可以按如下方式反序列化。

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

}

它工作正常,foreach循环遍历Listof type List<Object[]>。因此,问题可能是由 Spring 框架本身引起的。还需要什么,我不确定。为什么杰克逊没有映射它?

4

2 回答 2

2

我在 Spring 论坛上有同样的帖子。最终对我有用的问题的答复中的解决方案需要dispatcher-servlet.xml按如下方式配置文件。

<mvc:annotation-driven content-negotiation-manager="contentNegotiationManager" />

<bean id="contentNegotiationManager" class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
    <property name="favorPathExtension" value="false" />
    <property name="favorParameter" value="false" />
    <property name="ignoreAcceptHeader" value="false" />
    <property name="mediaTypes" >
        <value>
            atom=application/atom+xml
            html=text/html
            json=application/json
            *=*/*
        </value>
    </property>
</bean>

这导致 JSON 与 Jackson 1.9.8和 Spring 3.2.0一起工作。这归功于对该问题的所有答复


我的整个dispatcher-servlet.xml文件现在如下所示。

<?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-2.5.xsd
       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
       http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
       http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.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 content-negotiation-manager="contentNegotiationManager" />
    <bean id="contentNegotiationManager" class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
        <property name="favorPathExtension" value="false" />
        <property name="favorParameter" value="false" />
        <property name="ignoreAcceptHeader" value="false" />
        <property name="mediaTypes" >
            <value>
                atom=application/atom+xml
                html=text/html
                json=application/json
                *=*/*
            </value>
        </property>
    </bean>


    <bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" />
    <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"/>
    <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>
于 2012-12-31T14:30:14.370 回答
1

我正在使用 Spring 3.1.3,我发现 Jackson 映射尝试在响应中创建根对象。这与 Jackson2 映射器有关。我还没有尝试过使用较旧的 Jackson 映射器。如果您还升级了 Jackson,您可能会遇到同样的问题。

过去,对象数组会被映射为

[{name:'name1',id:4},{name:'name2',id:6}]

现在我发现他们为对象提供了一个自动生成的对象名称,所以它返回类似于

{ objectArray: [{name:'name1',id:4},{name:'name2',id:6}]}

所以你需要引用response.objectArray[0]而不是能够直接引用response[0]

无论如何,JSON 响应的格式可能有所改变。您应该查看新响应并查看 javascript 中需要发生哪些更改以使其映射新结构。

于 2012-12-27T19:55:12.113 回答