如何从 Spring MVC 控制器返回对象以响应 AJAX 请求?

Posted

技术标签:

【中文标题】如何从 Spring MVC 控制器返回对象以响应 AJAX 请求?【英文标题】:How to return an object from a Spring MVC controller in response to AJAX request? 【发布时间】:2014-04-24 11:06:27 【问题描述】:

我必须从控制器返回员工列表以响应 jQuery AJAX 请求。我该怎么做呢?

我的控制器:

@RequestMapping("phcheck")
public ModelAndView pay(@RequestParam("empid") int empid, String fdate, String tdate) 
    ModelAndView mav = new ModelAndView("phcheck");
    List<Employee> employees = entityManager.createQuery(
        "SELECT e FROM Employee e WHERE e.empId = " + empid, Employee.class)
        .getResultList();
    mav.addObject("employees", employees); // I need this list of employee in AJAX

    return mav;

相关视图中的AJAX代码:

$(document).ready(function () 
    $("#empid").change(function () 
        if ($("#fdate").val() != "" && $("#tdate").val() != "" && $("#empid").val() != "") 
            jQuery.ajax(
                url: "phcheck.htm?empid=" + $("#empid").val() +
                                 "&&fdate=" + $("#fdate").val() +
                                 "&&tdate=" + $("#tdate").val(),
                success: function (data) 
                    alert(data + "success");
                ,
                error: function (data) 
                    alert(data + "error");
                
            );
         else 
            alert("Please fill the from date and to date or select the employee id");
            $("#empid .option").attr("selected", "selected");
        
    );
);

提前致谢。

【问题讨论】:

【参考方案1】:

我需要这个 ajax 中的员工列表

spring 当你需要对象序列化、反序列化和消息转换时。在这种情况下,您需要使用@RequestBody@ResponseBody 注释您的控制器处理程序方法。

地点:

@ResponseBody : 将通知 spring 尝试转换其返回值并自动将其写入 http 响应。 @RequestBody :将通知 spring 尝试将传入请求正文的内容动态转换为您的参数对象。

在您需要 JSON 类型的情况下,您必须将 @ResponseBody 添加到您的方法签名或方法上方,并生成和使用可选的,例如:

@RequestMapping(value="phcheck", method=RequestMethod.GET
                produces="application/json")
public @ResponseBody List<Employee> pay(@RequestParam("empid") int empid, String fdate, String tdate) 

  //get your employee list here
  return empList;

并在 AJAX 调用中使用:

contentType: 'application/json' 属性告诉您发送的数据类型。和 dataType: json 属性告诉 jquery 将收到什么内容类型的响应。

在你的情况下,contentType: 'application/json' 不需要,默认一个,即'application/x-www-form-urlencoded; charset=UTF-8' 就足够了。

并且您可以在您的 AJAX 成功中收到员工列表,以便对其进行迭代:

  success: function (data) 
          $.each(data, function(index, currEmp) 
             console.log(currEmp.name); //to print name of employee
         );    
        ,


注意: Jackson mapper 或任何其他映射器应该在 buildpath 上可用,以便进行 JSON 序列化和反序列化。

另请参阅:

New features in spring mvc 3.1

【讨论】:

【参考方案2】:
@RequestMapping(value = "phcheck", produces = "application/json")
@ResponseBody
public ModelAndView pay(@RequestParam("empid") int empid, @RequestParam("fdate") String fdate, @RequestParam("tdate") String tdate) 

   return entityManager.createQuery("select e from Employee e where e.empId="+empid, Employee.class).getResultList();



url:"phcheck.htm?empid="+$("#empid").val()+"&fdate="+$("#fdate").val()+"&tdate="+$("#tdate").val()

在 Spring MVC 中,您必须注册 MappingJackson2HttpMessageConverter 就像完成 here

【讨论】:

我已经从 jQuery ajax 获取到控制器的值,但是我无法在 jQuery ajax 中接收到控制器的返回结果。【参考方案3】:

ModelAndView 意味着您计划渲染一个视图,而您并没有。要仅返回对象,请使用 @ResponseBody 注释:

@RequestMapping("phcheck")
public @ResponseBody List<Employee> pay(@RequestParam("empid") int empid, String fdate, String tdate) 
   return entityManager.createQuery("select e from Employee e where e.empId="+empid, Employee.class).getResultList();

此外,您应该更加小心处理查询的方式。您的查询不安全,将允许 sql 注入。例如,如果有人使用 empId = "'15' or '1'='1'" 调用您的方法,那么它将返回整个员工列表。

【讨论】:

如何在这种方法中增强安全性或防止sql注入,请您解释一下吗?? orm 工具已经限制了 sql 注入。如果您遵循他们的标准。如果您想安全起见,请使用准备好的语句来摆脱这些类型的问题。【参考方案4】:

在控制器中将方法设为@ResponseBody 类型,并在ajax 中从成功函数中获取列表。

如果使用 Maven,请将 Jackson Mapper 文件放入 Pom.xml 文件中

【讨论】:

以上是关于如何从 Spring MVC 控制器返回对象以响应 AJAX 请求?的主要内容,如果未能解决你的问题,请参考以下文章

Spring MVC 返回 JSONS 和异常处理

如何在 Spring MVC 中返回 403 Forbidden?

如何使用 Spring MVC 设计通用响应构建器/RESTful Web 服务?

Spring MVC 中 Json 响应的后处理

如何在spring mvc中的操作之前发送响应

使用 Spring MVC HandlerInterceptorAdapter 从 HttpServletResponse 记录响应正文 (HTML)