使用Spring 3.1和基于Java的配置構建RESTful Web服務,第2部分

1.概述

本文介紹了如何在Spring中設置REST –控制器和HTTP響應代碼,有效負載編組配置和內容協商。

2.在Spring了解REST

Spring框架支持兩種創建RESTful服務的方式:

  • ModelAndView一起使用MVC
  • 使用HTTP消息轉換器

ModelAndView方法較舊,文檔記載得更好,但也很冗長,配置繁重。 它試圖將REST范式轉換為舊模型,但這并非沒有問題。 Spring團隊對此有所了解,并從Spring 3.0開始提供了一流的REST支持。

基于HttpMessageConverter注釋的新方法輕巧得多,易于實現。 配置是最小的,它為RESTful服務提供了合理的默認值。 但是,它在文檔方面比較新,有點輕松。 更重要的是,參考并不能完全消除兩者之間的區別和權衡取舍。 盡管如此,這是在Spring 3.0之后構建RESTful服務的方式。

3. Java配置

@Configuration
@EnableWebMvc
public class WebConfig{//
}

新的@EnableWebMvc注釋做了很多有用的事情-特別是在REST的情況下,它檢測到類路徑中存在Jackson和JAXB 2,并自動創建并注冊默認的JSON和XML轉換器 。 注釋的功能等效于XML版本:

<mvc:注釋驅動/>

這是一個捷徑,盡管在許多情況下可能有用,但它并不完美。 當需要更復雜的配置時,請刪除注釋并直接擴展WebMvcConfigurationSupport

4.測試Spring上下文

Spring 3.1開始, 我們獲得對@Configuration類的一流測試支持:

