Java——Restful風格


REST與RESTful:
REST:表現層狀態轉移,資源在網絡中以某種形式進行狀態轉移。
RESTful是基於REST理念的一套開發風格,是具體的開發規則。

 

 

 服務器端只返回數據,以json或者xml的格式。

 

RESTful開發規范:
  • 使用URL作為用戶交互入口
  • 明確的語義規范(GET|POST|PUT|DELETE)
  • 只返回數據(JSON|XML),不包含任何展現

RESTful命名要求:

 

 

 

1.第一個RESTful應用

@Controller
@RequestMapping("/restful")  //URL中所有的都是名詞
public class RestfulController {
    @GetMapping(value = "/request",produces = "application/json;charset=utf-8")
    @ResponseBody
    public String doGetRequest(){
        return "{\"message\":\"測試\"}";  //使用\原義輸出
    }
}

 

2.實現RESTful實驗室

一般PC和移動端都可以調用API接口,下面模擬PC端調用,使用Ajax:

 

 

 通過ajax發送頁面請求:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>RESTful</title>
    <script src="jquery-3.4.1.min.js"></script>
    <script>
        $(function () {
            $("#btnGet").click(function () {
                $.ajax({
                    url : "/restful/request",
                    type : "get",
                    dataType : "json",
                    success : function (json) {
                        $("#message").text(json.message)
                    }
                })
            })
        })
    </script>
</head>
<body>
<input type="button" id="btnGet" value="發送Get請求">
<h2 id="message"></h2>
</body>
</html>

因為定義了webapp為靜態文件的根目錄,所以client.html可以直接訪問。

 

 

 竟然產生了亂碼,查看請求頭,發現采用不正確的字符集。

<mvc:annotation-driven>
    <mvc:message-converters>
        <bean class="org.springframework.http.converter.StringHttpMessageConverter">
            <property name="supportedMediaTypes">
                <list>
                    <value>test/html;charset=utf-8</value>
                    <!--通知瀏覽器以這種格式加載數據-->
                    <value>application/json;charset=utf-8</value>
                </list>
            </property>
        </bean>
    </mvc:message-converters>
</mvc:annotation-driven>

添加以上配置就可以了。(只能解決ajax亂碼問題)

 

3.RestController注解與路徑變量

(1)RestController

@Controller
@RequestMapping("/restful")  //URL中所有的都是名詞
public class RestfulController {
    @GetMapping(value = "/request",produces = "application/json;charset=utf-8")
    @ResponseBody
    public String doGetRequest(){
        return "{\"message\":\"測試\"}";  //使用\原義輸出
    }
}

如果我們希望返回純文本數據,我們必須要使用@ResponseBody這個注解。
如果我們使用@RestController這個注解,那么類下面所有方法都是返回純文本數據。

@RestController
@RequestMapping("/restful")  //URL中所有的都是名詞
public class RestfulController {
    @GetMapping(value = "/request",produces = "application/json;charset=utf-8")
    public String doGetRequest(){
        return "{\"message\":\"測試\"}";  //使用\原義輸出
    }
}

@RestController可以幫我們簡化開發。

(2)路徑變量

/request/1 對於放在URL中的變量我們可以稱之為路徑變量。那么如何取值了?

@RestController
@RequestMapping("/restful")  //URL中所有的都是名詞
public class RestfulController {
    @GetMapping(value = "/request/{rid}",produces = "application/json;charset=utf-8")
    public String doGetRequest(@PathVariable("rid") Integer requestId){
        System.out.println(requestId);
        return "{\"message\":\"測試\"}";  //使用\原義輸出
    }
}

使用@PathVariable路徑變量注解進行接收,而后賦值給方法參數。

 

4.JSON序列化

(1)引入步驟

導入依賴包:

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-core</artifactId>
    <!--一定要使用2.9.9之后的版本,否則會有安全問題-->
    <version>2.9.9</version>
</dependency>
<!--jackson與目標對象交互的根源-->
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.9.9</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-annotations</artifactId>
    <version>2.9.9</version>
</dependency>

 spring非常智能,只要檢查有jackson-core和jackson-databind這兩個依賴包。
就會自動啟用jackson為我們提供json序列化服務。

創建實體類:

public class Person {
    private String name;
    private String address;
}

編寫控制器:

@GetMapping("/person/{pid}")
public Person findByPersonId(@PathVariable("pid") Integer personId){
    Person person = new Person();
    if (personId == 1){
        person.setName("科比");
        person.setAddress("湖北羅田");
    } else if (personId == 2){
        person.setName("星爺");
        person.setAddress("湖北安陸");
    } else {
        person.setName("無名氏");
    }
    return person;
}

如果我們返回一個實體對象,並且配置了@RestController或者@ResponseBody,那么jackson就會自動提供序列化服務。

訪問:

 

 

 

(2)返回多個對象

如果一次返回多個對象,我們可以List集合:

@GetMapping("/persons")
public List<Person> findPersons(){
    List list = new ArrayList();
    Person p1 = new Person();
    p1.setName("科比");
    p1.setAddress("湖北羅田");
    Person p2 = new Person();
    p2.setName("科比");
    p2.setAddress("湖北羅田");
    list.add(p1);
    list.add(p2);
    return list;
}

 

 

在前端,我們會收到如下數據:

 

 

 在頁面中,我們可以通過如下方式進行提取:

$(function () {
    $("#btnPersons").click(function () {
        $.ajax({
            url : "/restful/persons",
            type : "get",
            datatype : "json",
            success : function (json) {
                console.info(json)
                for(var i=0;i<json.length;i++){
                    var p = json[i];
                    $("#divPersons").append("<h2>" + p.name + "-" + p.address + "</h2>")
                }
            }
        })
    })
})

 

(3)時間處理

需要注意的是,jackson對時間處理並不友好:
添加事件屬性:
private Date birthday;
如果不做處理,就是直接返回事件戳的形式。

 

 

 我們只需要添加對應時間注解:
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date birthday;
就可以正常輸出了:

 

 

 還有需要注意的是默認使用格林時間,需要指定時區:
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
private Date birthday;

 

5.瀏覽器的同源策略

同源策略:阻止從一個域加載的腳本去獲取另一個域上的資源。
兩個不同域名的網站不能通過Ajax訪問,這是出於安全的因素考慮。
比如下面兩個地址,雖然本質是一個頁面,但是卻屬於不同源.

只要協議、域名、端口有任何不同,都被當做是不同的域。
瀏覽器Console看到Access-Control-Allow-Origin就代表跨域了。

HTML中允許跨域的標簽:
  <img> 顯式遠程圖片
  <script> 加載遠程JS
  <link> 加載遠程CSS

 

6.SpringMVC解決跨域

CORS是一種機制,使用額外的HTTP頭通知瀏覽器訪問其他域。
URL響應頭中包含Access-Control-*指明請求允許跨域。

(1)@CrossOrigin - Controller跨域注解

@RestController
@RequestMapping("/restful") 
@CrossOrigin(origins = {"*"}) 
public class RestfulController {
    @GetMapping(value = "/request/{rid}",produces = "application/json;charset=utf-8")
    public String doGetRequest(@PathVariable("rid") Integer requestId){
        System.out.println(requestId);
        return "{\"message\":\"測試\"}"; 
    }
}

(2)<mvc:cors> Spring MVC全局跨域配置

<mvc:cors>
    <!--path哪一個路徑允許跨域訪問-->
    <!--allowed-origins允許誰進行跨域訪問-->
    <!--max-age設置緩存時間-->
    <mvc:mapping path="*" allowed-origins="*"/>
</mvc:cors>

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM