RESTful

https://blog.csdn.net/aiyaya_/article/details/78209992

 

一、概念

一种软件架构风格,设计风格而不是标准,只是提供了一组设计原则和约束条件。

REST,即Representational State Transfer的缩写。翻译是"表现层状态转化"。

它主要用于客户端和服务器交互类的软件。基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。

 

二、原则

最重要的 REST 原则是,客户端和服务器之间的交互在请求之间是无状态的。

从客户端到服务器的每个请求都必须包含理解请求所必需的信息。

如果服务器在请求之间的任何时间点重启,客户端不会得到通知。此外,无状态请求可以由任何可用服务器回答,这十分适合云计算之类的环境。客户端可以缓存数据以改进性能。

访问一个网站,就代表了客户端和服务器的一个互动过程。在这个过程中,势必涉及到数据和状态的变化。

互联网通信协议HTTP协议,是一个无状态协议。这意味着,所有的状态都保存在服务器端。因此,如果客户端想要操作服务器,必须通过某种手段,让服务器端发生"状态转化"(State Transfer)。

而这种转化是建立在表现层之上的,所以就是"表现层状态转化"。

客户端用到的手段,只能是HTTP协议。具体来说,就是HTTP协议里面,四个表示操作方式的动词:GET、POST、PUT、DELETE。

它们分别对应四种基本操作:GET用来获取资源,POST用来新建资源(也可以用于更新资源),PUT用来更新资源,DELETE用来删除资源。

 

另一个重要的 REST 原则是分层系统,这表示组件无法了解它与之交互的中间层以外的组件。通过将系统知识限制在单个层,可以限制整个系统的复杂性,促进了底层的独立性。

每一个URI代表一种资源;

 

三、综述

总结一下什么是RESTful架构:

  (1)每一个URI代表一种资源;

  (2)客户端和服务器之间,传递这种资源的某种表现层;

  (3)客户端通过四个HTTP动词,对服务器端资源进行操作,实现"表现层状态转化"。

 

四、举例

RESTful架构有一些典型的设计误区。

最常见的一种设计错误,就是URI包含动词。因为"资源"表示一种实体,所以应该是名词,URI不应该有动词,动词应该放在HTTP协议中。

举例来说,某个URI是/posts/show/1,其中show是动词,这个URI就设计错了,正确的写法应该是/posts/1,然后用GET方法表示show。

如果某些动作是HTTP动词表示不了的,你就应该把动作做成一种资源。比如网上汇款,从账户1向账户2汇款500元,错误的URI是:

  POST /accounts/1/transfer/500/to/2

正确的写法是把动词transfer改成名词transaction,资源不能是动词,但是可以是一种服务:

  POST /transaction HTTP/1.1
  Host: 127.0.0.1
  
  from=1&to=2&amount=500.00

另一个设计误区,就是在URI中加入版本号:

  http://www.example.com/app/1.0/foo

  http://www.example.com/app/1.1/foo

  http://www.example.com/app/2.0/foo

因为不同的版本,可以理解成同一种资源的不同表现形式,所以应该采用同一个URI。版本号可以在HTTP请求头信息的Accept字段中进行区分(参见Versioning REST Services):

  Accept: vnd.example-com.foo+json; version=1.0

  Accept: vnd.example-com.foo+json; version=1.1

  Accept: vnd.example-com.foo+json; version=2.0

 

五、基于spring mvc的实现

1、URI请求/blog/1 HTTP GET =>  得到id = 1的blog
/blog/1 HTTP DELETE => 删除 id = 1的blog
/blog/1 HTTP PUT =>  更新id = 1的blog
/blog   HTTP POST =>  新增BLOG

 

2、两个问题:

    1.如何在java构造没有扩展名的RESTful url,如 /forms/1,而不是 /forms/1.do

方法一:

在web.xml中进行配置   

        <servlet-name>springmvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:config/dispatcher-servlet.xml</param-value>
        </init-param>
        <load-on-startup>2</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <url-pattern>*</url-pattern>
    </servlet-mapping>

方法二:
应用URL rewrite,现我们使用 http://tuckey.org/urlrewrite/

方法三:
利用web服务器,像niginx,apache,对地址进行rewrite

        2.浏览器的form标签不支持提交delete,put请求,如何曲线解决

方法一:

写过滤器,filter将/blog?_method=delete转换为标准的http delete方法。

 

方法二:

用ajax发送put,delete请求

 

3、关键注解

springmvc的resturl是通过@RequestMapping 及@PathVariable annotation提供的,
通过如@RequestMapping(value="/blog /{id}",method=RequestMethod.DELETE)即可处理/blog/1 的delete请求.

@PathVariabl:从路径里面去获取变量,也就是把路径当做变量。

 

例如该注解可以实现如下请求:

/userinfo  => index()
/userinfo/new => _new()
/userinfo/{id} => show()
/userinfo/{id}/edit  => edit()
/userinfo POST => create()     (直接提交POST请求)
/userinfo/{id} PUT => update()
/userinfo/{id} DELETE => delete()
/userinfo DELETE => batchDelete()

 

代码示例:

@Controller
 6@RequestMapping("/userinfo")
 7public class UserInfoController extends BaseSpringController{

/** 列表 */
23  @RequestMapping
24  public ModelAndView index(HttpServletRequest request,HttpServletResponse response,UserInfo userInfo) {
25  
31  }
32
33  /** 进入新增 */
34  @RequestMapping(value="/new")
35  public ModelAndView _new(HttpServletRequest request,HttpServletResponse response,UserInfo userInfo) throws Exception {
36  return new ModelAndView("/userinfo/new","userInfo",userInfo);
37  }
38
39  /** 显示 */
40  @RequestMapping(value="/{id}")
41  public ModelAndView show(@PathVariable Long id,HttpServletRequest request,HttpServletResponse response) throws Exception {
42  UserInfo userInfo = (UserInfo)userInfoManager.getById(id);
43  return new ModelAndView("/userinfo/show","userInfo",userInfo);
44  }
45
46  /** 编辑 */
47  @RequestMapping(value="/{id}/edit")
48  public ModelAndView edit(@PathVariable Long id,HttpServletRequest request,HttpServletResponse response) throws Exception {
49  UserInfo userInfo = (UserInfo)userInfoManager.getById(id);
50  return new ModelAndView("/userinfo/edit","userInfo",userInfo);
51  }

 

posted @ 2017-03-20 17:47  malcome  阅读(76)  评论(0)    收藏  举报