最近需要做些接口服务,服务协议定为JSON,为了整合在Spring中,一开始确实费了很大的劲,经朋友提醒才发现,SpringMVC已经强悍到如此地步,佩服!

相关参考: 
Spring 注解学习手札(一) 构建简单Web应用 
Spring 注解学习手札(二) 控制层梳理 
Spring 注解学习手札(三) 表单页面处理 
Spring 注解学习手札(四) 持久层浅析 
Spring 注解学习手札(五) 业务层事务处理 
Spring 注解学习手札(六) 测试 
Spring 注解学习手札(七) 补遗——@ResponseBody,@RequestBody,@PathVariable 
Spring 注解学习手札(八) 补遗——@ExceptionHandler 

SpringMVC层跟JSon结合,几乎不需要做什么配置,代码实现也相当简洁。再也不用为了组装协议而劳烦辛苦了!

一、Spring注解@ResponseBody,@RequestBody和HttpMessageConverter

Spring 3.X系列增加了新注解@ResponseBody@RequestBody

  • @RequestBody 将HTTP请求正文转换为适合的HttpMessageConverter对象。
  • @ResponseBody 将内容或对象作为 HTTP 响应正文返回,并调用适合HttpMessageConverter的Adapter转换对象,写入输出流。

HttpMessageConverter接口,需要开启<mvc:annotation-driven  />。 
AnnotationMethodHandlerAdapter将会初始化7个转换器,可以通过调用AnnotationMethodHandlerAdaptergetMessageConverts()方法来获取转换器的一个集合 List<HttpMessageConverter>

引用
ByteArrayHttpMessageConverter 
StringHttpMessageConverter 
ResourceHttpMessageConverter 
SourceHttpMessageConverter 
XmlAwareFormHttpMessageConverter 
Jaxb2RootElementHttpMessageConverter 
MappingJacksonHttpMessageConverter

可以理解为,只要有对应协议的解析器,你就可以通过几行配置,几个注解完成协议——对象的转换工作!

PS:Spring默认的json协议解析由Jackson完成。

二、servlet.xml配置

Spring的配置文件,简洁到了极致,对于当前这个需求只需要三行核心配置:

  1. <context:component-scan base-package="org.zlex.json.controller" />
  2. <context:annotation-config />
  3. <mvc:annotation-driven />

三、pom.xml配置

闲言少叙,先说依赖配置,这里以Json+Spring为参考: 
pom.xml

  1. <dependency>
  2. <groupId>org.springframework</groupId>
  3. <artifactId>spring-webmvc</artifactId>
  4. <version>3.1.2.RELEASE</version>
  5. <type>jar</type>
  6. <scope>compile</scope>
  7. </dependency>
  8. <dependency>
  9. <groupId>org.codehaus.jackson</groupId>
  10. <artifactId>jackson-mapper-asl</artifactId>
  11. <version>1.9.8</version>
  12. <type>jar</type>
  13. <scope>compile</scope>
  14. </dependency>
  15. <dependency>
  16. <groupId>log4j</groupId>
  17. <artifactId>log4j</artifactId>
  18. <version>1.2.17</version>
  19. <scope>compile</scope>
  20. </dependency>

主要需要spring-webmvcjackson-mapper-asl两个包,其余依赖包Maven会帮你完成。至于log4j,我还是需要看日志嘛。 
包依赖图: 

至于版本,看项目需要吧!

四、代码实现

域对象:

  1. public class Person implements Serializable {
  2. private int id;
  3. private String name;
  4. private boolean status;
  5. public Person() {
  6. // do nothing
  7. }
  8. }

这里需要一个空构造,由Spring转换对象时,进行初始化。

@ResponseBody,@RequestBody,@PathVariable 
控制器:

  1. @Controller
  2. public class PersonController {
  3. /**
  4. * 查询个人信息
  5. *
  6. * @param id
  7. * @return
  8. */
  9. @RequestMapping(value = "/person/profile/{id}/{name}/{status}", method = RequestMethod.GET)
  10. public @ResponseBody
  11. Person porfile(@PathVariable int id, @PathVariable String name,
  12. @PathVariable boolean status) {
  13. return new Person(id, name, status);
  14. }
  15. /**
  16. * 登录
  17. *
  18. * @param person
  19. * @return
  20. */
  21. @RequestMapping(value = "/person/login", method = RequestMethod.POST)
  22. public @ResponseBody
  23. Person login(@RequestBody Person person) {
  24. return person;
  25. }
  26. }

