springMVC默认的 Json 解决方案是 Jackson, 所以只需要导入 Jackson 的 jar, 即可使用.
导入Jackson的依赖:
<!--Jackson--> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.9.8</version> </dependency> </dependencies>
jackson 可以通过以下三个注解来实现对 json 数据的处理:
- @ResponseBody
- @RestController
- @RequestBody
一. @ResponseBody
这个注解的意思是: 把这个handler的返回值转成json返回给客户端, 所以此handler不会跳转到相关JSP页面, 如果返回的是字符串, 则不会转成Json, 直接返回
handler 代码:
@Controller @RequestMapping("/jackson") public class TestJackson { @RequestMapping("/test1") //这个注解的意思是: 把这个handler的返回值转成json返回给客户端, 所以此handler不会跳转到相关JSP页面, 如果返回的是字符串, 则不会转成Json, 直接返回 @ResponseBody public JacksonData test1(){ System.out.println("test1"); JacksonData jacksonData = new JacksonData("name", "张三"); return jacksonData; } }
JacksonData.java 代码:
public class JacksonData { private String jacksonName; private String jacksonValue; @Override public String toString() { return "JacksonData{" + "jacksonName=‘" + jacksonName + ‘\‘‘ + ", jacksonValue=‘" + jacksonValue + ‘\‘‘ + ‘}‘; } public JacksonData(String jacksonName, String jacksonValue) { this.jacksonName = jacksonName; this.jacksonValue = jacksonValue; } public String getJacksonName() { return jacksonName; } public String getJacksonValue() { return jacksonValue; } public void setJacksonName(String jacksonName) { this.jacksonName = jacksonName; } public void setJacksonValue(String jacksonValue) { this.jacksonValue = jacksonValue; } }
访问及返回:
在@ResponseBody注解下, 若return字符串, 则直接将此字符串返回给客户端:
*注意: 此时由于未调用springMVC操作转json, 直接返回中文会有乱码问题, 需要我们设置编码格式, 设置方式为在@RequestMapping注解的参数中指定 value = "/test2", produces = "text/html;charset=utf-8"
@Controller @RequestMapping("/jackson") public class TestJackson { @RequestMapping(value = "/test2", produces = "text/html;charset=utf-8") @ResponseBody public String test2() { System.out.println("test2"); //在@ResponseBody注解下, 若return字符串, 则直接将此字符串返回给客户端 return "服务器数据"; } }
访问及返回:
二. @RestController
当我们在一个Controller中的所有handler前都要加@ResponseBody注解时, 我们可以在这个Controller前面加上@RestController注解, 这样, 其下的所有@ResponseBody注解都不需要加了, 同时, @RestController是一个复合注解, 其中集成了@Controller, 所以@Controller注解也可以省略, 如下示例:
@RequestMapping("/jackson") @RestController public class TestJackson { @RequestMapping("/test1") public JacksonData test1(){ System.out.println("test1"); JacksonData jacksonData = new JacksonData("name", "张三"); return jacksonData; } @RequestMapping(value = "/test2", produces = "text/html;charset=utf-8") public String test2() { System.out.println("test2"); return "服务器数据"; } }
访问及返回:
三. @RequestBody
@RequestBody 注解可以用来接收请求的 json 数据. 用法如下:
@RequestMapping("/jackson") @RestController public class TestJackson { @RequestMapping(value = "/test3", method = {RequestMethod.POST}) @ResponseBody //@RequestBody注解会让springMVC接收前端传过来的json数据并转成JacksonData对象赋值给jacksonData public String test3(@RequestBody JacksonData jacksonData){ System.out.println(jacksonData); return "hello"; } }
@RequestBody 只能接收post的数据, 创建testJackson.jsp:
<html> <head> <title>Title</title> <script src="js/jquery-2.1.1.js"></script> </head> <body> <input id="i1" type="button" value="ajax" onclick="send_json1();">
<script> function send_json1() { var data = {jacksonName: "Ryan", jacksonValue: "good"}; var dataJson = JSON.stringify(data); $.ajax({ // url: "localhost:8080/jackson/test3", url: "${pageContext.request.contextPath}/jackson/test3", type: "post", data: dataJson, dataType:"json", contentType: "application/json", success: function (res) { alert(res); } }) } </script> </body> </html>
先直接访问testJackson.jsp, 再通过这个页面以 Ajax 将数据以post的方式提交到 servlet, 正常情况下服务器将打印提交的数据.
但是按这样的写法, 我们可以发现, 在访问到 testJackson.jsp, 调用Ajax之后, 服务端报错 500:
如果是使用谷歌浏览器, 还会自动跳转到 Sources 页面并表示 jQuery 的 xhr.send( options.hasContent && options.data || null ); 这行代码有问题, 我不是很懂谷歌报这个错是什么意思...??
这个问题是因为, servlet 中用来接收 json 的对象的类中没有写无参构造器, 在本例中, 也就是 JacksonData 这个类没有无参构造器.
我们把这个类的无参构造器加上:
浏览器就能正常发送请求了, 服务端也能正常获取到前端提交的数据: