SpringMVC 與 REST.


一、REST 的基礎知識

    我敢打賭這並不是你第一次聽到或讀到REST這個詞。當討論REST時,有一種常見的錯誤就是將其視為“基於URL的Web服務”—— 將REST作為另一種類型的RPC機制,只不過是通過簡單的HTTP URL來觸發。恰好相反,REST 和 RPC 幾乎沒有任何關系。RPC 是面向服務的,並關注於行為和動作;而REST 是面向資源的,強調描述應用程序的事物和名詞。

    REST(Representational State Transfer)表述性狀態轉移,已信息為中心,為了理解REST是什么,我們將它的首字母縮寫拆分為不同的構成部分:

表述性(Representational):REST資源實際上可以用各種形式來進行表述,包括XML、JSON(JavaScript Object Notation)甚至HTML——最適合資源使用者的任意形式;
狀態(State):當使用REST的時候,我們更關注資源的狀態而不是對資源采取的行為;
轉移(Transfer):REST涉及到轉移資源數據,它以某種表述性形式從一個應用轉移到另一個應用。

    更簡潔地講,REST就是將資源的狀態以最適合客戶端或服務端的形式從服務器端轉移到客戶端(或者反過來)。其實就是,比如我想要 application/json 格式的數據,REST服務就能為我提供JSON格式的數據;我想要 application/xml 格式的數據,REST服務就能為了提供XML格式的數據(或者反過來)。

    在REST中,資源通過URL進行識別和定位。至於RESTful URL的結構並沒有嚴格的限制,但是URL應該能夠識別資源,而不是簡單的發一條命名到服務器上:

Create:POST
Read:GET
Update:PUT或PATCH
Delete:DELETE

tips:實際上,POST請求非冪等性的特點使其成為一個非常靈活的方法,對於無法適應其他HTTP方法的語義的操作,它都能勝任。

二、Spring MVC 構建 REST API

    Spring 對 REST 提供了良好的支持,支持以下方式來創建 REST 資源:

  • 控制器可以處理所有的HTTP方法,包含四個主要的REST方法:GET、PUT、DELETE以及POST。
  • 消息轉換器(Message conversion)將資源的Java表述形式轉換為發送給客戶端的表述形式。
  • 借助於 SpringMVC 的一系列注解,構建 REST API
  • 借助 RestTemplate,Spring應用能夠方便地使用REST資源。

1、消息轉換器(Message conversion)

    消息轉換(message conversion)提供了一種更為直接的方式,它能夠將控制器產生的數據轉換為服務於客戶端的表述形式。當使用消息轉換功能時,DispatcherServlet不再需要那么麻煩地將模型數據傳送到視圖中。實際上,這里根本就沒有模型,也沒有視圖,只有控制器產生的數據,以及消息轉換器(message converter)轉換數據之后所產生的資源表述。

    Spring 自帶了各種各樣的轉換器,如下使用了 MappingJackson2HttpMessageConverter,並由它轉換為返回客戶端的JSON表述形式。

    <mvc:annotation-driven>
        <!--使用HTTP信息轉換器-->
        <mvc:message-converters>
            <!--讀取或寫入Resource-->
            <bean class="org.springframework.http.converter.ResourceHttpMessageConverter"/>
            <!--在JSON和類型化的對象或非類型化的HashMap間互相讀取和寫入-->
            <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
                <!--服務端支持返回的資源形式-->
                <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>

2、SpringMVC 的 REST 注解

@PathVariable:控制器能夠處理參數化的URL(將變量輸入作為URL的一部分);
@ResponseBody:告訴Spring跳過正常的模型/視圖流程,並使用消息轉換器。它將會告知Spring,我們將要返回的對象作為資源發送給客戶端,並將其轉換為客戶端可接受的形式。
@RequestBody:告訴Spring查找一個消息轉換器,將來自客戶端的資源表述轉換為對象。
@RestController:如果在控制器類上使用@RestController來代替@Controller的話,Spring將會為該控制器的所有處理方法應用消息轉換功能。我們不必為每個方法都添加@ResponseBody了。
@ResponseStatus:指定返回的狀態碼。
@ResponseEntity:作為@ResponseBody的替代方案,控制器方法可以返回一個ResponseEntity對象。ResponseEntity中可以包含響應相關的元數據(如頭部信息和狀態碼)以及要轉換成資源表述的對象。

    @RequestMapping(
            value = "listUserDTO"
            , method = RequestMethod.POST
            , consumes = "application/json")
    public ResponseEntity<UserDTO> saveUserDto(@RequestBody UserDTO userDTO, UriComponentsBuilder ucb) {
        UserDTO user = userService.saveUser(userDTO);
        HttpHeaders headers = new HttpHeaders();
        URI uri = ucb.path("/").path(user.getName()).build().toUri();
        headers.setLocation(uri);
        ResponseEntity<UserDTO> userDTOResponseEntity = new ResponseEntity<>(user, headers, HttpStatus.CREATED);
        return userDTOResponseEntity;
    }

三、RestTemplate API

    RestTemplate 定義了36種與REST資源交互的形式(其實只有11個獨立的方法,10個被重載了3次,另外一個被重載了6次),其中大多數都對應於HTTP的方法。大多數HTTP方法都以三種方法進行了重載:

# 1. 一個使用String作為URL格式,並使用可變參數列表指明URL參數。
# url 參數指定訪問的地址, responseType 參數定義該方法的返回類型, urlVariables 參數為 url 中占位符對應的參數。
getForObject (String url, Class responseType, Object... urlVariables):

# 2. 一個使用String作為URL格式,並使用Map指明URL參數。
#在該函數中,使用 Map 類型的 urlVariables 替代上面數組形式的 urlVariables,因此使用時在 url 中需要將占位符的名稱與 Map 類型中的 key一一對應設置。
getForObject(String url, Class responseType, Map urlVariables):

# 3. 一個使用 java.net.URL 作為 URL格式,不支持參數化URL;
# 使用 URI 對象來替代之前的 url和urlVariables 參數使用。
getForObject(URI url, Class responseType)

 

    RestTemplate定義了11個獨立的操作,而每一個都有重載,這樣一共是36個方法 :

-- postForEntity() :POST數據到一個URL,返回包含一個對象的ResponseEntity,這個對象是從響應體中映射得到的。
-- postForLocation() :POST數據到一個URL,返回新創建資源的URL。
-- postForObject() :POST數據到一個URL,返回根據響應體匹配形成的對象。

# 需要注意的是新增加的 request 參數,該參數可以是一個普通對象,也可以是一個 HttpEntity 對象。
# 如果是一個普通對象,而非 HttpEntity 對象的時候,RestTemplate會將請求對象轉換為一個 HttpEntity 對象來處理,其中 Object 就是 request的類型,request內容會被視作完整的body來處理;
# 如果 request 是一個HttpEntity對象,那么就會被當作一個完成的 HTTP 請求對象來處理,這個 request 中不僅包含了 body 的內容, 也包含了 header 的內容。 postForObject(String url, Object request, Class responseType, Map uriVariables)

-- delete() :在特定的URL上對資源執行HTTP DELETE操作。
-- put() :PUT資源到特定的URL。
-- getForEntity() :發送一個HTTP GET請求,返回的ResponseEntity包含了響應體所映射成的對象。
-- getForObject() :發送一個HTTP GET請求,返回的請求體將映射為一個對象。
-- headForHeaders() :發送HTTP HEAD請求,返回包含特定資源URL的HTTP頭。
-- optionsForAllow() :發送HTTP OPTIONS請求,返回對特定URL的Allow頭信息。
-- exchange() :在URL上執行特定的HTTP方法,返回包含對象的ResponseEntity,這個對象是從響應體中映射得到的。
-- execute() :在URL上執行特定的HTTP方法,返回一個從響應體映射得到的對象。

 

RestTemplate 的相關操作以及如何使用 SpringMVC創建REST端點可參考:https://github.com/JMCuixy/SpringMvcForRest

 


免責聲明!

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



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