备注:@RequestMapping(value = "/person/profile/{id}/{name}/{status}", method = RequestMethod.GET)中的{id}/{name}/{status}@PathVariable int id, @PathVariable String name,@PathVariable boolean status一一对应,按名匹配。 这是restful式风格。 
如果映射名称有所不一,可以参考如下方式:

  1. @RequestMapping(value = "/person/profile/{id}", method = RequestMethod.GET)
  2. public @ResponseBody
  3. Person porfile(@PathVariable("id") int uid) {
  4. return new Person(uid, name, status);
  5. }
  • GET模式下,这里使用了@PathVariable绑定输入参数,非常适合Restful风格。因为隐藏了参数与路径的关系,可以提升网站的安全性,静态化页面,降低恶意攻击风险。
  • POST模式下,使用@RequestBody绑定请求对象,Spring会帮你进行协议转换,将Json、Xml协议转换成你需要的对象。
  • @ResponseBody可以标注任何对象,由Srping完成对象——协议的转换。

做个页面测试下: 
JS

  1. $(document).ready(function() {
  2. $("#profile").click(function() {
  3. profile();
  4. });
  5. $("#login").click(function() {
  6. login();
  7. });
  8. });
  9. function profile() {
  10. var url = 'http://localhost:8080/spring-json/json/person/profile/';
  11. var query = $('#id').val() + '/' + $('#name').val() + '/'
  12. + $('#status').val();
  13. url += query;
  14. alert(url);
  15. $.get(url, function(data) {
  16. alert("id: " + data.id + "\nname: " + data.name + "\nstatus: "
  17. + data.status);
  18. });
  19. }
  20. function login() {
  21. var mydata = '{"name":"' + $('#name').val() + '","id":"'
  22. + $('#id').val() + '","status":"' + $('#status').val() + '"}';
  23. alert(mydata);
  24. $.ajax({
  25. type : 'POST',
  26. contentType : 'application/json',
  27. url : 'http://localhost:8080/spring-json/json/person/login',
  28. processData : false,
  29. dataType : 'json',
  30. data : mydata,
  31. success : function(data) {
  32. alert("id: " + data.id + "\nname: " + data.name + "\nstatus: "
  33. + data.status);
  34. },
  35. error : function() {
  36. alert('Err...');
  37. }
  38. });

Table

  1. <table>
  2. <tr>
  3. <td>id</td>
  4. <td><input id="id" value="100" /></td>
  5. </tr>
  6. <tr>
  7. <td>name</td>
  8. <td><input id="name" value="snowolf" /></td>
  9. </tr>
  10. <tr>
  11. <td>status</td>
  12. <td><input id="status" value="true" /></td>
  13. </tr>
  14. <tr>
  15. <td><input type="button" id="profile" value="Profile——GET" /></td>
  16. <td><input type="button" id="login" value="Login——POST" /></td>
  17. </tr>
  18. </table>

四、简单测试

Get方式测试: 

Post方式测试: 

五、常见错误 
POST操作时,我用$.post()方式,屡次失败,一直报各种异常: 

引用
org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'application/x-www-form-urlencoded;charset=UTF-8' not supported 
org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'application/x-www-form-urlencoded;charset=UTF-8' not supported 
org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'application/x-www-form-urlencoded;charset=UTF-8' not supported

直接用$.post()直接请求会有点小问题,尽管我标识为json协议,但实际上提交的ContentType还是application/x-www-form-urlencoded。需要使用$.ajaxSetup()标示下ContentType

  1. function login() {
  2. var mydata = '{"name":"' + $('#name').val() + '","id":"'
  3. + $('#id').val() + '","status":"' + $('#status').val() + '"}';
  4. alert(mydata);
  5. $.ajaxSetup({
  6. contentType : 'application/json'
  7. });
  8. $.post('http://localhost:8080/spring-json/json/person/login', mydata,
  9. function(data) {
  10. alert("id: " + data.id + "\nname: " + data.name
  11. + "\nstatus: " + data.status);
  12. }, 'json');
  13. };

效果是一样!

详见附件!

相关参考: 
Spring 注解学习手札(一) 构建简单Web应用 
Spring 注解学习手札(二) 控制层梳理 
Spring 注解学习手札(三) 表单页面处理 
Spring 注解学习手札(四) 持久层浅析 
Spring 注解学习手札(五) 业务层事务处理 
Spring 注解学习手札(六) 测试 
Spring 注解学习手札(七) 补遗——@ResponseBody,@RequestBody,@PathVariable 
Spring 注解学习手札(八) 补遗——@ExceptionHandler 

转-Spring 注解学习手札(七) 补遗——@ResponseBody,@RequestBody,@PathVariable的更多相关文章

  1. Spring 注解学习手札(七) 补遗——@ResponseBody,@RequestBody,@PathVariable (转)

    最近需要做些接口服务,服务协议定为JSON,为了整合在Spring中,一开始确实费了很大的劲,经朋友提醒才发现,SpringMVC已经强悍到如此地步,佩服! 相关参考: Spring 注解学习手札(一 ...

  2. Spring 注解学习手札(七) 补遗——@ResponseBody,@RequestBody,@PathVariable(转)

    最近需要做些接口服务,服务协议定为JSON,为了整合在Spring中,一开始确实费了很大的劲,经朋友提醒才发现,SpringMVC已经强悍到如此地步,佩服! 相关参考: Spring 注解学习手札(一 ...

  3. 【转】Spring 注解学习手札(超好的springmvc注解教程)

    Spring 注解学习手札(一) 构建简单Web应用 Spring 注解学习手札(二) 控制层梳理 Spring 注解学习手札(三) 表单页面处理 Spring 注解学习手札(四) 持久层浅析 Spr ...

  4. Spring 注解学习笔记

    声明Bean的注解: @Component : 组件,没有明确的角色 @Service : 在业务逻辑层(service层)使用 @Repository : 在数据访问层(dao层)使用. @Cont ...

  5. Spring 注解学习 详细代码示例

    学习Sping注解,编写示例,最终整理成文章.如有错误,请指出. 该文章主要是针对新手的简单使用示例,讲述如何使用该注释,没有过多的原理解析. 已整理的注解请看右侧目录.写的示例代码也会在结尾附出. ...

  6. Spring Boot学习笔记(七)多数据源下的事务管理

    DataBaseConfig中加入事务管理器 DataBaseConfig的详解以及多数据源的配置参见我的上一篇文章 @Configuration @MapperScan(basePackages={ ...

  7. Spring注解驱动开发(七)-----servlet3.0、springmvc

    ServletContainerInitializer Shared libraries(共享库) / runtimes pluggability(运行时插件能力) 1.Servlet容器启动会扫描, ...

  8. spring框架学习(七)spring管理事务方式之xml配置

    1.DAO AccountDao.java package cn.mf.dao; public interface AccountDao { //加钱 void increaseMoney(Integ ...

  9. Spring注解学习笔记一

    一.Retention注解Retention(保留)注解说明,这种类型的注解会被保留到那个阶段. 有三个值: 1.RetentionPolicy.SOURCE —— 这种类型的Annotations只 ...

随机推荐

  1. apache http client vs urlconnection

    Google has deprecated HttpClient Choose an HTTP Client Most network-connected Android apps use HTTP ...

  2. UITouch的用法

    UITouch一般无法直接获取,是通过UIView的touchesBegan等函数获得. //这四个方法是UIResponder中得方法 // Generally, all responders wh ...

  3. BZOJ 3260 跳

    YY一下发现答案基本上就是(n+1)+ΣC(n+i,i),其中i=1...m. 然后发现后面每一项可以递推,只要处理1..m的逆元就好了. 这题很容易爆long long,每一步都要取模. #incl ...

  4. Palindrome Number ---- LeetCode 009

    Determine whether an integer is a palindrome. Do this without extra space. Some hints: Could negativ ...

  5. Java 集合源码解析(1):Iterator

    Java, Android 开发也有段时间了,当初为了早点学 Android,Java 匆匆了解个大概就结束了,基础不够扎实. 虽然集合框架经常用,但是一直没有仔细看看原理,仅止于会用,不知道为什么要 ...

  6. JDBC接口规范

    前言 JDBC(JavaDatabase Connectivity)表示Java查询引擎连接,由一组用Java编程语言编写的类和接口组成.JDBC为Java程序访问关系型查询引擎提供了编程接口,为查询 ...

  7. Linux下用C读取配置文件。类似ini这样。

    Introduction ccl is the customizable configuration library, a collection of functions for applicatio ...

  8. 在FreeBSD上安装Bugzilla

    Bugzilla 是一款开源的 Web 应用,是一款bug跟踪系统和测试工具,由 mozilla 开发,并采用 Mozilla 公共许可证授权(MPL),它经常被一些高科技公司如 mozilla.红帽 ...

  9. 简单实用的纯CSS百分比圆形进度条插件

    percircle是一款简单实用的纯CSS百分比圆形进度条插件.你不需要做任何设置,只需要按该圆形进度条插件提供的标准HTML结构来编写代码,就可以生成一个漂亮的百分比圆形进度条. 首先要做的就是引入 ...

  10. yii点击上传图片后立即显示

    结合yii上传做的图片上传后立即显示,自己琢磨的,有点low <script type="text/javascript">//下面用于图片上传预览功能function ...