Spring 5.2.2 MVC (7)—註解控制器

接着Spring 5.2.2 MVC (6)--註釋控制器講基於註解控制內容。
java


3)後綴匹配typescript

     默認狀況下,Spring MVC執行.*後綴模式匹配,以便映射到/person的控制器也隱蔽映射到/person.*。而後使用文件擴展名解釋請求的內容類型以用於響應(即,代替Accept 頭) - ,例如/person.pdf/person.xml和其餘。編程

     當瀏覽器用來發送難以一致的Accept 頭時,以這種方式使用文件擴展名是必要的。目前,這已再也不是必需的,使用Accept 頭應該是首選。json

     隨着時間的推移,文件擴展名的使用已經被證實在許多方面存在問題。當使用URI變量、路徑參數和URI編碼覆蓋時,它可能會致使歧義。關於基於URL的受權和安全性的推理也變得更加困難。瀏覽器

要徹底禁用文件擴展名的使用,必須同時設置如下兩項:安全

  1. useSuffixPatternMatching(false)--參看PathMatchConfigurer微信

  2. favorPathExtension(false)--參看ContentNegotiationConfigureapp


基於URL的內容仍然頗有用(例如,在瀏覽器中鍵入URL時)。爲了實現這一點,咱們建議使用基於查詢參數的策略,以免文件擴展名帶來的大多數問題。或者,若是必須使用文件擴展名,請考慮經過ContentNegotiationConfigurermediaTypes 屬性將它們限制爲顯式註冊的擴展名列表。ide

@Configuration@EnableWebMvcpublic class WebConfig implements WebMvcConfigurer {
@Override public void configureContentNegotiation(ContentNegotiationConfigurer configurer) { configurer.mediaType("json", MediaType.APPLICATION_JSON); configurer.mediaType("xml", MediaType.APPLICATION_XML); }}


4)後綴匹配和RFD測試

      反射文件下載(reflected file download,RFD)攻擊與XSS相似,它依賴於響應中反射的請求輸入(例如,查詢參數和URI變量)。然而RFD攻擊不是將JavaScript插入HTML,而是依賴於瀏覽器切換來執行下載,並在之後雙擊時將響應視爲可執行腳本。

     在Spring MVC中,@ResponseBodyResponseEntity 方法面臨風險,由於它們能夠呈現不一樣的內容類型,客戶端能夠經過URL路徑擴展請求這些內容類型。禁用後綴模式匹配和使用路徑擴展進行內容能夠下降風險,但不足以防止RFD攻擊。

    爲了防止RFD攻擊,在呈現響應體以前,Spring MVC添加了一個:Content-Disposition:inline;filename=f.txt頭來建議一個固定且安全的下載文件。只有當URL路徑包含既沒有白名單也沒有爲內容顯式註冊的文件擴展名時,纔會執行此操做。然而,當URL直接輸入到瀏覽器中時,它可能會產生反作用。

    默認狀況下,許多公共路徑擴展都是白名單。具備自定義HttpMessageConverter 實現的應用程序能夠註冊用於內容的文件擴展名,以免爲這些擴展名添加Content-Disposition頭。

有關RFD的其餘建議,見CVE-2015-5211。

5)Consumable 媒體Types

    能夠根據請求的Content-Type縮小請求映射範圍,以下例所示:

//使用consumes屬性縮小Content-Type映射範圍。@PostMapping(path = "/pets", consumes = "application/json") public void addPet(@RequestBody Pet pet) { // ...}

consumes 屬性還支持否認表達式 - ,例如!text/plain是指除text/plain之外的任何內容類型。

     能夠在類級別聲明一個共享consumes 屬性。然而,與大多數其餘請求映射屬性不一樣,當在類級別使用時,方法級別使用consumes 屬性重寫,而不是擴展類級別聲明。

   MediaType 爲經常使用的媒體類型(如APPLICATION_JSON_VALUE APPLICATION_XML_VALUE)提供常量。


6)Producible 媒體 Types

    能夠基於Accept 請求頭和控制器方法生成的內容類型列表縮小請求映射,以下例所示:

//使用products屬性縮小content type映射範圍。@GetMapping(path = "/pets/{petId}", produces = "application/json") @ResponseBodypublic Pet getPet(@PathVariable String petId) { // ...}

