Restful风格的应用

129 阅读3分钟

RESTful基本使用方法

传统Web应用的问题

REST与RESTful

  • REST-表现层状态转换(理念),资源在网络中以某种表现形式进行状态转移(在web环境下获取img,html,js就需要以URL的形式进行展现)
  • RESTful是基于REST理念的一套开发风格,是具体的开发规则(服务器端只返回数据,返回数据要求不包含于展现相关的内容)

RESTful传输数据

RESTful开发风格

  • 使用URL作为用户交互入口
  • 明确的语义规范(GET|POST|PUT|DELETE)(查询|新增|更新|删除)
  • 只返回数据(JSON|XML),不包含任何展现

RESTful命名要求

URI说明修改建议
GET /articles?au=lily正确用法
GET /a/1URI必须具有语义GET /student/1
POST /createArticle/1URI必须使用名词POST /article/1
GET /articles/author/1URI扁平化,不超两级GET /articles/author?id=1
DELETE /articles/1URI名词区分单复数GET /articles?au=lily&DELETE /article/1

开发RESTful Web应用

@Controller
@RequestMapping("/restful")
public class RestfunConroller {
    @GetMapping("/request")
    @ResponseBody
    public String doGetRequest(){
        return "{\"message\":\"返回查询结果\"}";
    }

    @PostMapping("/request")
    @ResponseBody
    public String doPostRequest(){
        return "{\"message\":\"数据新建成功\"}";
    }
    @PutMapping("/request")
    @ResponseBody
    public String doPutRequest(){
        return "{\"message\":\"数据更新成功\"}";
    }
    @DeleteMapping("/request")
    @ResponseBody
    public String doDeleteRequest(){
        return "{\"message\":\"数据删除成功\"}";
    }
}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>RESTful实验室</title>
    <script src="https://afterglow.fun/jquery/jquery-3.4.1.min.js"></script>
    <script>
        $(function () {
            $("#btnGet").click(function () {
                $.ajax({
                    url: "/restful/request",
                    type: "get",
                    dataType: "json",
                    success : function (json) {
                        $("#messages").add(json.message);
                        $("#message").text(json.message);
                    }
                })
            })
        })
        $(function () {
            $("#btnPost").click(function () {
                $.ajax({
                    url: "/restful/request",
                    type: "post",
                    dataType: "json",
                    success : function (json) {
                        $("#messages").add(json.message);
                        $("#message").text(json.message);
                    }
                })
            })
        })
        $(function () {
            $("#btnPut").click(function () {
                $.ajax({
                    url: "/restful/request",
                    type: "put",
                    dataType: "json",
                    success : function (json) {
                        $("#messages").add(json.message);
                        $("#message").text(json.message);
                    }
                })
            })
        })
        $(function () {
            $("#btnDelete").click(function () {
                $.ajax({
                    url: "/restful/request",
                    type: "delete",
                    dataType: "json",
                    success : function (json) {
                        $("#messages").add(json.message);
                        $("#message").text(json.message);
                    }
                })
            })
        })
    </script>
</head>
<body>
<input type="button" id="btnGet" value="发送Get请求">
<input type="button" id="btnPost" value="发送Post请求">
<input type="button" id="btnPut" value="发送Put请求">
<input type="button" id="btnDelete" value="发送Delete请求">
<h1 id="message"></h1>
<h1 id="messages"></h1>
</body>
</html>

RestController注解与路径变量

//  POST /restful/1
//  POST /restful/100
@PostMapping("/request/{rid}")
//    @ResponseBody
public String doPostRequest(@PathVariable("rid") Integer requestId){
    return "{\"message\":\"数据新建成功\",\"id\":"+requestId+"}";
}

简单请求与非简单请求

  • 简单请求是指标准结构的HTTP请求,对应GET/POST请求
  • 非简单请求是复杂要求的HTTP请求,指PUT/DELETE、扩展标准请求
  • 两者最大区别是非简单请求发送前需要发送预检请求

非简单请求

需要在web.xml中配置参数过滤器

<filter>
    <filter-name>formContentFilter</filter-name>
    <filter-class>org.springframework.web.filter.FormContentFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>formContentFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
//put型复合请求
@GetMapping("/persons")
public List<Person> findByPerson(){
    List list = new ArrayList();
    Person person1 = new Person();
    person1.setName("张三");
    person1.setAge(100);
    person1.setBirthady(new Date());
    Person person2 = new Person();
    person2.setName("李四");
    person2.setAge(101);
    person2.setBirthady(new Date());

    list.add(person1);
    list.add(person2);
    return list;
}
public class Person {
    private String name;
    private Integer age;
	//对时间进行格式化操作,调整时区
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
    private Date birthady;

JSON序列化

//在pom.xml配置文件中配置jackson的相关依赖,版本一定要选择2.9以后的,在使用过程中,springmvc会自动将实体类对象转换为json数据格式返回
<dependency>
//核心包
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-core</artifactId>
    <version>2.9.9</version>
</dependency>
<dependency>
//数据绑定
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.9.9</version>
</dependency>
<dependency>
//json注解
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-annotations</artifactId>
    <version>2.9.9</version>
</dependency>

跨域问题

浏览器的同源策略

  • 同源策略阻止从一个域加载的脚本去获取另一个域上的资源(ajax只能获取同网站、同域名下的资源,不能访问跨域名下的资源)
  • 只要协议、域名、端口有任何一个不同, 都被当作是不同的域
  • 浏览器Console看到Access-Control-Allow-Origin就代表跨域了
源URL目标URL直接访问?
imooc.comxxx.com:8080/test不能
imooc.comimooc.com不能
imooc.comabc.imooc.com不能
imooc.comimooc.com:8080不能
http://localhosthttp://127.0.0.1不能
imooc.comimooc.com/user/test可以

HTML中允许跨域的标签

< img> - 显示远程图片 < script> - 加载远程js < link> - 加载远程csss

CORS跨域资源访问

  • CORS是一-种机制使用额外的HTTP头通知浏览器可以访问其他域
  • URL响应头包含Access-Control-*指明请求允许跨域

Spring MVC解决跨域访问

  • @CrossOrigin - Controller跨域注解(局部注解,只在当前Controller中生效)
  • mvc:cors - Spring MVC全局跨域配置
//@CrossOrigin(origins={"http://localhost:8080", "http://wWw.afterglow.fun"})
@CrossOrigin(origins = "*",maxAge = 3600)

CORS全局配置

  • 在applicationContext.xml中配置
<mvc:cors>
    <!--  对应当前应用的URI地址  -->
    <!--  path="/restful/**":只要是远程域名访问到了restful为前缀的URI上都会对这个策略管理  -->
    <mvc:mapping path="/restful/**" allowed-origins="http://localhost:8080,http://afterglow.fun" max-age="3600"/>
</mvc:cors>