@RunWith( SpringJUnit4ClassRunner.class )
@ContextConfiguration( classes = { ApplicationConfig.class, PersistenceConfig.class },loader = AnnotationConfigContextLoader.class )
public class SpringTest{@Testpublic void whenSpringContextIsInstantiated_thenNoExceptions(){// When}
}

只需使用@ContextConfiguration批注指定Java配置類,新的AnnotationConfigContextLoader即可@Configuration類加載Bean定義。

注意, WebConfig配置類未包含在測試中,因為它需要在未提供的Servlet上下文中運行。

5.控制器

@Controller是RESTful API整個Web層中的中心構件。 出于本文的目的,控制器正在對簡單的REST資源– Foo建模:

@Controller
@RequestMapping( value = "foo" )
class FooController{@AutowiredIFooService service;@RequestMapping( method = RequestMethod.GET )@ResponseBodypublic List< Foo > getAll(){return service.getAll();}@RequestMapping( value = "/{id}", method = RequestMethod.GET )@ResponseBodypublic Foo get( @PathVariable( "id" ) Long id ){return RestPreconditions.checkNotNull( service.getById( id ) );}@RequestMapping( method = RequestMethod.POST )@ResponseStatus( HttpStatus.CREATED )@ResponseBodypublic Long create( @RequestBody Foo entity ){RestPreconditions.checkNotNullFromRequest( entity );return service.create( entity );}@RequestMapping( method = RequestMethod.PUT )@ResponseStatus( HttpStatus.OK )public void update( @RequestBody Foo entity ){RestPreconditions.checkNotNullFromRequest( entity );RestPreconditions.checkNotNull( service.getById( entity.getId() ) );service.update( entity );}@RequestMapping( value = "/{id}", method = RequestMethod.DELETE )@ResponseStatus( HttpStatus.OK )public void delete( @PathVariable( "id" ) Long id ){service.deleteById( id );}}

Controller的實現是非公開的 –這是因為不需要這樣做。 通常,控制器是依賴關系鏈中的最后一個控制器–它從Spring前端控制器( DispathcerServlet )接收HTTP請求,然后簡單地將它們委托給服務層。 如果沒有用例必須通過直接引用來注入或操縱控制器,則我不希望將其聲明為公共。

請求映射很簡單–與任何控制器一樣,映射的實際以及HTTP 方法都用于確定請求的目標方法。 @ RequestBody將方法的參數綁定到HTTP請求的主體,而@ResponseBody對響應和返回類型執行相同的操作。 它們還確保使用正確的HTTP轉換器對資源進行編組和解組。 盡管也可以使用其他HTTP頭來確定表示形式,但將主要根據Accept頭進行內容協商,以選擇使用哪個活動轉換器。

6.映射HTTP響應代碼

HTTP響應的狀態碼是REST服務最重要的部分之一,因此主題很快就會變得非常復雜。 正確執行這些操作可能會導致或中斷服務。

6.1。 未映射的請求

如果Spring MVC收到沒有映射的請求,則認為該請求不被允許,并向客戶端返回405 METHOD NOT ALLOWED NOT ALLOWED 。 這也是很好的做法,包括允許 HTTP標頭返回一個405到客戶端時,以指定哪些操作允許的。 這是Spring MVC的標準行為,不需要任何其他配置。

6.2。 有效的映射請求

對于任何確實具有映射的請求,Spring MVC認為該請求有效,如果未指定其他狀態代碼,則響應為200 OK 。 因此,控制器為createupdatedelete動作聲明了不同的@ResponseStatus ,但為get聲明了不同的@ResponseStatus ,實際上應該返回默認的200 OK。

6.3。 客戶端錯誤

如果發生客戶端錯誤 ,則會定義自定義異常并將其映射到適當的錯誤代碼。 只需從Web層的任何層拋出這些異常,即可確保Spring在HTTP響應上映射相應的狀態代碼。

@ResponseStatus( value = HttpStatus.BAD_REQUEST )
public class BadRequestException extends RuntimeException{//
}
@ResponseStatus( value = HttpStatus.NOT_FOUND )
public class ResourceNotFoundException extends RuntimeException{//
}

這些例外是REST API的一部分,因此,僅應在與REST相對應的適當層中使用; 例如,如果存在DAO / DAL層,則不應直接使用異常。 還要注意,這些不是經過檢查的異常,而是運行時異常 –與Spring的實踐和習慣用法一致。

6.4。 使用@ExceptionHandler

將自定義異常映射到特定狀態代碼的另一種方法是在控制器中使用@ExceptionHandler批注。 這種方法的問題在于,注釋僅適用于定義了它的控制器,而不適用于整個Spring容器,這意味著需要在每個控制器中分別聲明它。 這很快變得很麻煩,尤其是在具有許多控制器的更復雜的應用程序中。 目前,Spring已解決了一些JIRA問題 ,以解決此限制和其他相關限制: SPR-8124 , SPR-7278 , SPR-8406 。

7.其他Maven依賴項

除了標準Web應用程序所需的spring-webmvc依賴關系之外,我們還需要為REST API設置內容編組和解編組:

<dependencies><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>${jackson.version}</version></dependency><dependency><groupId>javax.xml.bind</groupId><artifactId>jaxb-api</artifactId><version>${jaxb-api.version}</version><scope>runtime</scope></dependency>
</dependencies><properties><jackson.version>2.2.2</jackson.version><jaxb-api.version>2.2.9</jaxb-api.version>
</properties>

這些庫用于將REST資源的表示形式轉換為JSONXML

8.結論

這篇文章介紹了使用Spring 3.1和基于Java的配置對RESTful服務的配置和實現,并討論了HTTP響應代碼,基本內容協商和封送處理。

在本系列的下一篇文章中,我將重點介紹API的可發現性 ,高級內容協商以及使用資源的其他表示形式 。 同時,檢查github項目 。

參考:來自baeldung博客的JCG合作伙伴 Eugen Paraschiv 使用Spring 3和Java Config構建REST API 。

翻譯自: https://www.javacodegeeks.com/2011/11/building-restful-web-service-with.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/374027.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/374027.shtml
英文地址,請注明出處:http://en.pswp.cn/news/374027.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Vmware Player 比較

VMware Workstation 12 Player 與 VMware Player 7 Pro 比較 主要功能特性VMware Player 7 ProVMware Workstation 12 Player針對商業用途授予許可是是支持多達 16 個虛擬 CPU、8 TB 磁盤、64 GB RAM 和 2 GB 顯存是是支持 Microsoft Windows 10、Ubuntu 15.04、RHEL 7.1、Fedo…

(轉)求單鏈表是否有環,環入口和環長

轉自&#xff1a;http://www.cnblogs.com/youxin/p/3303172.html 1.鏈表中是否有環的判斷可以設置兩個指針(fast,slow)&#xff0c;初始值均指向頭&#xff0c;slow每次向前一步&#xff0c;fast每次向前兩步&#xff1b;如果鏈表中有環&#xff0c;則fast先進入環中&#xff0…

OJ RuntimeError常見原因

RuntimeError常見出錯的原因可能有以下幾種&#xff1a; 1、數組開得太小了&#xff0c;導致訪問到了不該訪問的內存區域 2、發生除零錯誤 3、大數組定義在函數內,導致程序棧區耗盡 4、指針用錯了&#xff0c;導致訪問到不該訪問的內存區域 5、還有可能是程序拋出了未接收…

python recv_Python socket.recv方法代碼示例

# 需要導入模塊: from gevent import socket [as 別名]# 或者: from gevent.socket import recv [as 別名]def handle(self):"""The main request handling method, called by the server.This method runs a request handling loop, calling:meth:handle_one_r…

使用Selenium或WebDriver測試GWT應用

對于Web應用程序開發人員及其團隊而言&#xff0c;良好的功能測試是最困難的任務之一。 開發價格低廉且維護良好的測試是一項挑戰&#xff0c;這有助于降低質量檢查成本并提高質量。 Selenium和WebDriver&#xff08;本質上現在是Selenium的繼承者&#xff09;都提供了一種無需…

MySQL中有關TIMESTAMP和DATETIME的總結

一、MySQL中如何表示當前時間&#xff1f; 其實&#xff0c;表達方式還是蠻多的&#xff0c;匯總如下&#xff1a; CURRENT_TIMESTAMP CURRENT_TIMESTAMP() NOW() LOCALTIME LOCALTIME() LOCALTIMESTAMP LOCALTIMESTAMP() 二、關于TIMESTAMP和DATETIME的比較 一個完整的日期格式…

NYOJ 202 紅黑樹

紅黑樹 時間限制&#xff1a;3000 ms | 內存限制&#xff1a;65535 KB難度&#xff1a;3描述 什么是紅黑樹呢&#xff1f;顧名思義&#xff0c;跟棗樹類似&#xff0c;紅黑樹是一種葉子是黑色果子是紅色的樹。。。 當然&#xff0c;這個是我說的。。。 《算法導論》上可不是這么…

為對象添加方法mothod

Function.prototype.mothod function( name, fn ) { this.prototype[name] fn ; return this ; };轉載于:https://www.cnblogs.com/40dadao/p/5816521.html

python爬蟲cookie池 與ip綁定_Python爬蟲:設置Cookie解決網站攔截并爬取螞蟻短租

前言文的文字及圖片來源于網絡,僅供學習、交流使用,不具有任何商業用途,版權歸原作者所有,如有問題請及時聯系我們以作處理。作者&#xff1a; EastmountPS&#xff1a;如有需要Python學習資料的小伙伴可以加點擊下方鏈接自行獲取我們在編寫Python爬蟲時&#xff0c;有時會遇到…

Java Secret:加載和卸載靜態字段

總覽 首先&#xff0c;很自然地假設靜態字段具有特殊的生命周期&#xff0c;并且在應用程序的生命周期中一直存在。 您可以假設它們存在于內存中的特殊位置&#xff0c;例如C或類元信息的perm gen中的內存開始。 但是&#xff0c;得知靜態字段駐留在堆上&#xff0c;可以具有任…

HTTP協議詳解(真的很經典)

轉自&#xff1a;http://blog.csdn.net/gueter/archive/2007/03/08/1524447.aspx Author :Jeffrey 引言 HTTP是一個屬于應用層的面向對象的協議&#xff0c;由于其簡捷、快速的方式&#xff0c;適用于分布式超媒體信息系統。它于1990年…

NYOJ 63 小猴子下落

小猴子下落 時間限制&#xff1a;3000 ms | 內存限制&#xff1a;65535 KB難度&#xff1a;3描述 有一顆二叉樹&#xff0c;最大深度為D,且所有葉子的深度都相同。所有結點從左到右從上到下的編號為1,2,3&#xff0c;&#xff0c;2的D次方減1。在結點1處放一個小猴子&#xff0…

python科學計算與圖形渲染_寧哥Python科學計算與圖形渲染庫課程

50dccd474759c0ffd343efcac14f8ab2.png (259.41 KB, 下載次數: 0)2019-4-9 12:23 上傳課程目錄章節1: NumPy基礎知識課時1NumPy簡介14:05課時2搭建NumPy開發環境&#xff0c;驗證NumPy開發環境17:08課時3源代碼和數據下載章節2: NumPy數組課時4創建多維數組09:20課時5獲取單個數…

http協議說明

今天公司有同事讓我給他講一講http..然后自己寫了一個示例代碼,這如果都看不懂.那我也沒辦法了.... 1 <?php2 3 //這里服務器以apache舉例.nginx.iis.他們實際上處理方式的都是同理4 //申明http鏈接的數據包 注意最后面有兩個換號.這是告訴apache.數據包的結束,如果后面沒…

JBoss模塊示例–模塊化Web應用程序

最近&#xff0c;我讀了為什么沒有標準來開發真正的模塊化Web應用程序&#xff1f; 由Patroklos Papapetrou撰寫&#xff08; 在Java Code Geeks中也有介紹 &#xff09;。 受本文的啟發&#xff0c;我決定檢查實際使用的JBoss模塊 。 這篇文章逐步描述了我的實驗。 我首先想到…

由MySql漏洞導致電腦被入侵(特征為新增加名為piress的帳戶)

今天開機&#xff0c;突然發現新增了一個名為piress的賬戶&#xff0c;突然間就意識到我的電腦可能被入侵了。后來發現網上很多人都遇到這樣的問題。經過一步步的查證&#xff0c;原來最近MySQL爆出一個安全漏洞&#xff0c;遠程登錄mysql&#xff0c;嘗試225次后就可以繞過身份…

multiprocessing.manager管理的對象需要加鎖嗎_Go: 內存管理和分配

本文基于Go1.13當不再使用內存時&#xff0c;標準庫會自動執行Go的內存管理即從分配到回收。盡管開發者不需要處理它&#xff0c;但是Go的底層管理進行了很好的優化并且充滿了有趣的概念。堆上的分配內存管理被設計可以在并發環境快速執行并且集成了gc。讓我們從一個例子開始&a…

NYOJ 35表達式求值

表達式求值 時間限制&#xff1a;3000 ms | 內存限制&#xff1a;65535 KB難度&#xff1a;4描述 ACM隊的mdd想做一個計算器&#xff0c;但是&#xff0c;他要做的不僅僅是一計算一個AB的計算器&#xff0c;他想實現隨便輸入一個表達式都能求出它的值的計算器&#xff0c;現在請…

Java EE6 CDI,命名組件和限定符

Java EE6的最大承諾之一就是簡化了依賴注入的使用。 他們做到了&#xff0c;使用CDI 。 CDI代表Java EE的上下文和依賴注入&#xff0c;它提供了一個基礎集&#xff0c;用于在企業應用程序中應用依賴注入。 在CDI之前&#xff0c;EJB 3還引入了依賴注入&#xff0c;但這有點基礎…

c#獲取當前目錄的一些方法

【內容來源地址】&#xff1a;http://www.cnblogs.com/marcozh/archive/2008/10/19/1314667.html Assembly myAssembly Assembly.GetEntryAssembly(); string path myAssembly.Location; DirectoryInfo dr new DirectoryInfo(path); pathd…