简体   繁体   English

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

[英]Returning a java.util.List from a Spring MVC controller via AJAX using Jackson

Based on my question posted a few days ago, I realized that SimpleFormController is inappropriate for handling Ajax requests. 根据几天前发布的问题 ,我意识到SimpleFormController不适合处理Ajax请求。 Therefore, I'm migrating my application towards annotated controllers. 因此,我正在将我的应用程序迁移到带注释的控制器。

I'm trying to return a java.util.List from Oracle database using Spring MVC 3.0.2 with Hibernate via Ajax using Jackson 1.9.8 (its download page ) but I haven't yet worked with JSON in any technology. 我正在尝试使用Spring MVC 3.0.2和Hibernate通过Ajax使用Jackson 1.9.8 (其下载页面 )从Oracle数据库返回java.util.List ,但我还没有在任何技术中使用JSON。 I have read up some tutorials/articles but I couldn't get the idea of how to return such complex data structures and parse them using JSON in Spring. 我已经阅读了一些教程/文章,但我无法理解如何返回这样复杂的数据结构并在Spring中使用JSON解析它们。 I'm trying to learn JSON-like concepts first. 我首先尝试学习类似JSON的概念。

What basically I'm trying is when a country is selected from a country select box, the states corresponding to that country should be populated from the database via Ajax. 基本上我正在尝试的是当从国家选择框中选择国家时,应该通过Ajax从数据库填充与该国家相对应的州。 I don't have precise idea about how to return a java.util.List over an Ajax response, how to parse it and again use it in Java code. 我不知道如何通过Ajax响应返回java.util.List ,如何解析它并在Java代码中再次使用它。 I'm only upto the following level. 我只达到以下水平。

JS code. 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);
        }
    });
}

The method in the Spring controller class which is invoked when the Ajax request is made on the onchange event of the country select box. 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;
}

The state select box I need to populate with the list of states returned by the Ajax response using a <c:forEach></c:forEach> loop of EL. 状态选择框我需要使用EL的<c:forEach></c:forEach>循环填充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/>

I could only make Ajax request and response successfully. 我只能成功地进行Ajax请求和响应。 Nothing more I could understand from those tutorials found over the internet. 通过互联网找到的那些教程我无法理解。 More precisely, how can I use the Ajax response in the items attribute of the preceding <c:forEach><c:forEach> loop such as items="${stateList}" ? 更确切地说,如何在前面的<c:forEach><c:forEach>循环的items属性中使用Ajax响应,例如items="${stateList}"

Could you give me some hint/idea how can I return a list of data and use it in the preceding loop to populate the state select box? 你能给我一些提示/想法如何返回数据列表并在前面的循环中使用它来填充状态选择框? Could you please lead me some steps ahead from here? 你能告诉我一些从这里开始的事吗?

I'm using NetBeans 6.9.1 (not Eclipse). 我正在使用NetBeans 6.9.1(而不是Eclipse)。 In some tutorials about Marvan projects in Eclipse, it was mentioned that the pom.xml file is required to configure to include <dependencies></dependencies> (Jackson dependency). 在一些关于Eclipse中Marvan项目的教程中,提到了pom.xml文件需要配置为包含<dependencies></dependencies> (Jackson依赖)。 There is no such thing like pom.xml in my project in NetBeans. 在我的NetBeans项目中没有像pom.xml这样的东西。 Is it required to configure somewhere in some xml file in NetBeans such as the one mentioned here ? 是否需要在NetBeans中的某个xml文件中配置某个位置,例如此处提到的那个?

The strategy you should use is to make the AJAX call from jQuery, take the JSON response and use it to update the form dynamically from jQuery not java. 您应该使用的策略是从jQuery进行AJAX调用,获取JSON响应并使用它从jQuery而不是java动态更新表单。 The only use I can see for the JSP tags would be to render the page when it loads. 我可以看到的JSP标记的唯一用途是在加载时呈现页面。 Here is how I would approach this... 以下是我将如何处理这个......

  1. Change your controller to use a GET instead of a POST. 将控制器更改为使用GET而不是POST。 For one, it is incorrect in REST to use a POST here (you are only retrieving data, not altering it). 首先,在REST中使用POST是不正确的(您只检索数据,而不是更改数据)。 But, more importantly, it will make it easier for you to test the controller by simply putting the URL into a browser to see the JSON response. 但更重要的是,通过简单地将URL放入浏览器以查看JSON响应,您可以更轻松地测试控制器。 Using the @ResponseBody annotation and including Jackson on the classpath should produce a JSON response here (unless you have some Hibernate lazy loading issues). 使用@ResponseBody注释并在类路径中包含Jackson应该在这里产生一个JSON响应(除非你有一些Hibernate延迟加载问题)。

  2. Once you verify the controller is returning JSON, update your jQuery success handler to dynamically populate the dropdown. 验证控制器返回JSON后,更新jQuery成功处理程序以动态填充下拉列表。 This should be relatively easy. 这应该相对容易。 Test this in the browser. 在浏览器中测试。

  3. Write a new controller to handle this form submission. 编写一个新的控制器来处理此表单提交。 In this controller, just include a method to return the list and annotate it as @ModelAttribute("stateList") . 在此控制器中,只需包含一个返回列表的方法,并将其注释为@ModelAttribute("stateList") This will make the list available for use in your <c:forEach> loop to render the page on load. 这将使列表可用于<c:forEach>循环以在加载时呈现页面。 You will have another method that will handle the actual form submission in the same controller. 您将拥有另一种方法来处理同一控制器中的实际表单提交。

