1. 程式人生 > >【SpringMVC】@RequestMapping 註解使用技巧

【SpringMVC】@RequestMapping 註解使用技巧

@RequestMapping 是 Spring Web 應用程式中最常被用到的註解之一。這個註解會將 HTTP 請求對映到 MVC 和 REST 控制器的處理方法上。

在這篇文章中,你將會看到 @RequestMapping 註解在被用來進行 Spring MVC 控制器方法的對映可以如何發揮其多才多藝的功能的。

Request Mapping 基礎用法

在 Spring MVC 應用程式中,RequestDispatcher (在 Front Controller 之下) 這個 servlet 負責將進入的 HTTP 請求路由到控制器的處理方法。

在對 Spring MVC 進行的配置的時候, 你需要指定請求與處理方法之間的對映關係。


要配置 Web 請求的對映,就需要你用上 @RequestMapping 註解。

@RequestMapping 註解可以在控制器類的級別和/或其中的方法的級別上使用。

在類的級別上的註解會將一個特定請求或者請求模式對映到一個控制器之上。之後你還可以另外新增方法級別的註解來進一步指定到處理方法的對映關係。

下面是一個同時在類和方法上應用了 @RequestMapping 註解的示例:
@RestController
@RequestMapping("/home")
public class IndexController {
    @RequestMapping("/")
    String get() {
        //mapped to hostname:port/home/
        return "Hello from get";
    }
    @RequestMapping("/index")
    String index() {
        //mapped to hostname:port/home/index/
        return "Hello from index";
    }
}

如上述程式碼所示,到 /home 的請求會由 get() 方法來處理,而到 /home/index 的請求會由 index() 來處理。

@RequestMapping 來處理多個 URI

你可以將多個請求對映到一個方法上去,只需要新增一個帶有請求路徑值列表的 @RequestMapping 註解就行了。

@RestController
@RequestMapping("/home")
public class IndexController {

    @RequestMapping(value = {
        "",
        "/page",
        "page*",
        "view/*,**/msg"
    })
    String indexMultipleMapping() {
        return "Hello from index multiple mapping.";
    }
}

如你在這段程式碼中所看到的,@RequestMapping 支援統配符以及ANT風格的路徑。前面這段程式碼中,如下的這些 URL 都會由 indexMultipleMapping() 來處理:

  • localhost:8080/home

  • localhost:8080/home/

  • localhost:8080/home/page

  • localhost:8080/home/pageabc

  • localhost:8080/home/view/

  • localhost:8080/home/view/view

帶有 @RequestParam 的 @RequestMapping

@RequestParam 註解配合 @RequestMapping 一起使用,可以將請求的引數同處理方法的引數繫結在一起。

@RequestParam 註解使用的時候可以有一個值,也可以沒有值。這個值指定了需要被對映到處理方法引數的請求引數, 程式碼如下所示:

@RestController
@RequestMapping("/home")
public class IndexController {

    @RequestMapping(value = "/id")
    String getIdByValue(@RequestParam("id") String personId) {
        System.out.println("ID is " + personId);
        return "Get ID from query string of URL with value element";
    }
    @RequestMapping(value = "/personId")
    String getId(@RequestParam String personId) {
        System.out.println("ID is " + personId);
        return "Get ID from query string of URL without value element";
    }
}

在程式碼的第6行,id 這個請求引數被對映到了 thegetIdByValue() 這個處理方法的引數 personId 上。

如果請求引數和處理方法引數的名稱一樣的話,@RequestParam 註解的 value 這個引數就可省掉了, 如程式碼的第11行所示。

@RequestParam 註解的 required 這個引數定義了引數值是否是必須要傳的。

@RestController
@RequestMapping("/home")
public class IndexController {
    @RequestMapping(value = "/name")
    String getName(@RequestParam(value = "person", required = false) String personName) {
        return "Required element of request param";
    }
}

在這段程式碼中,因為 required 被指定為 false,所以 getName() 處理方法對於如下兩個 URL 都會進行處理:

  • /home/name?person=xyz

  • /home/name

