RESTful开发风格

RESTful开发风格

REST与RESTful

  • REST(Representational State Transfer)-表现层状态转换,资源在网络中以某种表现形式进行状态转移
  • 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应用

RestfulController.java

package com.imooc.restful.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

/**
 * @author Rex
 * @create 2021-01-12 12:00
 */
@Controller
@RequestMapping("/restful")
public class RestfulController {
    @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\":\"数据删除成功\"}";
    }

}


client.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>RESTful实验室</title>
    <script src="./jquery-3.5.1.min.js"></script>
    <script>
        $(function () {
            $("#btnGet").click(function () {
                $.ajax({
                    "url":"/restful/request",
                    "type":"get",
                    "dataType":"json",
                    "success": function (json) {
                        $("#message").text(json.message);
                    }
                })
            });
            $("#btnPost").click(function () {
                $.ajax({
                    "url":"/restful/request",
                    "type":"post",
                    "dataType":"json",
                    "success": function (json) {
                        $("#message").text(json.message);
                    }
                })
            });
            $("#btnPut").click(function () {
                $.ajax({
                    "url":"/restful/request",
                    "type":"put",
                    "dataType":"json",
                    "success": function (json) {
                        $("#message").text(json.message);
                    }
                })
            });
            $("#btnDelete").click(function () {
                $.ajax({
                    "url":"/restful/request",
                    "type":"delete",
                    "dataType":"json",
                    "success": function (json) {
                        $("#message").text(json.message);
                    }
                })
            });
        })
    </script>
</head>
<body>
    <input type="button" value="发送Get请求" id="btnGet"/>
    <input type="button" value="发送Post请求" id="btnPost"/>
    <input type="button" value="发送Put请求" id="btnPut"/>
    <input type="button" value="发送Delete请求" id="btnDelete"/>

    <h1 id="message"></h1>
</body>
</html>

结果:

在这里插入图片描述

为了解决json乱码问题需要在applicationContext对MediaTypes进行处理

<mvc:annotation-driven>
    <mvc:message-converters>
        <bean class="org.springframework.http.converter.StringHttpMessageConverter">
            <property name="supportedMediaTypes">
                <list>
                    <value>text/html; charset=utf-8</value>
                    <value>application/json; charset=utf-8</value>
                </list>
            </property>
        </bean>
    </mvc:message-converters>
</mvc:annotation-driven>

RestController注解

@RestController = @ResposneBody + @Controller, 默认将String向请求中输出,而不是将请求转发到该路径下

路径变量(@PathVariable)

路径变量:存放在URI中可变的数值

代码示例:

RestfulController.java

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

client.html

$("#btnPost").click(function () {
    $.ajax({
        "url":"/restful/request/100",
        "type":"post",
        "dataType":"json",
        "success": function (json) {
            $("#message").text(json.message + ":"+json.id);
        }
    })
});

结果:

在这里插入图片描述

简单请求和非简单请求

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

非简单请求

在这里插入图片描述

非简单请求中参数传递

需要配置FormContentFilter过滤器

代码示例:

web.xml

<filter>
    <filter-name>formContent</filter-name>
    <filter-class>org.springframework.web.filter.FormContentFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>formContent</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

RestfulController.java

@PutMapping("/request")
public String doPutRequest(Person person){
    System.out.println(person.getName()+":"+person.getAge());
    return "{\"message\":\"数据更新成功\"}";
}

client.html

$("#btnPut").click(function () {
    $.ajax({
        "url":"/restful/request",
        "type":"put",
        "dataType":"json",
        "data":"name=lily&age=23",
        "success": function (json) {
            $("#message").text(json.message);
        }
    })
});

结果:

在这里插入图片描述

JSON序列化

  • 引入jackson-core -> jack核心包
  • 引入jackson-databind->用于jackson与目标对象交互
  • 引入jackson-annotations用于jackson的注解

tip:日期类型、数字类型、货币类型的处理需要加上@JsonFormat注解,如@JsonFormat(pattern="", timezone=“GMT+8”)

