使用Jackson通过AJAX从Spring MVC控制器返回java.util.List

Tin*_*iny 9 java ajax json spring-mvc jackson

根据几天前发布的问题,我意识到这SimpleFormController不适合处理Ajax请求.因此,我正在将我的应用程序迁移到带注释的控制器.

我正在尝试java.util.List使用Spring MVC 3.0.2和Hibernate通过Ajax使用Jackson 1.9.8(其下载页面)从Oracle数据库返回,但我还没有在任何技术中使用JSON.我已经阅读了一些教程/文章但我无法理解如何返回这样复杂的数据结构并在Spring中使用JSON解析它们.我首先尝试学习类似JSON的概念.

基本上我正在尝试的是当从国家选择框中选择国家时,应该通过Ajax从数据库填充与该国家相对应的州.我不知道如何返回java.util.ListAjax响应,如何解析它并在Java代码中再次使用它.我只达到以下水平.

JS代码.

function getStates(countryId)
{
    $.ajax({
        datatype:"json",
        type: "POST",
        url: "/wagafashion/ajax/TempAjax.htm",
        data: "countryId=" + countryId,

        success: function(response)
        {
            $('#msg').html(response);
            $('#stateList').val('');
        },
        error: function(e)
        {
            alert('Error: ' + e);
        }
    });
}
Run Code Online (Sandbox Code Playgroud)

Spring控制器类中的方法,当onchange在国家/地区选择框的事件上发出Ajax请求时调用该方法.

@RequestMapping(method=RequestMethod.POST, value="ajax/TempAjax")
public @ResponseBody List<StateTable> getStateList(@ModelAttribute("tempBean") TempBean tempBean, BindingResult error, Map model, HttpServletRequest request, HttpServletResponse response)
{
    Session session=NewHibernateUtil.getSessionFactory().getCurrentSession();
    session.beginTransaction();
    List<StateTable>list=session.createQuery("from StateTable where country.countryId=:countryId order by stateId").setParameter("countryId", new BigDecimal(request.getParameter("countryId"))).list();

    session.flush();
    session.getTransaction().commit();
    return list;
}
Run Code Online (Sandbox Code Playgroud)

状态选择框我需要使用<c:forEach></c:forEach>EL循环填充Ajax响应返回的状态列表.

<form:select path="cmbState" class="validate[required] text-input tooltip" title="Mandatory select field.">
    <form:option value="">Select</form:option>

    <c:forEach items="${stateList}" var="row">
        <c:choose>
            <c:when test="${row.stateId==param['stateId'] and deselectCombo!=1}">
                <form:option value="${row.stateId}" selected="selected">${row.stateName}</form:option>
            </c:when>
            <c:otherwise>
                <form:option value="${row.stateId}">${row.stateName}</form:option>
            </c:otherwise>
        </c:choose>
    </c:forEach>
</form:select>

<font style="color: red"><form:errors path="stateId"/></font><br/>
Run Code Online (Sandbox Code Playgroud)

我只能成功地进行Ajax请求和响应.通过互联网找到的那些教程我无法理解.更确切地说,如何items在前一个<c:forEach><c:forEach>循环的属性中使用Ajax响应,例如items="${stateList}"

你能给我一些提示/想法如何返回数据列表并在前面的循环中使用它来填充状态选择框?你能告诉我一些从这里开始的事吗?

我正在使用NetBeans 6.9.1(而不是Eclipse).在一些关于Eclipse中Marvan项目的教程中,有人提到该pom.xml文件需要配置为包含<dependencies></dependencies>(Jackson依赖).pom.xml在我的NetBeans项目中没有这样的东西.是否需要在NetBeans中的某个xml文件中配置某个位置,例如此处提到的那个?

hyn*_*ess 13

您应该使用的策略是从jQuery进行AJAX调用,获取JSON响应并使用它从jQuery而不是java动态更新表单.我可以看到的JSP标记的唯一用途是在加载时呈现页面.以下是我将如何处理这个......

  1. 将控制器更改为使用GET而不是POST.首先,在REST中使用POST是不正确的(您只检索数据,而不是更改数据).但更重要的是,通过简单地将URL放入浏览器以查看JSON响应,您可以更轻松地测试控制器.使用@ResponseBody注释并在类路径中包含Jackson应该在这里产生一个JSON响应(除非你有一些Hibernate延迟加载问题).

  2. 验证控制器返回JSON后,更新jQuery成功处理程序以动态填充下拉列表.这应该相对容易.在浏览器中测试.

  3. 编写一个新的控制器来处理此表单提交.在此控制器中,只需包含一个返回列表并将其注释为的方法@ModelAttribute("stateList").这将使列表可用于<c:forEach>循环以在加载时呈现页面.您将拥有另一种方法来处理同一控制器中的实际表单提交.

另一件需要考虑的事情是通过将数据库代码放在自己的服务或存储库中来更好地分离关注点.在MVC架构中的控制器中进行数据访问是一种不好的做法.作为奖励,您不需要复制任何代码以在两个不同的控制器中加载列表.

另外,看看Spring的@Transactional声明式事务处理.这样您就不需要为事务处理编写任何代码.您也可以简单地注入SessionFactory而不是自己编写HibernateUtils.

希望有所帮助

编辑:在REST中,这里是映射到相应CRUD操作的HTTP方法.

  • POST - 创建
  • GET - 检索
  • PUT - 更新
  • 删除 - 删除