@RequestParam 的 defaultValue 取值就是用來給取值為空的請求引數提供一個預設值的。

@RestController
@RequestMapping("/home")
public class IndexController {
    @RequestMapping(value = "/name")
    String getName(@RequestParam(value = "person", defaultValue = "John") String personName) {
        return "Required element of request param";
    }
}
在這段程式碼中,如果 person 這個請求引數為空,那麼 getName() 處理方法就會接收 John 這個預設值作為其引數。

用 @RequestMapping 處理 HTTP 的各種方法

Spring MVC 的 @RequestMapping 註解能夠處理 HTTP 請求的方法, 比如 GET, PUT, POST, DELETE 以及 PATCH。

所有的請求預設都會是 HTTP GET 型別的。

為了能降一個請求對映到一個特定的 HTTP 方法,你需要在 @RequestMapping 中使用 method 來宣告 HTTP 請求所使用的方法型別,如下所示:

@RestController
@RequestMapping("/home")
public class IndexController {
    @RequestMapping(method = RequestMethod.GET)
    String get() {
        return "Hello from get";
    }
    @RequestMapping(method = RequestMethod.DELETE)
    String delete() {
        return "Hello from delete";
    }
    @RequestMapping(method = RequestMethod.POST)
    String post() {
        return "Hello from post";
    }
    @RequestMapping(method = RequestMethod.PUT)
    String put() {
        return "Hello from put";
    }
    @RequestMapping(method = RequestMethod.PATCH)
    String patch() {
        return "Hello from patch";
    }
}

在上述這段程式碼中, @RequestMapping 註解中的 method 元素聲明瞭 HTTP 請求的 HTTP 方法的型別。

所有的處理處理方法會處理從這同一個 URL( /home)進來的請求, 但要看指定的 HTTP 方法是什麼來決定用哪個方法來處理。

例如,一個 POST 型別的請求 /home 會交給 post() 方法來處理,而一個 DELETE 型別的請求 /home 則會由 delete() 方法來處理。

你會看到 Spring MVC 將使用這樣相同的邏輯來對映其它的方法。

用 @RequestMapping 來處理生產和消費物件

可以使用 @RequestMapping 註解的 produces 和 consumes 這兩個元素來縮小請求對映型別的範圍。

為了能用請求的媒體型別來產生物件, 你要用到 @RequestMapping 的 produces 元素再結合著 @ResponseBody 註解。

你也可以利用 @RequestMapping 的 comsumes 元素再結合著 @RequestBody 註解用請求的媒體型別來消費物件。

下面這段程式碼就用到的 @RequestMapping 的生產和消費物件元素:

@RestController
@RequestMapping("/home")
public class IndexController {
    @RequestMapping(value = "/prod", produces = {
        "application/JSON"
    })
    @ResponseBody
    String getProduces() {
        return "Produces attribute";
    }

    @RequestMapping(value = "/cons", consumes = {
        "application/JSON",
        "application/XML"
    })
    String getConsumes() {
        return "Consumes attribute";
    }
}

在這段程式碼中, getProduces() 處理方法會產生一個 JSON 響應, getConsumes() 處理方法可以同時處理請求中的 JSON 和 XML 內容。

使用 @RequestMapping 來處理訊息頭

@RequestMapping 註解提供了一個 header 元素來根據請求中的訊息頭內容縮小請求對映的範圍。

在可以指定 header 元素的值,用 myHeader = myValue 這樣的格式:

@RestController
@RequestMapping("/home")
public class IndexController {
    @RequestMapping(value = "/head", headers = {
        "content-type=text/plain"
    })
    String post() {
        return "Mapping applied along with headers";
    }
}

在上面這段程式碼中, @RequestMapping 註解的 headers 屬性將對映範圍縮小到了 post() 方法。有了這個,post() 方法就只會處理到 /home/head 並且 content-typeheader 被指定為 text/plain 這個值的請求。

你也可以像下面這樣指定多個訊息頭:

