1 关于REST

  我的理解,REST就是将资源以最合适的形式在服务端和客户端之间传递。

  • 系统中资源采用URL进行标识(可以理解为URL路径中带参数)
  • 使用HTTP方法进行资源的管理(GET,PUT,POST,DELETE等HTTP方法)
  • 以一种或者多种适合客户端的方式来表述资源(@ResponseBody,@RequestBody,ContentNegotiatingViewResolver视图解析器)

2 REST风格的Controller

2.1 RESTful URL

  先来看一下RESTful的url和RESTless的url有何区别:

RESTful的url——http://localhost:8080/ProjectName/students/123
RESTless的url——http://localhost:8080/ProjectName/studentDetail.html?id=123

  RESTful的url是面向资源的,可以用来标识资源,而RESTless的url是面向行为的,不能标识资源。

  RESTful的url是有多个层级的,比如localhost:8080标识了域和端口,ProjectName标识了运行在服务器上的应用程序,students标识了学生列表资源,123标识了id为123的学生资源。

  RESTful的url的路径是参数化的。RESTless的url使用查询参数作为输入,而RESTful的url的输入是url路径的一部分。为了处理这种类型的url,需要一种能够从url路径中获取输入的Controller。

2.2 获取RESTful URL的参数

  为了使用参数化的url路径,Spring 3引入了新的@PathVariable注解。

@Controller
@RequestMapping("/students")
public class StudentController{
...
  @RequestMapping(value="/{id}",method=RequestMethod.GET)
  public String getStudent(@PathVariable("id") long id){
    ...
  }
}

  @RequestMapping用于处理请求地址,@PathVariable用于获取请求地址中的参数。

  如果方法的参数名与路径的变量名相同,可以省略@PathVariable的值,如下:

  @RequestMapping(value="/{id}",method=RequestMethod.GET)
  public String getStudent(@PathVariable long id){
    ...
  }

2.3 使用HTTP方法进行资源的管理

  HTTP提供了多种方法来操作资源,常用的有4种方法:GET,POST,PUT,DELETE。这四种方法对应的操作分别是:获取、创建、更新和删除。

  Spring中使用@RequestMapping注解的method属性设置方法应该处理的方法类型,例如上例中getStudent方法就是一个处理GET请求的例子。

  有一点非常重要:尽管@RequestMapping注解的method属性设置方法应该处理的方法类型,但方法里的实现也应该遵循方法的语义,这一点取决于开发者的代码编写,比如getStudent方法中不应该出现更新或者删除student的代码。

3 表述资源

  表述资源是REST中很重要的一个方面,它意味着在服务器和客户端之间,资源可以以任意的形式传递——资源没有发生变化,只是它的表述方式发生变化了。

  Spring提供了两种方法将资源的Java表述形式转换为发送给客户端的表述形式:

  • 基于视图渲染进行协商(ContentNegotiatingViewResolver视图解析器)
  • HTTP消息转换器(@ResponseBody注解)