媒體類型能夠指定字符集。例如,支持否認表達式 -!text/plain是指除「text/plain」以外的任何內容類型。

    能夠在類級別聲明共享的produces 屬性。可是,與大多數其餘請求映射屬性不一樣,當在類級別使用時,方法級別生成produces 屬性重寫,而不是擴展類級別聲明。


7)Parameters, headers

    能夠基於請求參數條件縮小請求映射範圍。你能夠測試是否存在請求參數(myParam),是否缺乏一個(!myPara)或特定值(myParam=myValue)。如下示例演示如何測試特定值:

//測試myParam是否等於myValue@GetMapping(path = "/pets/{petId}", params = "myParam=myValue") public void findPet(@PathVariable String petId) { // ...}

你還能夠對請求頭條件使用相同的條件,以下例所示:

//測試myHeader是否等於myvalue。@GetMapping(path = "/pets", headers = "myHeader=myValue") public void findPet(@PathVariable String petId) { // ...}

    你能夠將Content-TypeAccept 與headers條件匹配,但最好使用consumersproducts


8)HTTP HEAD, OPTIONS

   @GetMapping(和@RequestMapping(method=HttpMethod.GET))爲請求映射支持HTTP HEAD 。控制器方法不須要更改。在javax.servlet.http.HttpServlet中應用的response 封裝確保將Content-Length頭設置爲寫入的字節數(而不實際寫入響應)。

  @GetMapping(和@RequestMapping(method=HttpMethod.GET))隱式映射到並支持HTTP HEAD。一個HTTP HEAD請求被看成HTTP GET來處理,只是不寫正文,而是計算字節數並設置Content-Length頭。

     默認狀況下,經過將Allow response頭設置爲全部@RequestMapping方法中列出的具備匹配URL模式的HTTP方法列表來處理HTTP選項。

    對於沒有HTTP方法聲明的@RequestMappingAllow 頭被設置爲GET、HEAD、POST、PUT、PATCH、DELETE、OPTIONS。控制器方法應始終聲明支持的HTTP方法(例如,使用HTTP方法特定的變量:@GetMapping@PostMapping和其餘變量)。

     你能夠將@RequestMapping方法映射到HTTP HEAD和HTTP  OPTIONS,但在通常狀況下這是不必的。


9)自定義註解

    Spring MVC支持使用組合註解進行請求映射。這些註解自己就是用@RequestMapping進行元註解的註解,用於從新聲明@RequestMapping屬性的一個子集(或所有),具備更窄、更具體的用途。

   @GetMapping@PostMapping@PutMapping@DeleteMapping@PatchMapping是組合註解的示例。之因此提供它們,是由於大多數控制器方法應該映射到特定的HTTP方法,而不是使用@RequestMapping,默認狀況下,它與全部HTTP方法匹配。若是須要組合註解的示例,請查看如何聲明這些註釋。

    Spring MVC還支持具備自定義請求匹配邏輯的自定義請求映射屬性。這是一個更高級的選項,須要子類RequestMappingHandlerMapping 並重寫getCustomMethodCondition 方法,你能夠在該方法中檢查自定義屬性並返回本身的RequestCondition


10)易於理解的Registrations

    你能夠以編程方式註冊處理程序方法,這些方法可用於動態註冊或高級狀況,例如不一樣URL下同一處理程序的不一樣實例。如下示例註冊處理程序方法:

@Configurationpublic class MyConfig { //爲控制器注入目標處理程序和處理程序映射。 @Autowired public void setHandlerMapping(RequestMappingHandlerMapping mapping, UserHandler handler)  throws NoSuchMethodException {    //準備請求映射數據。 RequestMappingInfo info = RequestMappingInfo .paths("/user/{id}").methods(RequestMethod.GET).build();  //獲取處理程序方法 Method method = UserHandler.class.getMethod("getUser", Long.class);  //添加註冊。 mapping.registerMapping(info, handler, method);  }}


明天講 基於控制器註解的句柄方法(Handler Methods)。


敬請持續關注。


歡迎關注和轉發Spring中文社區(加微信羣,能夠關注後加我微信):


本文分享自微信公衆號 - Spring中文社區(gh_81d233bb13a4)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。

相關文章
相關標籤/搜索