@RestController
@RequestMapping("/home")
public class IndexController {
    @RequestMapping(value = "/head", headers = {
        "content-type=text/plain",
        "content-type=text/html"
    }) String post() {
        return "Mapping applied along with headers";
    }
}

這樣, post() 方法就能同時接受 text/plain 還有 text/html 的請求了。

使用 @RequestMapping 來處理請求引數

@RequestMapping 直接的 params 元素可以進一步幫助我們縮小請求對映的定位範圍。使用 params 元素,你可以讓多個處理方法處理到同一個URL 的請求, 而這些請求的引數是不一樣的。

你可以用 myParams = myValue 這種格式來定義引數,也可以使用萬用字元來指定特定的引數值在請求中是不受支援的。

@RestController
@RequestMapping("/home")
public class IndexController {
    @RequestMapping(value = "/fetch", params = {
        "personId=10"
    })
    String getParams(@RequestParam("personId") String id) {
        return "Fetched parameter using params attribute = " + id;
    }
    @RequestMapping(value = "/fetch", params = {
        "personId=20"
    })
    String getParamsDifferent(@RequestParam("personId") String id) {
        return "Fetched parameter using params attribute = " + id;
    }
}

在這段程式碼中,getParams() 和 getParamsDifferent() 兩個方法都能處理相同的一個 URL (/home/fetch) ,但是會根據 params 元素的配置不同而決定具體來執行哪一個方法。

例如,當 URL 是 /home/fetch?id=10 的時候, getParams() 會執行,因為 id 的值是10,。對於 localhost:8080/home/fetch?personId=20 這個URL, getParamsDifferent() 處理方法會得到執行,因為 id 值是 20。

使用 @RequestMapping 處理動態 URI

@RequestMapping 註解可以同 @PathVaraible 註解一起使用,用來處理動態的 URI,URI 的值可以作為控制器中處理方法的引數。你也可以使用正則表示式來只處理可以匹配到正則表示式的動態 URI。

@RestController
@RequestMapping("/home")
public class IndexController {
    @RequestMapping(value = "/fetch/{id}", method = RequestMethod.GET)
    String getDynamicUriValue(@PathVariable String id) {
        System.out.println("ID is " + id);
        return "Dynamic URI parameter fetched";
    }
    @RequestMapping(value = "/fetch/{id:[a-z]+}/{name}", method = RequestMethod.GET)
    String getDynamicUriValueRegex(@PathVariable("name") String name) {
        System.out.println("Name is " + name);
        return "Dynamic URI parameter fetched using regex";
    }
}

在這段程式碼中,方法 getDynamicUriValue() 會在發起到 localhost:8080/home/fetch/10 的請求時執行。這裡 getDynamicUriValue() 方法 id 引數也會動態地被填充為 10 這個值。

方法 getDynamicUriValueRegex() 會在發起到 localhost:8080/home/fetch/category/shirt 的請求時執行。不過,如果發起的請求是 /home/fetch/10/shirt 的話,會丟擲異常,因為這個URI並不能匹配正則表示式。

@PathVariable 同 @RequestParam的執行方式不同。你使用 @PathVariable 是為了從 URI 裡取到查詢引數值。換言之,你使用 @RequestParam 是為了從 URI 模板中獲取引數值。

@RequestMapping 預設的處理方法

在控制器類中,你可以有一個預設的處理方法,它可以在有一個向預設 URI 發起的請求時被執行。

下面是預設處理方法的示例:

@RestController
@RequestMapping("/home")
public class IndexController {
    @RequestMapping()
    String
    default () {
        return "This is a default method for the class";
    }
}

在這段程式碼中,向 /home 發起的一個請求將會由 default() 來處理,因為註解並沒有指定任何值。

@RequestMapping 快捷方式

Spring 4.3 引入了方法級註解的變體,也被叫做 @RequestMapping 的組合註解。組合註解可以更好的表達被註解方法的語義。它們所扮演的角色就是針對 @RequestMapping 的封裝,而且成了定義端點的標準方法。

