RESTful

Posted 57容杰龙

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了RESTful相关的知识,希望对你有一定的参考价值。

1.RESTful简介("<资源>表现层状态转化")

  REST(英文:Representational State Transfer,简称REST)描述了一个架构样式的网络系统,REST 指的是一组架构约束条件和原则。满足这些约束条件和原则的应用程序或设计就是 RESTful。RESTful是一种软件架构风格,设计风格而不是标准,只是提供了一组设计原则和约束条件。

Server提供的RESTful API中,URL中只使用名词来指定资源,原则上不使用动词。“资源”是REST架构或者说整个网络处理的核心。

  (1)每一个URI代表一种资源;
  (2)客户端和服务器之间,传递这种资源的某种表现层;
  (3)客户端通过四个HTTP动词,对服务器端资源进行操作,实现"表现层状态转化"。

URL定位资源,用HTTP动词(GET,POST,DELETE,PUT)描述操作

2. RESTful规范

A.定位资源的url风格

  名词来指定资源,原则上不使用动词

  URI使用名词而不是动词,且推荐用复数

  例如:http://localhost:8080/users/123

B.对资源进行操作

采用HTTP GET、POST、PUT、DELETE进行增删查改

3. spring对RESTFUL支持(spring-mvc)

  利用@RequestMapping 指定要处理请求的URI模板和HTTP请求的动作类型

     利用@PathVariable讲URI请求模板中的变量映射到处理方法参数上

  利用Ajax,在客户端发出HTTP动词(GET,POST,DELETE,PUT)动作的请求

@PathVariable 和 @RequestParam 的区别在于:  

@PathVariable 的 url:/my/user/zhangsan/18

@RequestParam 的 url:/my/user?nickname=zhangsan&age=18   

例如:

@RequestMapping("/user/{nickname}/{age}");   

  public String getUserInfo(@PathVariable("nickname") String name, @PathVariable int age) {...}   

A.RESTful对静态资源的处理

采用RESTful架构后,需要将web.xml中控制器拦截的请求设置为/,这样会将css,js等静态资源进行拦截,发送404错误。

  <servlet>
      <servlet-name>springmvc</servlet-name>
      <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
      <init-param>
          <param-name>contextConfigLocation</param-name>
          <param-value>classpath:application.xml</param-value>
      </init-param>
  </servlet>
  <servlet-mapping>
      <servlet-name>springmvc</servlet-name>
      <url-pattern>/</url-pattern>
  </servlet-mapping>

解决方法:

<mvc:resources mapping="请求URI" location="资源位置" />

<!-- 配置解决restful风格下的过滤器把静态资源当请求来处理的问题 
        location:服务器的真实路径配置
        mapping: 匹配jsp请求上面的地址路径
        **:表示匹配当前路径下和子路径下的所有文件资源
    -->
    <mvc:resources location="/js/" mapping="/js/**"></mvc:resources>
    <!-- 配置css和图片等映射 -->
    <mvc:resources location="/css/" mapping="/css/**"></mvc:resources>
    <mvc:resources location="/image/" mapping="/image/**"></mvc:resources>

B.Restful地址栏传值中文乱码问题解决

