RESTful记录-RESTful内容
什么是资源?
REST架构对待每一个内容都作为一种资源。这些资源可以是文本文件,HTML网页,图片,视频或动态业务数据。 REST服务器只是提供资源,REST客户端可访问和修改的资源。这里每个资源由URI标识/全局标识。 REST采用各种交涉代表的资源如文本,JSON,XML。 XML和JSON是资源的最流行的表示。
资源表示
在REST资源是在面向对象编程或数据库类似于实体类似的对象。一旦资源被标识则其表示是用一个标准的格式来决定,以便服务器可以发送资源上文所述的格式和客户端可以理解的格式。
例如,在REST Web服务 - 第一个应用教程,用户是使用下面的XML格式表示资源:
<user>
<id>1</id>
<name>Mahesh</name>
<profession>Teacher</profession>
</user>
同样的资源也可以使用JSON格式表示如下:
{
"id":1,
"name":"Mahesh",
"profession":"Teacher"
}
好的资源表示
REST并没有对资源表示格式有任何限制。客户端可以请求JSON表示,其中作为另一种客户端可能会要求同一资源的XML表示到服务器等。它是REST服务器的负责传递客户端的资源到客户端可以理解的格式。
以下是在设计资源的表示形式在一个RESTful Web服务要考虑的重要因素。
-
易懂: 服务器和客户端应能够理解和使用的资源的表示格式。
-
完整: 格式应当能够完全代表一个资源。例如,一个资源可以包含其他资源。格式应该能够代表简单以及资源的复杂的结构。
-
可链接: 资源可以有一个联动到另一个资源,一个格式应当能够处理这种情况。
然而,目前大多数的Web服务使用XML或JSON格式代表的资源。有很多可用的理解,分析,并修改XML和JSON数据库和工具。
RESTful web services使用HTTP协议的客户端和服务器之间的通信媒介。 一个客户在一个HTTP响应形式的HTTP请求和服务器响应的形式发送消息。这种技术被称为消息。这些消息包含的信息数据和元数据,即有关消息本身的信息。让我们一起来看看在HTTP请求和HTTP响应消息HTTP1.1。
HTTP 请求
HTTP请求有五个主要部分:
-
Verb- 表示HTTP方法,如GET,POST,DELETE,PUT等
-
URI- 统一资源标识符(URI)来标识服务器上的资源
-
HTTP Version- 表示HTTP版本,例如HTTP1.1版。
-
Request Header- 包含元数据的HTTP请求消息作为键 - 值对。 例如,客户端(或浏览器)型,由客户端支持的格式,邮件正文的格式,缓存设置等。
-
Request Body- 消息内容或资源的表示。
HTTP 响应
HTTP响应有四个主要部分:
-
Status/Response Code - 表示对所请求的资源服务器状态。例如404表示未找到资源,200表示响应正常。
-
HTTP Version- 表示HTTP版本,例如HTTP1.1版。
-
Response Header- 包含元数据的HTTP响应消息作为键 - 值对。 例如,内容长度,内容类型,响应时间,服务器类型等
-
Response Body- 响应消息的内容或资源表示。
例子
正如我们在已经解释 RESTful Web服务第一个应用教程, 让我们把 http://localhost:8080/UserManagement/rest/UserService/users 在POSTMAN使用GET请求。如果你点击Postman近发送按钮预览按钮,然后点击发送按钮,您可能会看到下面的输出。
在这里,你可以看到,浏览器发送一个GET请求,并得到了响应的内容主体作为XML。
地址是指查找资源或多个资源位于服务器上。它类似于定位的人的邮寄地址。
REST架构中的每个资源都由其URI,统一资源标识符。 URI是以下格式:
<protocol>://<service-name>/<ResourceType>/<ResourceID>
一个URI的目的是要找到承载Web服务的服务器上的资源。请求的另一个重要属性是动词,标识要在资源上执行的操作。例如,在REST Web服 第一应用教程, URI 就是http://localhost:8080/UserManagement/rest/UserService/users 和动词是GET。
构建一个标准的URI
以下是要考虑在设计一个URI要点:
-
使用复数名词 - 使用复数名词来定义的资源。例如,我们已经使用的用户识别用户的资源。
-
避免使用空格 - 利用下划线(_)或连字符( - ),使用一个长的资源的名称,例如,使用authorized_users代替authorized%20users。
-
使用小写字母 - 虽然URI是区分大小写,这是很好的做法,以保持网址只有小写字母。
-
保持向后兼容 - 由于Web服务是一种公共服务,URI一旦做出公开应始终可用。在某些情况下URI更新,使用HTTP状态码,300表示旧的URI重定向到新的URI。
-
使用HTTP动词 - 始终使用HTTP动词像GET,PUT和DELETE做业务上的资源。这是不好用操作名字URI。
例子
下面是一个URI的例子来获取的用户。
正如我们讨论至今认为RESTful web服务使得重用HTTP动词,以确定要执行所指定的资源(多个)的操作。 下表使用HTTP动词常用状态的例子。
S.N. | HTTP方法,URI和操作 |
---|---|
1 | GET http://localhost:8080/UserManagement/rest/UserService/users 获取用户列表 (只读) |
2 | GET http://localhost:8080/UserManagement/rest/UserService/users/1 获取ID为1的用户 (只读) |
3 | PUT http://localhost:8080/UserManagement/rest/UserService/users/2 使用ID为2插入用户 (等幂) |
4 | POST http://localhost:8080/UserManagement/rest/UserService/users/2 更新ID为2的用户 (N/A) |
5 | DELETE http://localhost:8080/UserManagement/rest/UserService/users/1 删除ID为2用户 (等幂) |
6 | OPTIONS http://localhost:8080/UserManagement/rest/UserService/users 列出Web服务支持的操作 (只读) |
7 | HEAD http://localhost:8080/UserManagement/rest/UserService/users 仅返回HTTP头,没有主体。 (只读) |
下面是要考虑的重要问题:
-
GET 仅是读操作并且是安全的。
-
PUT 和 DELETE 操作幂等意味着他们的结果总是相同的,无论多少次,这些操作可被调用。
-
PUT 和 POST 动作几乎相同,区别仅位于在结果其中PUT操作是等幂,POST操作可能导致不同的结果。
例子
让我们来更新RESTful Web服务创建示例 - 第一应用教程创建Web服务它可以执行CRUD(创建,读取,更新,删除)操作。为简单起见,这里使用了一个文件I/O,以取代数据库操作。
现在更新User.java,UserDao.java和UserService.java文件在com.yiibai包下。
User.java
package com.yiibai;
import java.io.Serializable;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement(name = "user")
public class User implements Serializable {
private static final long serialVersionUID = 1L;
private int id;
private String name;
private String profession;
public User(){}
public User(int id, String name, String profession){
this.id = id;
this.name = name;
this.profession = profession;
}
public int getId() {
return id;
}
@XmlElement
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
@XmlElement
public void setName(String name) {
this.name = name;
}
public String getProfession() {
return profession;
}
@XmlElement
public void setProfession(String profession) {
this.profession = profession;
}
@Override
public