例如,@GetMapping 是一個組合註解,它所扮演的是 @RequestMapping(method =RequestMethod.GET) 的一個快捷方式。
方法級別的註解變體有如下幾個:

  • @GetMapping

  • @PostMapping

  • @PutMapping

  • @DeleteMapping

  • @PatchMapping

如下程式碼展示瞭如何使用組合註解:

@RestController
@RequestMapping("/home")
public class IndexController {
    @GetMapping("/person")
    public @ResponseBody ResponseEntity < String > getPerson() {
        return new ResponseEntity < String > ("Response from GET", HttpStatus.OK);
    }
    @GetMapping("/person/{id}")
    public @ResponseBody ResponseEntity < String > getPersonById(@PathVariable String id) {
        return new ResponseEntity < String > ("Response from GET with id " + id, HttpStatus.OK);
    }
    @PostMapping("/person")
    public @ResponseBody ResponseEntity < String > postPerson() {
        return new ResponseEntity < String > ("Response from POST method", HttpStatus.OK);
    }
    @PutMapping("/person")
    public @ResponseBody ResponseEntity < String > putPerson() {
        return new ResponseEntity < String > ("Response from PUT method", HttpStatus.OK);
    }
    @DeleteMapping("/person")
    public @ResponseBody ResponseEntity < String > deletePerson() {
        return new ResponseEntity < String > ("Response from DELETE method", HttpStatus.OK);
    }
    @PatchMapping("/person")
    public @ResponseBody ResponseEntity < String > patchPerson() {
        return new ResponseEntity < String > ("Response from PATCH method", HttpStatus.OK);
    }
}

在這段程式碼中,每一個處理方法都使用 @RequestMapping 的組合變體進行了註解。儘管每個變體都可以使用帶有方法屬性的 @RequestMapping 註解來互換實現, 但組合變體仍然是一種最佳的實踐 — 這主要是因為組合註解減少了在應用程式上要配置的元資料,並且程式碼也更易讀。

@RequestMapping 總結

如你在本文中所看到的,@RequestMapping 註解是非常靈活的。你可以使用該註解配置 Spring MVC 來處理大量的場景用例。它可以被用來在 Spring MVC 中配置傳統的網頁請求,也可以是 REST 風格的 Web 服務。


相關推薦

SpringMVC@RequestMapping 註解使用技巧

@RequestMapping 是 Spring Web 應用程式中最常被用到的註解之一。這個註解會將 HTTP 請求對映到 MVC 和 REST 控制器的處理方法上。 在這篇文章中,你將會看到 @RequestMapping 註解在被用來進行 Spring MVC 控

SpringMVC2. 註解@RequestMapping的使用

注意!!! 此文章需要配置了SpringDispatcherServlet和InternalResourceViewResolver才能夠使用,如果不會配置,請翻看我【SpringMVC】系列的第一篇文章《【SpringMVC】1. SpringMVC的第一個程

SpringMVC@Controller和@RequestMapping註解說明

一、@Controller註解 1、說明: 用於指示Spring類的例項是一個控制器,控制器可以支援同時處理多個請求動作。 2、保證Spring能找到控制器: (1)在SpringMVC的配置檔案的標頭檔案中引入spring-context (2)使用

SpringMVCSpringMVC常用註解

【[email protected]】        引用包:org.springframework.stereotype.Controller,使用Controller標識他是一個控制器 【2.@RequestMapping】 ①實

SpringMVC解決@ResponseBody註解返回中文亂碼

