zoukankan      html  css  js  c++  java
  • 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 Request

    HTTP请求有五个主要部分:

    • Verb- 表示HTTP方法,如GET,POST,DELETE,PUT等

    • URI- 统一资源标识符(URI)来标识服务器上的资源

    • HTTP Version- 表示HTTP版本,例如HTTP1.1版。

    • Request Header- 包含元数据的HTTP请求消息作为键 - 值对。 例如,客户端(或浏览器)型,由客户端支持的格式,邮件正文的格式,缓存设置等。

    • Request Body- 消息内容或资源的表示。

    HTTP 响应

    HTTP Response

    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近发送按钮预览按钮,然后点击发送按钮,您可能会看到下面的输出。

    HTTP Request/Response

    在这里,你可以看到,浏览器发送一个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 boolean equals(Object object){
          if(object == null){
             return false;
          }else if(!(object instanceof User)){
             return false;
          }else {
             User user = (User)object;
             if(id == user.getId()
                && name.equals(user.getName())
                && profession.equals(user.getProfession())
             ){
                return true;
             }			
          }
          return false;
       }	
    }

    UserDao.java

    package com.yiibai;
    
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.ObjectInputStream;
    import java.io.ObjectOutputStream;
    import java.util.ArrayList;
    import java.util.List;
    
    public class UserDao {
       public List<User> getAllUsers(){
          List<User> userList = null;
          try {
             File file = new File("Users.dat");
             if (!file.exists()) {
                User user = new User(1, "Mahesh", "Teacher");
                userList = new ArrayList<User>();
                userList.add(user);
                saveUserList(userList);		
             }
             else{
                FileInputStream fis = new FileInputStream(file);
                ObjectInputStream ois = new ObjectInputStream(fis);
                userList = (List<User>) ois.readObject();
                ois.close();
             }
          } catch (IOException e) {
             e.printStackTrace();
          } catch (ClassNotFoundException e) {
             e.printStackTrace();
          }		
          return userList;
       }
    
       public User getUser(int id){
          List<User> users = getAllUsers();
    
          for(User user: users){
             if(user.getId() == id){
                return user;
             }
          }
          return null;
       }
    
       public int addUser(User pUser){
          List<User> userList = getAllUsers();
          boolean userExists = false;
          for(User user: userList){
             if(user.getId() == pUser.getId()){
                userExists = true;
                break;
             }
          }		
          if(!userExists){
             userList.add(pUser);
             saveUserList(userList);
             return 1;
          }
          return 0;
       }
    
       public int updateUser(User pUser){
          List<User> userList = getAllUsers();
    
          for(User user: userList){
             if(user.getId() == pUser.getId()){
                int index = userList.indexOf(user);			
                userList.set(index, pUser);
                saveUserList(userList);
                return 1;
             }
          }		
          return 0;
       }
    
       public int deleteUser(int id){
          List<User> userList = getAllUsers();
    
          for(User user: userList){
             if(user.getId() == id){
                int index = userList.indexOf(user);			
                userList.remove(index);
                saveUserList(userList);return1;}}return0;}privatevoid saveUserList(List<User> userList){try{File file =newFile("Users.dat");FileOutputStream fos;
    
             fos =newFileOutputStream(file);ObjectOutputStream oos =newObjectOutputStream(fos);		
             oos.writeObject(userList);
             oos.close();}catch(FileNotFoundException e){
             e.printStackTrace();}catch(IOException e){
             e.printStackTrace();}}}

    UserService.java

    package com.yiibai;
    
    import java.io.IOException;
    import java.util.List;
    
    import javax.servlet.http.HttpServletResponse;
    import javax.ws.rs.Consumes;
    import javax.ws.rs.DELETE;
    import javax.ws.rs.FormParam;
    import javax.ws.rs.GET;
    import javax.ws.rs.OPTIONS;
    import javax.ws.rs.POST;
    import javax.ws.rs.PUT;
    import javax.ws.rs.Path;
    import javax.ws.rs.PathParam;
    import javax.ws.rs.Produces;
    import javax.ws.rs.core.Context;
    import javax.ws.rs.core.MediaType;
    
    @Path("/UserService")
    public class UserService {
    	
       UserDao userDao = new UserDao();
       private static final String SUCCESS_RESULT="<result>success</result>";
       private static final String FAILURE_RESULT="<result>failure</result>";
    
    
       @GET
       @Path("/users")
       @Produces(MediaType.APPLICATION_XML)
       public List<User> getUsers(){
          return userDao.getAllUsers();
       }
    
       @GET
       @Path("/users/{userid}")
       @Produces(MediaType.APPLICATION_XML)
       public User getUser(@PathParam("userid") int userid){
          return userDao.getUser(userid);
       }
    
       @PUT
       @Path("/users")
       @Produces(MediaType.APPLICATION_XML)
       @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
       public String createUser(@FormParam("id") int id,
          @FormParam("name") String name,
          @FormParam("profession") String profession,
          @Context HttpServletResponse servletResponse) throws IOException{
          User user = new User(id, name, profession);
          int result = userDao.addUser(user);
          if(result == 1){
             return SUCCESS_RESULT;
          }
          return FAILURE_RESULT;
       }
    
       @POST
       @Path("/users")
       @Produces(MediaType.APPLICATION_XML)
       @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
       public String updateUser(@FormParam("id") int id,
          @FormParam("name") String name,
          @FormParam("profession") String profession,
          @Context HttpServletResponse servletResponse) throws IOException{
          User user = new User(id, name, profession);
          int result = userDao.updateUser(user);
          if(result == 1){
             return SUCCESS_RESULT;
          }
          return FAILURE_RESULT;
       }
    
       @DELETE
       @Path("/users/{userid}")
       @Produces(MediaType.APPLICATION_XML)
       public String deleteUser(@PathParam("userid")int userid){int result = userDao.deleteUser(userid);if(result ==1){return SUCCESS_RESULT;}return FAILURE_RESULT;}@OPTIONS@Path("/users")@Produces(MediaType.APPLICATION_XML)publicString getSupportedOperations(){return"<operations>GET, PUT, POST, DELETE</operations>";}}

    现在使用Eclipse,导出应用程序为war文件,并部署在Tomcat中。要使用eclipse创建WAR文件,按照选项 File -> export -> Web > War File 最后选择项目UserManagement和目标文件夹。 要将WAR文件部署在Tomcat,将UserManagement.war文件放置在Tomcat的安装目录下 > webapps 目录并启动Tomcat。

    测试Web服务

    Jersey提供的API来创建Web服务客户端并测试Web服务。我们已经创建了一个示例测试类 WebServiceTester.java 在com.yiibai下在的同一个项目中。

    WebServiceTester.java

    package com.yiibai;
    
    import java.util.List;
    
    import javax.ws.rs.client.Client;
    import javax.ws.rs.client.ClientBuilder;
    import javax.ws.rs.client.Entity;
    import javax.ws.rs.core.Form;
    import javax.ws.rs.core.GenericType;
    import javax.ws.rs.core.MediaType;
    
    public class WebServiceTester  {
    
       private Client client;
       private String REST_SERVICE_URL = "http://localhost:8080/UserManagement/rest/UserService/users";
       private static final String SUCCESS_RESULT="<result>success</result>";
       private static final String PASS = "pass";
       private static final String FAIL = "fail";
    
       private void init(){
          this.client = ClientBuilder.newClient();
       }
    
       public static void main(String[] args){
          WebServiceTester tester = new WebServiceTester();
          //initialize the tester
          tester.init();
          //test get all users Web Service Method
          tester.testGetAllUsers();
          //test get user Web Service Method 
          tester.testGetUser();
          //test update user Web Service Method
          tester.testUpdateUser();
          //test add user Web Service Method
          tester.testAddUser();
          //test delete user Web Service Method
          tester.testDeleteUser();
       }
       //Test: Get list of all users
       //Test: Check if list is not empty
       private void testGetAllUsers(){
          GenericType<List<User>> list = new GenericType<List<User>>() {};
          List<User> users = client
             .target(REST_SERVICE_URL)
             .request(MediaType.APPLICATION_XML)
             .get(list);
          String result = PASS;
          if(users.isEmpty()){
             result = FAIL;
          }
          System.out.println("Test case name: testGetAllUsers, Result: " + result );
       }
       //Test: Get User of id 1
       //Test: Check if user is same as sample user
       private void testGetUser(){
          User sampleUser = new User();
          sampleUser.setId(1);
    
          User user = client
             .target(REST_SERVICE_URL)
             .path("/{userid}")
             .resolveTemplate("userid", 1)
             .request(MediaType.APPLICATION_XML)
             .get(User.class);
          String result = FAIL;
          if(sampleUser != null && sampleUser.getId() == user.getId()){
             result = PASS;
          }
          System.out.println("Test case name: testGetUser, Result: " + result );
       }
       //Test: Update User of id 1
       //Test: Check if result is success XML.
       private void testUpdateUser(){
          Form form = new Form();
          form.param("id", "1");
          form.param("name", "suresh");
          form.param("profession", "clerk");
    
          String callResult = client
             .target(REST_SERVICE_URL)
             .request(MediaType.APPLICATION_XML)
             .post(Entity.entity(form,
                MediaType.APPLICATION_FORM_URLENCODED_TYPE),
                String.class);
          String result = PASS;if(!SUCCESS_RESULT.equals(callResult)){
             result = FAIL;}System.out.println("Test case name: testUpdateUser, Result: "+ result );}//Test: Add User of id 2//Test: Check if result is success XML.privatevoid testAddUser(){Form form =newForm();
          form.param("id","2");
          form.param("name","naresh");
          form.param("profession","clerk");String callResult = client
             .target(REST_SERVICE_URL).request(MediaType.APPLICATION_XML).put(Entity.entity(form,MediaType.APPLICATION_FORM_URLENCODED_TYPE),String.class);String result = PASS;if(!SUCCESS_RESULT.equals(callResult)){
             result = FAIL;}System.out.println("Test case name: testAddUser, Result: "+ result );}//Test: Delete User of id 2//Test: Check if result is success XML.privatevoid testDeleteUser(){String callResult = client
             .target(REST_SERVICE_URL).path("/{userid}").resolveTemplate("userid",2).request(MediaType.APPLICATION_XML).delete(String.class);String result = PASS;if(!SUCCESS_RESULT.equals(callResult)){
             result = FAIL;}System.out.println("Test case name: testDeleteUser, Result: "+ result );}}

    现在运行测试,使用Eclipse。右键单击该文件,并按照选项Run as -> Java Application. 你会看到下面的结果Eclipse控制台:

    Test case name: testGetAllUsers, Result: pass
    Test case name: testGetUser, Result: pass
    Test case name: testUpdateUser, Result: pass
    Test case name: testAddUser, Result: pass
    Test case name: testDeleteUser, Result: pass
    http://localhost:8080/UserManagement/rest/UserService/getUser/1

    以下是良好的URL的一个例子来获取的用户。

    http://localhost:8080/UserManagement/rest/UserService/users/1
  • 相关阅读:
    树莓派debian配置lamp[解决Apache不显示php网页]
    centos7 mysql数据库安装和配置
    Linux学习之CentOS(十三)--CentOS6.4下Mysql数据库的安装与配置
    Linux从git上下东西
    在Debian/Ubuntu上面安装升级nginx到最新版
    今天做一个项目的时候,要在一个编辑的jsp页面的textarea标签设置value属性,结果发现他没有value属性,但是是编辑页面又必须要回显要修改的内容,所以在参考了w3cschool之后很轻松的解决了这个问题。
    JavaScript 弹出框:警告(alert)、确认(confirm)的简单写法
    sql 语句实现可用户名、邮箱、手机号登录系统
    留言功能问题
    手机访问pc版网站自动跳转为手机版页面
  • 原文地址:https://www.cnblogs.com/xinfang520/p/7722587.html
Copyright © 2011-2022 走看看