页面: url:encodeURI(encodeURI(\'${basePath}/users/123\')

后台: URLDecoder.decode(name)

 1 <%@ page language="java" contentType="text/html; charset=UTF-8"
 2     pageEncoding="UTF-8"%>
 3 <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
 4 <c:set var="basePath" value="${pageContext.request.contextPath }"></c:set>
 5 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
 6 <html>
 7 <head>
 8 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
 9 <title>Insert title here</title>
10 <script type="text/javascript" src="${basePath }/js/jquery-1.8.3.js"></script>
11 </head>
12 <body>
13     
14         <input id="name" type="text" name="name">
15         <input id="age" type="number" name="age">
16         
17         <input id="submit" type="button" value="提交">
18 <script type="text/javascript">
19 
20     $(function(){
21         $("#submit").click(function(){
22             var name=$("#name").val();
23             var age=$("#age").val();
24             alert(name+age);
25             $.ajax({
26                 url:encodeURI(encodeURI("${basePath}/rjl/person/"+name+"/"+age)),
27                 type:"GET",
28                 dataType:"json",
29                 success:function(data){
30                     
31                     alert(data.age+data.name);
32                     alert(data.name);
33                 },
34                 error:function(data){
35                     alert(data);
36                     console.log("error"+data);
37                 },
38                 timeout:3000
39             }
40                 
41             );
42         });
43         
44     });
45 </script>
46     
47 </body>
48 </html>
 1 package com.rong.controller;
 2 
 3 import java.io.UnsupportedEncodingException;
 4 import java.net.URLDecoder;
 5 
 6 import org.springframework.stereotype.Controller;
 7 import org.springframework.web.bind.annotation.PathVariable;
 8 import org.springframework.web.bind.annotation.RequestMapping;
 9 import org.springframework.web.bind.annotation.RequestMethod;
10 import org.springframework.web.bind.annotation.ResponseBody;
11 
12 import com.rong.entity.Person;
13 
14 @Controller
15 @RequestMapping("/rjl")
16 public class PersonController {
17     @RequestMapping(value="/restful")
18     public String login(){
19         System.out.println("login");
20         return "login";
21     }
22     
23     @RequestMapping(value="/person/{name}/{age}",method=RequestMethod.GET)
24     @ResponseBody
25     public Person welcome(@PathVariable("name")String myName,@PathVariable("age")Integer myAge){
26         /*myName=URLDecoder.decode(myName);
27         System.out.println(myName);*/
28         try {
29             myName=URLDecoder.decode(myName, "UTF-8");
30             System.out.println(myName);
31             
32         } catch (UnsupportedEncodingException e) {
33             e.printStackTrace();
34         }
35         Person person=new Person(myName, myAge);
36         System.out.println(person);
37         return person;
38     }
39 }

4.springmvc通过json传值到后台

注意:使用AJAX时传递json数据要添加jackson-databind依赖包2.8.1

<!-- 以json字符串方式传递参数到后台 -->

通过传递JSON字符串到后台

a.将数据处理成JSON字符串

b.ajax的contentType和dataType设置json格式

c.后台Controller接收处理 需要添加@RequestBody注解

 1     $(function(){
 2         $("#submit").click(function(){
 3             var name=$("#name").val();
 4             var age=$("#age").val();
 5             //该json的key需要与后台的bean的属性名对应   创建json对象
 6             var json={"name":name,"age":age};
 7             var postData=JSON.stringify(json);//将json对象转换成json字符串传递到后台
 8             alert(name+age);
 9             $.ajax({
10                 url:"${basePath}/rjl/persons",
11                 data:postData,
12                 type:"POST",
13                 dataType:"json",//后台返回响应类型
14                 contentType:"application/json",//修改传值方式为json字符串
15                 success:function(data){
16                     
17                     alert(data.age+data.name);
18                     alert(data.name);
19                 },
20                 error:function(data){
21                     alert(data);
22                     console.log("error"+data);
23                 },
24                 timeout:3000
25             }
26                 
27             );
28         });
29         
30     });
 1     /**
 2      * 接收页面传递json格式,后台处理方式:
 3      * 1.接收参数必须是对象模型
 4      * 2.参数上添加@RequestBody注解,springmvc会自动调用json包,将json字符串的信息封装到bean对象上
 5      * 3.需要导入json包
 6      * 
 7      * @ResponseBody  springmvc 会自动的将该bean转成json数据返回给ajax
 8      *
 9      */
10     @RequestMapping(value="/persons",method=RequestMethod.POST)
11     @ResponseBody
12     public Person main(@RequestBody Person person){
13         System.out.println(person);
14         return person;
15     }

通过请求参数方式name=xxx&pwd=xxx方式传递一:

 1 $("#submit").click(function(){
 2             var name=$("#name").val();
 3             var age=$("#age").val();
 4             alert(name+age);
 5             $.ajax({
 6                 url:"${basePath}/rjl/persons",
 7                 data:{name:name,age:age},
 8                 type:"POST",
 9                 dataType:"json",//后台返回响应类型
10                 success:function(data){
11                     
12                     alert(data.age+data.name);
13                     alert(data.name);
14                 },
15                 error:function(data){
16                     alert(data);
17                     console.log("error"+data);
18                 },
19                 timeout:3000
20             }
21                 
22             );
23         });
    @RequestMapping(value="/persons",method=RequestMethod.POST)
    @ResponseBody
    public Person main(Person person){
        System.out.println(person);
        return person;
    }

通过请求参数方式name=xxx&pwd=xxx方式传递二:(jQuery给我们提供的$(“#login”).serialize()序列化表单

项目中字段还是特别多的,这样JS端拼接会相当繁琐,jq有个方法供我们使用:serialize()

var params=$("#login").serialize();//将所有子元素中的表单元素序列化成字符串格式

    <fieldset id="login" style="width: 600px;border:1px solid #000">
        <legend>用户注册</legend>
        <input id="name" type="text" name="name">
        <input id="age" type="number" name="age">
        
        <input id="submit" type="button" value="提交">
    </fieldset>
<script type="text/javascript">

    $(function(){
        $("#submit").click(function(){
            var params=$("#login").serialize();//将所有子元素中的表单元素序列化成字符串格式
            alert(params);
            $.ajax({
                url:"${basePath}/rjl/persons",
                data:params,
                type:"POST",
                dataType:"json",//后台返回响应类型
                success:function(data){
                    
                    alert(data.msg);
                },
                error:function(data){
                    alert(data.msg);
                    console.log("error"+data);
                },
                timeout:3000
            }
                
            );
        });
        
    });
</script>
 1     @RequestMapping(value="/persons",method=RequestMethod.POST)
 2     @ResponseBody
 3     public Map<String,Object> main(Person person){
 4         System.out.println(person);
 5         Map<String,Object> map=null;
 6         if("rjl".equals(person.getName())&&60==person.getAge()){
 7             map=new HashMap<>();
 8             map.put("msg", person.getName());
 9         }else{
10             map=new HashMap<>();
11             map.put("msg", "www");
12         }
13         return map;
14     }

 

@responseBody注解返回json 乱码问题

解决:@RequestMapping(value="/persons",method=RequestMethod.POST,produces="application/json;charset=utf-8")

 1     /**
 2      * produces="application/json;charset=utf-8" 解决json传值乱码问题
 3      */
 4     @RequestMapping(value="/persons",method=RequestMethod.POST,produces="application/json;charset=utf-8")
 5     @ResponseBody
 6     public Map<String,Object> main(Person person){
 7         System.out.println(person);
 8         Map<String,Object> map=new HashMap<>();
 9         if("rjl".equals(person.getName())&&60==person.getAge()){
10             map.put("msg", person.getName());
11         }else{
12             map.put("msg", "NO错"+person.getName());
13         }
14         return map;
15     }
$("#submit").click(function(){
            var params=$("#login").serialize();//将所有子元素中的表单元素序列化成字符串格式
            alert(params);
            $.ajax({
                url:"${basePath}/rjl/persons",
                data:params,
                type:"POST",
                dataType:"json",//后台返回响应类型
                success:function(data){
                    alert(data.msg);
                },
                error:function(data){
                    alert(data.msg);
                    console.log("error"+data);
                },
                timeout:3000
            }
                
            );
        });

 

以上是关于RESTful的主要内容,如果未能解决你的问题,请参考以下文章

Spring Boot 中 10 行代码构建 RESTful 风格应用

有没有办法为 RESTful 堆栈生成样板代码?

restful 架构风格的curd(增删改查)

处理 Restful 服务

使用 WCF 客户端访问 RESTful 服务时访问 HTTP 状态代码

通俗易懂的RESTful API实践详解(含代码)