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. 基于dsp_builder的算法在FPGA上的实现

    基于dsp_builder的算法在FPGA上的实现   一.摘要 结合dsp_builder.matlab.modelsim和quartus ii等软件完成算法的FPGA实现. 二.实验平台 硬件平台 ...

  2. [ci] 基于1 上文实现拉取代码后能自动触发sonar-runner实现代码扫描评测,job1完成

    基于1 上文实现拉取代码后能自动触发sonar-runner实现代码扫描评测,job1完成   添加sonar插件 SonarQube Plugin   配置: 系统设置à告知jenkins,sona ...

  3. html之常用元素

    基础: <!DOCTYPE> 定义文档的类型 语法: html5 <!DOCTYPE html> <html> 定义html文档,这个就不多说了! <titl ...

  4. PHP预定义常量DIRECTORY_SEPARATOR

    PHP预定义常量DIRECTORY_SEPARATOR BY 天涯 · // DIRECTORY_SEPARATOR是一个显示系统分隔符的命令,DIRECTORY_SEPARATOR是PHP的内部常量 ...

  5. PHP使用CURL获取302跳转后的地址实例

    /*返回一个302地址*/     function  curl_post_302($url, $vars) { $ch = curl_init();          curl_setopt($ch ...

  6. Cmder 配置使用

    官网下载 配置: 1.把 Cmder 加到环境变量 将Cmder.exe存放的目录添加到系统环境变量path 添加成功后,Win+r 输入cmder,可以正确打开cmder 窗口即可. 2.添加 cm ...

  7. PHP中插件机制的一种实现方案

    这篇文章的出发点是我对插件机制的理解,及其在PHP中的实现.此方案仅是插件机制在PHP中的实现方案之一,写下来和大家分享,欢迎大家一起讨论. 插件,亦即Plug-in,是指一类特定的功能模块(通常由第 ...

  8. Eclipse 创建 XML 文件

    Eclipse 创建 XML 文件 打开新建 XML 文件向导 你可以使用新建 XML 文件向导来创建 XML 文件.打开向导的方式有: 点击 File 菜单并选择 New > Other 点击 ...

  9. Spring 入门之-dao使用jdbcTemplate(注入过程)

    技巧:在为把dataSourc连接池注入到jdbcTemplate里面时,学到一招:按住CTRL 不松,点击相关类名,可以自动跳转或打开. 说明:主要过程, 1.创建UserDao和UserServi ...

  10. asp.net c#采集需要登录页面的实现原理及代码

    当我们采集页面的时候,如果被采集的网站需要登录才能采集,原理搞清楚了,就好办了,我们所要做的仅仅是在采集的时候(或者说HttpWebRequest提交数据的时候),将Cookie信息放入Http请求头 ...