3.1 ContentNegotiatingViewResolver视图解析器

  Spring的ContentNegotiatingViewResolver是一个特殊的视图解析器,它会将资源以最适合的形式返回给客户端(同一资源,多种返回)。

  ContentNegotiatingViewResolver如何确定客户端最适合的资源类型呢?

  • 通过查看URL的文件扩展名(http://www.test.com/user.json
  • 通过查看http request header的Accept(Accept:application/json
  • 通过查看URL中的format参数(http://www.test.com/user?format=json

  像其它的视图解析器一样,ContentNegotiatingViewResolver也需要作为一个<bean>配置在Spring上下文里。  

<bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
<property name="mediaTypes">
<map>
<entry key="json" value="application/json" />
<entry key="xml" value="application/xml"/>
</map>
</property> 默认为true,若设置为false,则忽略查看URL的文件扩展名
<property name="favorPathExtension" value="true"></property> 默认为true,若设置为false,则忽略查看URL中的format参数
<property name="favorParameter" value="false"></property> 默认为false,若设置为true,则忽略查看Accept信息
<property name="ignoreAcceptHeader" value="true"></property> 如果所有的mediaType都没匹配上,并且请求头中不包含Accept头部信息,就会使用defaultContentType
<property name="defaultContentType" value="text/html" />
</bean>

  ContentNegotiatingViewResolver会首先查看URL的文件扩展名或format参数,如果没有,则查看Accept信息,如果再没有,则使用defaultContentType属性设置的类型。

  不像其它视图解析器那样,ContentNegotiatingViewResolver并不会直接解析视图,而是委托其它视图解析器来解析,如果没有特别指明的话,它将使用应用程序中的所有视图解析器。但可以通过设置viewResolvers属性声明它委托的视图解析器列表。

3.2 Spring HTTP信息转换器和@ResponseBody

  典型的Spring MVC的Controller方法在结束的时候会将一些信息放在模型中,返回值通常解析为跳转路径。

  Spring HTTP消息转换器的工作是,将处理方法返回的Java对象转换为满足客户端要求的表述形式。

  如果方法使用@ResponseBody注解,则表明Spring HTTP信息转换器将会发挥作用,并将返回的对象转换为客户端需要的任意形式。即返回值不会被解析为跳转路径,而是直接写入HTTP response body中。

   @RequestMapping(value = "student/login")
@ResponseBody
public Student login(@RequestBody Student student) {//将请求中的数据写入student对象中
return student;//不会被解析为跳转路径,而是直接写入HTTP response body中
}

  上例中,@ResponseBody注解会告知Spring,将要返回的student对象作为资源返回给客户端,并转换为Accept头部信息要求的表述形式,如果请求中没有Accept头部信息的话,那就假设客户端可以接受任意的表述形式。

  @ResponseBody能对发送给客户端的数据进行转换成适合的表述形式,而@RequestBody能把客户端发来的数据转换成Java对象。

4 提交RESTful表单

  前面说的都是如何在服务端添加REST功能,接下来说浏览器客户端如何与服务端的RESTful资源交互(Java客户端使用RestTemplate模板与服务端交互)。

  前面提到了如何使用HTTP方法(4个主要方法为:GET,POST,PUT和DELETE)定义资源的基本操作——通过使用@RequestMapping注解的method属性,让DispatcherServlet把不同的HTTP方法的请求定向到特定的Controller方法上。那么如何在请求中设置4种不同的HTTP方法呢?

  HTML4官方在表单中值支持GET和POST,忽略了PUT,DELETE以及其他的HTTP方法。HTML5中则支持所有的HTTP方法。

  规避HTML4中缺陷的方法是将PUT和DELETE请求伪装成POST请求,Spring通过两个特性来支持POST伪装:

  • 提交带有隐藏域的表单或者使用<sf:form>JSP标签。
  • 使用HiddenHttpMethodFilter来进行请求转换。

  带有隐藏域的表单示例:  

<form method="post">
<input type="hidden" name="_method" value="delete"/> 创建一个隐藏域,指明期望的HTTP方法。
...
</form>

  使用<sf:form>JSP标签示例:

<sf:form method="delete" modelAttribute="spitter"> 将method设置为期望的HTTP方法,<sf:form>将为你处理隐藏域。
...
</sf:form>

  上面两个例子展示了浏览器端的POST伪装,那服务器端是如何处理这些伪装的POST请求的呢?

  伪装的POST请求到达服务器的时候仍然是一个POST请求,而服务端Controller的方法使用@RequestMapping注解,等待处理PUT和DELETE请求。所以在DispatcherServlet查找控制器处理方法之前,必须将伪装的POST请求转换成期望的请求类型。这就是HiddenHttpMethodFilter所要做的事情。

  HiddenHttpMethodFilter是一个Servlet过滤器,需要在web.xml中进行配置:

    <filter>
<filter-name>HiddenHttpMethodFilter</filter-name>
<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>HiddenHttpMethodFilter</filter-name>
<servlet-name>/*</servlet-name>
</filter-mapping>

  当一个POST请求到达服务器端的时候,HiddenHttpMethodFilte会查看不同请求类型的hidden域,并将请求重写为期望的方法类型。

参考:

《Spring In Action》

http://www.ruanyifeng.com/blog/2011/09/restful

http://www.ruanyifeng.com/blog/2014/05/restful_api.html

http://www.cnblogs.com/rollenholt/p/3693229.html

http://www.cnblogs.com/guodefu909/p/4216327.html

http://blog.csdn.net/z69183787/article/details/41654603

转载请注明出处

Spring学习笔记5—为Spring添加REST功能的更多相关文章

  1. 【Spring学习笔记-MVC-2】spring导出Excel

    说明: 1.结合Spring MVC实现Excel导出功能: 2. 在MVC配置文件中配置Excel视图解析器: 需要的jar包 以poi开头的jar包都是必须的 web.xml <?xml v ...

  2. 【Spring学习笔记-MVC-15】Spring MVC之异常处理

    作者:ssslinppp       1. 描述 在J2EE项目的开发中,不管是对底层的数据库操作过程,还是业务层的处理过程,还是控制层的处理过程,都不可避免会遇到各种可预知的.不可预知的异常需要处理 ...

  3. 【Spring学习笔记-MVC-14】Spring MVC对静态资源的访问

    作者:ssslinppp       参考链接: http://www.cnblogs.com/luxh/archive/2013/03/14/2959207.html  http://www.cnb ...

  4. 【Spring学习笔记-MVC-13】Spring MVC之文件上传

    作者:ssslinppp       1. 摘要 Spring MVC为文件上传提供了最直接的支持,这种支持是通过即插即用的MultipartResolve实现的.Spring使用Jakarta Co ...

  5. 【Spring学习笔记-MVC-10】Spring MVC之数据校验

    作者:ssslinppp       1.准备 这里我们采用Hibernate-validator来进行验证,Hibernate-validator实现了JSR-303验证框架支持注解风格的验证.首先 ...

  6. 【Spring学习笔记-0】Spring开发所需要的核心jar包

    spring开发所需要的核心jar 1. libs目录下的核心jar包: 2. common-logging-xxx.jar 来自为知笔记(Wiz) 附件列表

  7. 【Spring学习笔记-5】Spring中的抽象bean以及bean继承

    *.hl_mark_KMSmartTagPinkImg{background-color:#ffaaff;}*.hl_mark_KMSmartTagBlueImg{background-color:# ...

  8. 【Spring学习笔记-MVC-16】Spring MVC之重定向-解决中文乱码

    概述 spring MVC框架controller间跳转,需重定向,主要有如下三种: 不带参数跳转:形如:http://localhost:8080/SpringMVCTest/test/myRedi ...

  9. 【Spring学习笔记-MVC-12】Spring MVC视图解析器之ResourceBundleViewResolver

    场景 当我们设计程序界面的时候,中国人希望界面是中文,而美国人希望界面是英文. 我们当然希望后台代码不需改变,系统能够通过配置文件配置,来自己觉得是显示中文界面还是英文界面. 这是,Spring mv ...

随机推荐

  1. set hive.exec.parallel

    hive.exec.parallel参数控制在同一个sql中的不同的job是否可以同时运行,默认为false.下面是对于该参数的测试过程: 测试sql:select r1.a    from (sel ...

  2. Failed to add reference to 'System.Net.Http'. Please make sure that it is in the Global Assembly Cache.

    关闭VS再来就好了

  3. android动画具体解释二 属性动画原理

    property动画是一个强大的框架,它差点儿能使你动画不论什么东西. 你能够定义一个动画来改变对象的不论什么属性,不论其是否被绘制于屏幕之上. 一个属性动画在一定时间内多次改变一个属性(对象的一个字 ...

  4. MapReduce-MulitipleOutputs实现自己定义输出到多个文件夹

    输入源数据例子: Source1-0001 Source2-0002 Source1-0003 Source2-0004 Source1-0005 Source2-0006 Source3-0007 ...

  5. android studio - 隐藏编辑器上面的竖线

    android studio 的代码编辑器上面默认有一条竖线不知道是干什么用的,很难看.可以用下列方法进行隐藏. 取消选中这个复选框即可.

  6. Creating Dialogbased Windows Application (1) / 创建基于对话框的Windows应用程序(一)新建窗体 / VC++, Windows

    创建基于对话框的Windows应用程序(一) —— 新建窗体 1.新建一个Visual C++的Empty Project.  2.在Solution Explorer中右键Add New Item, ...

  7. 521. Longest Uncommon Subsequence I【easy】

    521. Longest Uncommon Subsequence I[easy] Given a group of two strings, you need to find the longest ...

  8. finsh初步

    一. finsh在RT-Thread中被设计成一个独立的线程,它试图从外部设备中获得用户的输入,然后对用户命令进行解析执行. 正确使用finsh需要一个关联过程: rt_hw_board_init() ...

  9. 在海思hisiv100nptl平台上交叉编译并安装SRS

    ./configure --with-arm-ubuntu12 && make 须要安装: apt-get installgcc-arm-linux-gnueabi     ,但hi3 ...

  10. JavaScript HTML DOM增删改查

    首先 js 可以修改HTML中的所有元素和属性,它还可以改变CSS样式,并且可以监听到所有事件并作出响应,这篇笔记呢 主要记录如何对HTML元素进行增删改查. 1 查找DOM 第一种方式是我们最常用的 ...