使用示例:

RestController.java

@GetMapping("/persons")
public List<Person> findPersons(){
    List list = new ArrayList();
    Person p1 = new Person();
    p1.setName("lily");
    p1.setAge(23);
    p1.setBirthday(new Date());
    Person p2 = new Person();
    p2.setName("smith");
    p2.setAge(22);
    p2.setBirthday(new Date());
    list.add(p1);
    list.add(p2);
    return list;
}

Person.java

package com.imooc.restful.entity;

import com.fasterxml.jackson.annotation.JsonFormat;

import java.util.Date;

/**
 * @author Rex
 * @create 2021-01-12 14:02
 */
public class Person {
    private String name;
    private Integer age;
    @JsonFormat(pattern = "yyyy-MM-dd HH-mm-ss", timezone = "GMT+8")
    private Date birthday;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }
}

client.html

<script>
    //...
    $("#btnPersons").click(function () {
        $.ajax({
            "url":"/restful/persons",
            "type":"get",
            "dataType":"json",
            "success": function (json) {
                console.log(json)
                // $("#message").text(json.message);
                for (var i = 0; i < json.length; i++) {
                    var p = json[i];
                    $("#divPersons").append("<h2>"+p.name+"-"+p.age+"-"+p.birthday+"</h2>")
                }
            }
        })
    });
</script>
<!--...-->
<input type="button" id="btnPersons" value="查询所有人员">
<div id="divPersons"></div>

结果:

在这里插入图片描述

浏览器的跨域访问

浏览器的同源策略

  • 同源策略阻止从一个域加载的脚本去获取另一个域上的资源
  • 只要协议、域名、端口号有任何一个不同,都被当作是不同的域
  • 浏览器Console看到Access-Control-Allow-Origin就代表跨域了

同源策略示例

源URL目标URL直接访问?
http://imooc.comhttps://xxx.com:8080/test不能
http://imooc.comhttps://imooc.com不能
http://imooc.comhttp://abc.imooc.com不能
http://imooc.comhttp://imooc.com:8080不能
http://localhosthttp://127.0.0.1不能
http://imooc.comhttp://imooc.com/user/test可以

HTML中允许跨域的标签

  • <img> - 显示远程图片
  • <script> - 加载远程JS
  • <link> - 加载远程CSS

SpringMVC跨域访问

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

SpringMVC解决跨域访问

  • @CrossOrigin - Controller跨域注解

    代码示例:

    80端口下的RestfulController.java:

    package com.imooc.restful.controller;
    
    import com.imooc.restful.entity.Person;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.*;
    
    import java.util.ArrayList;
    import java.util.Date;
    import java.util.List;
    
    /**
     * @author Rex
     * @create 2021-01-12 12:00
     */
    @RestController
    @RequestMapping("/restful")
    //@CrossOrigin(origins = {"http://localhost:8080", "http://www.imooc.com"})
    @CrossOrigin(origins = "*", maxAge = 3600)//匹配每一个URL, maxAge->设置预检请求的访问时间
    public class RestfulController {
        //....
    }
    

    8080端口下的client.html

    $("#btnPersons").click(function () {
        $.ajax({
            "url":"http://localhost/restful/persons",
            "type":"get",
            "dataType":"json",
            "success": function (json) {
                console.log(json)
                // $("#message").text(json.message);
                for (var i = 0; i < json.length; i++) {
                    var p = json[i];
                    $("#divPersons").append("<h2>"+p.name+"-"+p.age+"-"+p.birthday+"</h2>")
                }
            }
        })
    });
    

    结果:

    在这里插入图片描述

  • <mvc:cors> - Spring MVC 全局跨域配置

    applicationContext.xml

    <mvc:cors>
        <mvc:mapping path="/restful/**"
                     allowed-origins="http://localhost:8080, http://www.imooc.com"
                     max-age="3600"/>
    </mvc:cors>
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Rex·Lin

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值