@ResponseBody @RequestMapping(value="/toPerBirthday.do") public String getIndexPerBasicInfo(HttpServletRequest request, HttpServletResponse response,M

springmvcspringmvc中如何上傳文件

doc 問題 ffffff color 遍歷 -c tip int imu 使用到的組件:可自行根據情況選擇版本 <!--上傳依賴包--> <dependency> <groupId

SpringMVC---搭建框架步驟

enc dex xmlns 4.3 base isp quest bind 得到 項目如下 一、加入 Jar 包 部分jar包可以不導(第4、9、11個可以不導入) 二、在 Web.xml 中配置 DispatcherServlet <?xml v

SpringMvc關於ModelAndAttribue

請求參數 lan 類名 nbsp 鍵值對 需要 ring 方法 springmvc   用在方法上,表示執行該控制器類的每個方法前,先執行這個方法,對Model進行操作(即會直接影響傳入方法的Model) 用在入參上,可以指定入參的key (如果不指定,則默認

SpringMVC數據校驗時,拋出javax.validation.UnexpectedTypeException: HV000030: No validator could be found for type: java.util.Date.

springmvc 去掉 not orm align found 包括 text expect 老魏原創,轉載請留言。 原因:給Javabean中的字段註解多余或者錯誤導致。 @NotEmpty @Past @DateTimeFormat(pattern="yy

位運算技巧

返回 左移 得到 blog int pan color get post 1 int getbit(int c,int i)//獲取c這個數字第i位的bit是什麽 2 { 3 return ((c>>(i-1))&1);//將c右移i-

springmvc傳值的幾種方式&&postman接口測試

red ews 參數 一點 名稱 each comment PQ 分享圖片 最近在用postman測試postman接口,對於springmvc傳值這一塊,測試了幾種常用方式,總結一下。對於postman這個工具的使用也增加了了解。p

JMeter教程及技巧匯總(轉載)

cti iba 免費開源 支持 ide 討論板 處理器 strong 為什麽 轉載地址:http://www.hissummer.com/jmeter-summary.html 參考/學習資料:http://www.yiibai.com/jmeter/jmeter_buil

TestNGTestNG註解@Factory的使用說明

當通過testng.xml或命令列把測試類傳遞給TestNG時,TestNG會呼叫這些測試類的無參構造方法,將這些類例項化,然後執行在每個類中的測試方法。 如果假設某個測試類中構造方法是有參的,那麼執行時,TestNG會報出TestNGException異常,因為無法初始化這個類(該類沒

SpringMvc從零開始學SpringMvc之資料庫(二)

大家好,在上一篇中,我們介紹了SpringMvc 的搭建,這篇我們來看下SpringMvc連線資料庫。 【SpringMvc】從零開始學SpringMvc之初始化(一) 準備 首先, 需要安裝Mysql、Navicat(或者類似軟體)、有一點sql基礎,瞭解一點

SpringMvc從零開始學SpringMvc之初始化(一)

大家好,我們今天開始SpringMvc 這個系列,由於筆者也是安卓出身,對SpringMvc 也是接觸不久,所以,這個系列僅僅只是記錄筆者學習SpringMvc 過程中的心得,如有錯誤,歡迎指正。 在開始之前,我們需要準備一些東西,JDK、Eclipse(MyEclipse)、Tom

SpringMvc從零開始學SpringMvc之實現使用者登入(三)

大家好,在前2篇中,我們實現了SpringMvc的配置和資料庫連線,這一篇我們來用html/ajax實現一個簡單的登入功能。 【SpringMvc】從零開始學SpringMvc之初始化(一) 【SpringMvc】從零開始學SpringMvc之資料庫(二) 準

Spring@Autowired註解Field injection is not recommended

參考文章:http://vojtechruzicka.com/field-dependency-injection-considered-harmful/     首先對於還不熟悉@Autowired的同學當然也包括我先去看看它到底有什麼作用。—

spring註解程式設計模型

原文連結: https://github.com/spring-projects/spring-framework/wiki/Spring-Annotation-Programming-Model#stereotype-annotations 原文連結: https://github.

spring註解編程模型

例如 以及 ref 功能 隱式 詳細信息 另一個 type 常見 原文鏈接: https://github.com/spring-projects/spring-framework/wiki/Spring-Annotation-Programming-Model#ster

SpringMVC6.SpringMVC的檢視和檢視解析器

注意!!! 此文章需要配置了SpringDispatcherServlet和InternalResourceViewResolver才能夠使用,如果不會配置,請翻看我【SpringMVC】系列的第一篇文章《【SpringMVC】1. SpringMVC的第