最近需要做些接口服务,服务协议定为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. 云计算平台简介(App Engine)

    云计算平台简介(App Engine)     1   简介 App Engine: 应用程序引擎,是托管网络应用程序的云计算平台. 1.1  什么是云 云计算通常简称为“云”,是一种通过 Inter ...

  2. BZOJ 3439 Kpm的MC密码

    倒着建trie,然后主席树来求子树第k大. #include<iostream> #include<cstdio> #include<cstring> #inclu ...

  3. 浅谈Android应用性能之内存

    本文来自http://blog.csdn.net/liuxian13183/ ,引用必须注明出处! 文/ jaunty [博主导读]在Android开发中,不免会遇到许多OOM现象,一方面可能是由于开 ...

  4. 换个心境搞IT,在IT职场如何打拼?

    刚进入IT这行时,我也是从程序员做起.尤其是前两三个月里,那种感觉就像时时刻刻处于备战状态一样.我是一个在对自己的要求方面有洁癖的人,在没有任何经验的状态下,只有坚持苦干,把下发的每件编程任务做好,才 ...

  5. Nginx启动出错 error while loading shared libraries:

    在centos5.7 32位上编译安照 nginx-1.1.16 出错 [root@localhost conf]# /usr/local/nginx/sbin/nginx/usr/local/ngi ...

  6. Linux中的三个特殊文件

    stdin: 0 标准输入 stdout: 1 标准输出 stderr : 2 标准错误输出 /dev/null 表示一个只写文件.所有写入到这个文件的信息都会丢失

  7. markdown简明语法

    # markdown简明语法 标签(空格分隔): markdown 本语法只涵盖了常用的内容 [toc] 标题 标题 标题 语法为: 根据需求 可以指定 不同大小的标题 # 顶级 ## 次级 ### ...

  8. QQ截图取色方法

    转自:http://www.oicqzone.com/qqjiqiao/2014110920194.html ctrl+alt+a截图的时候,会显示RGB值.是的,你也许会想,但是我要的是#RRGGB ...

  9. Linux 安装挂载时注意事项

    Linux系统下使用的是目录树系统,所以安装的时候要规划磁盘分区与目录树的挂载.实际上,在Linux系统安装的时候已经提供了相当多的默认模式让你选择分割的方式了,不过无论如何,分割的结果可能都不是能符 ...

  10. db2 存储过程 语法 及结果集查询

    第一次用存储过程,关于处理待办的,不知道怎么执行和传参数 给存储过程 ,其实就一句话很简单. @call PRC_MISSIONLIST_QUERY('27020214', '27040000', ' ...