Another thing to consider is to have better separation of concerns by putting the database code in its own service or repository. 另一件需要考虑的事情是通过将数据库代码放在自己的服务或存储库中来更好地分离关注点。 It's a bad practice to do data access in a controller in an MVC architecture. 在MVC架构中的控制器中进行数据访问是一种不好的做法。 As a bonus, you won't need to duplicate any code to load the list in two different controllers. 作为奖励,您不需要复制任何代码以在两个不同的控制器中加载列表。

Also, look into Spring's @Transactional declarative transaction handling. 另外,查看Spring的@Transactional声明式事务处理。 That way you won't need to write any code for transaction handling. 这样您就不需要为事务处理编写任何代码。 You can also simply inject the SessionFactory instead of writing your own HibernateUtils . 您也可以简单地注入SessionFactory而不是编写自己的HibernateUtils

Hope that helps 希望有所帮助

Edit : In REST, here are HTTP methods mapped to their corresponding CRUD actions. 编辑:在REST中,这里是映射到相应CRUD操作的HTTP方法。

  • POST - Create POST - 创建
  • GET - Retrieve GET - 检索
  • PUT - Update PUT - 更新
  • DELETE - Delete 删除 - 删除

you should try to your option list in ajax response instead of json like below one 你应该尝试在ajax响应中的选项列表而不是像下面的json

<option value="1">Mumbai</option>
<option value="2">Delhi</option>
<option value="3">Kerala</option>
<option value="4">Rajasthan</option>

and then your should add it to your select box liek below one 然后你应该把它添加到你的选择框下面

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

    success: function(response)
    {
        $('#stateList').html(response);
    },
    error: function(e)
    {
        alert('Error: ' + e);
    }
  });
}

or you can create json on serverside like below one 或者您可以在服务器端创建json,如下所示

[{"key":1, "value": "Mumbai"}, {"key":2, "value":"Delhi"}....]

and in javascript code 并在JavaScript代码中

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

    success: function(response)
    {
         if(response !=''){
              jQuery("#stateList").html("");
              jQuery.each(response, function(index,item) {
                jQuery("#stateList").append(jQuery("<option />")
                .attr("value",item.value)
                .text(item.key)); 
            });
         }

    },
    error: function(e)
    {
        alert('Error: ' + e);
    }
  });
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 使用Spring-data在Java.util.List中插入$ currentDate - Insert $currentDate in java.util.List using Spring-data 在 Web 服务中返回 java.util.List - returning a java.util.List in a Web Service 使用 java.util.List 时如何解决 jackson 反序列化错误? - How can I resolve jackson deserialization error while using java.util.List? 使用BerkeleyDB替换java.util.List - using BerkeleyDB to replace java.util.List 将 CustomPropertyComparator 与 java.util.List 结合使用 - Using CustomPropertyComparator with java.util.List 使用JRuby中的java.util.List - Working with java.util.List from JRuby spring boot - 如何在HTTP控制器处理程序中避免“无法实例化[java.util.List]:指定的类是一个接口”? - spring boot - how to avoid “Failed to instantiate [java.util.List]: Specified class is an interface” in HTTP controller handler? spring MVC3错误无法实例化bean类[java.util.List]:指定的类是偶尔的接口 - spring MVC3 errors Could not instantiate bean class [java.util.List]: Specified class is an interface Occasional 如何使用Jackson序列化为java.util.List和java.util.Map - How to serialize to java.util.List and java.util.Map with Jackson 通过JNI查找java.util.list的添加方法 - Find add method of java.util.list via JNI
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM