【Spring-MVC AJAX请求】
前言
准备筹划一个自己的个人网站,初步的架构设计采用SSH(Spring-MVC,Spring,Hibernate),
在这里顺便记录一下设计和开发过程,以备参考。后续会陆续更新文档,如有任何问题,
欢迎各位不吝指出,共同学习。
环境
eclipse | 4.3.2 |
maven | 3.2.1 |
Spring-MVC | 3.2.3.RELEASE |
Spring | Spring |
Hibernate | 3.2.5 |
十三哥将来的架构是后台不渲染页面,只返回JSON数据,所以在此详细
介绍下SpirngMVC对ajax请求的处理。
【添加处理JSON数据的jar包】
pom.xml添加spring-mvc的依赖
<!-- jack core annotation databind begin--> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <version>2.2.2</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-annotations</artifactId> <version>2.2.2</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.2.2</version> </dependency> <dependency> <groupId>org.codehaus.jackson</groupId> <artifactId>jackson-mapper-lgpl</artifactId> <version>1.9.12</version> </dependency> <!-- jack core annotation databind end--> <!-- Fastjson begin(这个可以不需要,因为Fastjson要比Jackson的效率高, 当自己组织JSON数据时可以使用)--> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.1.30</version> </dependency> <!-- Fastjson end-->
【Controller代码】
package com.xbs.ready.ssh.controller; import com.alibaba.fastjson.JSON; import java.io.IOException; import java.io.PrintWriter; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; /** * * @author xbs */ @Controller @RequestMapping("hello") public class HelloController { /** * ajax请求不需要返回页面,只需要得到response中的数据即可,所以方法签名为void即可 * * @param request * @param response */ @RequestMapping(value = "ajax", method = RequestMethod.POST) public void ajaxDatas(HttpServletRequest request, HttpServletResponse response) { String jsonResult = getJSONString(request); renderData(response, jsonResult); } private String getJSONString(HttpServletRequest request) { //故意构造一个数组,使返回的数据为json数组,数据更复杂些 List<Map<String, Object>> datas = new ArrayList<Map<String, Object>>(5); Map<String, Object> map1 = new HashMap<String, Object>(10); //可以获得ajax请求中的参数 map1.put("a", request.getParameter("a")); map1.put("b", request.getParameter("b")); map1.put("c", request.getParameter("c")); datas.add(map1); //故意构造一个数组,使返回的数据为json数组,数据更复杂些 Map<String, Object> map2 = new HashMap<String, Object>(10); map2.put("a", "11"); map2.put("b", "22"); map2.put("c", "33"); datas.add(map2); String jsonResult = JSON.toJSONString(datas); return jsonResult; } /** * 通过PrintWriter将响应数据写入response,ajax可以接受到这个数据 * * @param response * @param data */ private void renderData(HttpServletResponse response, String data) { PrintWriter printWriter = null; try { printWriter = response.getWriter(); printWriter.print(data); } catch (IOException ex) { Logger.getLogger(HelloController.class.getName()).log(Level.SEVERE, null, ex); } finally { if (null != printWriter) { printWriter.flush(); printWriter.close(); } } } }
【HTML代码】
html文件路径:.../webapp/views/index.html
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html > <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <!--<script type="text/javascript" src="../static/js/jquery-1.7.2.min.js"> </script>--> <!--JS的地址可以写成下面这样,将来部署的时候,这些静态文件就可以单独部署了, 不依赖于后台路径--> <script type="text/javascript" src="http://localhost:8080/sshdemo /static/js/jquery-1.7.2.min.js"></script> <script type="text/javascript"> $(document).ready(function() { ajaxRequest(); }); function ajaxRequest() { $.ajax({ url: "http://localhost:8080/sshdemo/hello/ajax", type: "POST", dataType: "json", data: { "a": 1, "b": 2, "c": 3 }, async: false, success: function(data) { alert("success"); $.each(data, function(index, element) { alert(element.a); alert(element.b); alert(element.c); }); }, error: function() { alert("error"); } }); } </script> </head> <body> <div>Hello World!</div> </body> </html>
访问路径:http://localhost:8080/sshdemo/views/index.html
(或者:http://localhost:8080/sshdemo/)
使用@ResponseBody注解
Spring的官方文档中这样说:
The @ResponseBody annotation is similar to @RequestBody. This annotation can be put on a
method and indicates that the return type should be written straight to the HTTP response body
(and not placed in a Model, or interpreted as a view name).
意思是:@ResponseBody与@RequestBody差不多。@ResponseBody可以用在方法上,这样说
明方法的返回结果会被直接写在HTTP的response内。既然写在了response的body内,那么就不是
一个Model或者视图的名字。从而判断出返回的肯定不是页面了。
Sping官网给的例子如下:
@RequestMapping(value = "/something", method = RequestMethod.PUT) @ResponseBody public String helloWorld() { return "Hello World"; }
如果上面的代码中没有使用@ResponseBody注解,那么返回的就是一个页面,页面名字是【Hello
World】(例如:Hello World.jsp)。 但是使用了@ResponseBody注解后,response的body内会
写入Hello World这个字符串,ajax当然也就可以获取到了。
Spring文档给出了一段说明:
As with @RequestBody, Spring converts the returned object to a response body by using an
HttpMessageConverter.
意思是:使用@RequestBody时,Spring会使用HttpMessageConverter将返回结果写到response的
body里。所以,如果有想了解这方面原理的朋友,可以去官网看看 http://docs.spring.io/spring/docs/3.0.x/spring-framework-reference/html/remoting.html#rest-message-conversion
Spring提供的HttpMessageConverter大致有以下这几个:
StringHttpMessageConverter,FormHttpMessageConverter,ByteArrayMessageConverter,
MarshallingHttpMessageConverter,MappingJacksonHttpMessageConverter,
SourceHttpMessageConverter,BufferedImageHttpMessageConverter
使用ResponseEntity
Spring的官方文档这样说:
A HttpEntity<?> or ResponseEntity<?> object to provide access to the Servlet response HTTP
headers and contents. The entity body will be converted to the response stream using
HttpMessageConverters.
意思是:HttpEntity或者ResponseEntity可以访问Servlet的响应头和正文。使用
HttpMessageConverters将实体写到响应流中。这样的话,ajax就可以获得后台的响应数据了。
HttpEntity支持泛型,可以通过HttpEntity获得请求中的参数。
【Controller代码】
@RequestMapping("entity") public ResponseEntity<Map> handle(HttpEntity<String> requestEntity) { //获得ajax的请求数据 String body = requestEntity.getBody(); System.out.println("requestParams:" + body); //构造一个map作为返回数据,前端会接收到JSON格式的数据 Map<String, Object> map = new HashMap<String, Object>(10); map.put("a", "11"); map.put("b", "22"); map.put("c", "33"); return new ResponseEntity<Map>(map, HttpStatus.OK); }
【AJAX代码】
//url = "http://localhost:8080/sshdemo/hello/entity"; function responseEntity(url) { $.ajax({ url: url, type: "POST", dataType: "json", data: { "a": 1, "b": 2, "c": 3 }, async: false, success: function(data) { alert("success"); alert(data.a); alert(data.b); alert(data.c); }, error: function() { alert("error"); } }); }
【问题说明】
问题1:当使用ResponseEntity处理ajax请求时,出现406 Not Acceptable
HTTP Status 406 - type Status report message description The resource identified by this request is only capable of generating responses with characteristics not acceptable according to the request "accept" headers. Apache Tomcat/7.0.34
解决方案:这个问题与SpringMVC的版本和配置有关。
修改springMVC-servlet.xml中spring-mvc的文档版本为3.2,增加
ContentNegotiationManagerFactoryBean。
原配置文件:
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" 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">
修改为:
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" 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.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> <!-- 增加以下配置,这样可以使ajax的请求返回JSON数据, 否则返回text/html格式,那么会报406 --> <mvc:annotation-driven content-negotiation-manager="contentNegotiationManager" /> <bean id="contentNegotiationManager" class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean" />
另外,pom.xml中一定要添加jackson的依赖,springMVC通过使用jackson把返回结果转换成JSON格式
的数据。
在以上的三种处理ajax请求的方式中(1:方法声明层void 2:使用@ResponseBody
3:使用ResponseEntity),极力推荐使用@ResponseBody这种方式。
因为@ResponseBody不用修改配置文件为3.2,不依赖于jackson包。
相关推荐
配置Springmvc 处理ajax请求所需jar包 包含jackson-annotations-2.1.1.jar,jackson-core-2.1.1.jar,jackson-core-lgpl-1.2.1.jar,jackson-databind-2.1.2.jar,jackson-mapper-lgpl-1.2.1.jar,jackson-module-...
springmvc接收ajax请求注意事项
NULL 博文链接:https://cdxs2.iteye.com/blog/1950519
主要介绍了Springmvc处理ajax请求并返回json数据,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
使用springmvc整合ajax请求demo代码示例
使用Ajax从页面向控制层请求数据,并将提交的数据再次返回,国外网站下载代码,很有参考意义。请使用Eclipse工具
一个实用了spring mvc和ajax异步请求的例子
SpringMVC(八)处理AJAX请求
其中包括jackson-annotations-2.8.7.jar,jackson-core-2.8.7.jar,jackson-databind-2.8.7.jar
主要介绍了springMVC解决ajax请求乱码的三种方法的相关资料,在springmvc的项目中,使用返回页面的请求方式,数据都能正常显示,但是对于ajax的请求,始终显示乱码,这里提供解决办法,需要的朋友可以参考下
Ajax实现异步请求+基于SpringMVC
主要介绍了Springmvc ajax跨域请求处理方法实例详解,需要的朋友可以参考下
sprinmvc框架 demo spring+springmvc HIbernate
springmvc jquery ajax json 异步传递数据 springmvc异步传递请求 已包含全部源代码实现 把jar包放入 然后新建文件 配置xml !!!!! 全部资源
SpringMVC使用Ajax异步提交请求完成登录-附件资源
SpringMVC框架下使用jQueryAJAX进行数据交互的一个DEMO http://blog.csdn.net/lazyrabbitlll/article/details/78615309
Springmvc_注解方式+批量增加数据库+ajax异步请求【图解】.png
springmvc 例子; 使用框架:spring(包含hibernate),jquery。 ajax,文件上传,拦截器.....
十五、spring mvc 处理ajax请求 十六、spring mvc 关于写几个配置文件的说明 十七、spring mvc 如何取得Spring管理的bean 十八、spring mvc 多视图控制器 十九、 <mvc:annotation-driven /> 到底做了什么工作 二十...