註解之 @RestController 和 @RequestMapping

        Controller 是 Spring 中最基本的組件,主要處理用戶交互,一般每個業務邏輯都會有一個 Controller,供用戶請求接口進行數據訪問;@RequestMapping 註解用於綁定URI到具體處理器。二者相輔相成,共同完成前後端數據交互。

一、簡介

       本文軟件環境:

IntelliJ IDEA version:2018.3
Spring Boot version: 2.1.4.RELEASE;
Java version:1.8。

        Controller 是 Spring 中最基本的組件,主要處理用戶交互,一般每個業務邏輯都會有一個 Controller,供用戶請求接口進行數據訪問。

        在Spring MVC 中,控制器Controller 負責處理由DispatcherServlet 分發的請求,它把用戶請求的數據經過業務層處理之後封裝成一個Model ,然後再把該Model 返回給對應的View 進行展示。Spring MVC 提供了一個非常簡便的定義Controller 的方法,你無需繼承特定的類或實現特定的接口,只需使用@Controller 標記一個類即可,然後使用@RequestMapping 和@RequestParam 等一些註解以定義URL 請求和Controller 方法之間的映射,這樣Controller 就能被外界訪問到。此外Controller 不會直接依賴於HttpServletRequest 和HttpServletResponse 等HttpServlet 對象。

        @RequestMapping 註解可謂非常的強大,Spring MVC 和 Spring Boot 中都會用到這個註解。要學會 @RequestMapping 的用法,就需要從它的原理和實現機制說起,本文就和讀者朋友們一起扒一扒Spring Boot中 @RequestMapping 的神祕面紗。

爲了先對Controller 有一個初步的印象,我們定義一個簡單的UserController:

       例1 控制器類UserController

複製代碼

@Controller
@RequestMapping("/user")
public class UserController {
    private static Logger logger = LoggerFactory.getLogger(UserController.class);
    /**
     * 示例地址 http://localhost:8087/user/viewUser?ownerId=100
     *
     * @author Wiener
     * @date 2019/5/8 11:27
     */
    @RequestMapping("/viewUser")
    @ResponseBody
    public User viewUser(Long ownerId) {
        logger.info("請求參數 ownerId = " + ownerId);
        User user = new User();
        user.setId(ownerId);
        user.setName(" --> Lucy");
        return user;
    }
}
// 定義User Bean
public class User {
    private Long id;
    private String name;
  
    // omit getter、setter and toString
}

複製代碼

        在上述示例中,@Controller 是標記在類UserController上面的,所以此類就是一個控制器類對象了。使用@RequestMapping("/user")標記控制器,用@RequestMapping(“/viewUser”) 標記方法,表示當請求“/user/viewUser”的時候訪問的是UserController的viewUser方法,它返回了一個User 對象。這些在下文將會詳細介紹。

二、@RestController介紹

        在例1中,被@Controller標記的類就是一個Spring Boot Controller 對象。分發處理器將會掃描使用了該註解的類的方法,並檢測該方法是否使用了@RequestMapping 註解。@Controller只是定義了一個控制器類,而使用@RequestMapping 註解的方法纔是真正處理請求的處理器,這個接下來就會講到。

在Spring Boot Web項目中,單單使用@Controller 標記在一個類上就可以把這個控制器類交給Spring 來管理,無需額外配置。

       @RestController:Spring 4 新增註解,同樣可以註解 Controller 類,相當於@Controller + @ResponseBody,主要是爲了使 http 請求返回 json 或者xml格式數據,一般情況下都是使用這個註解。下文都基於此註解進行驗證。

三、@RequestMapping 配置URI映射

        要配置 Web 請求的映射,就需要用上 @RequestMapping 註解。@RequestMapping 註解可以在控制器類的級別和/或其中的方法的級別上使用。在類級別上的註解會將一個特定請求或者請求模式映射到一個控制器之上,之後還可以添加方法級別的註解來進一步綁定與具體處理方法的映射關係。類上的 “請求地址”是方法上的“請求地址”的父地址。

        在例1中,因爲UserController被@RequestMapping 標記,所以當訪問被@RequestMapping 標記的viewUser方法時,需要使用相對路徑“/user/viewUser”請求;如果去掉“/user”,使用絕對路徑“/viewUser”就可以了。

       @RequestMapping 註解的源碼:

複製代碼

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Mapping
public @interface RequestMapping {
    String name() default "";
    String[] value() default {};
    String[] path() default {};
    RequestMethod[] method() default {};
    String[] params() default {};
    String[] headers() default {};
    String[] consumes() default {};
    String[] produces() default {};
}

複製代碼

     註解@Target有兩個屬性,分別爲 ElementType.METHOD 和 ElementType.TYPE,這表明@RequestMapping註解可以添加在類級別和方法級別上。

     @RequestMapping 註解中的屬性除了 name 返回類型是字符串,其它的方法均返回數組,也就是可以定義多個屬性值。此處name屬性,相當於方法的註釋,使方法更易理解。

四、@RequestMapping屬性介紹

        在RequestMapping 中除了指定請求路徑value 屬性外,還有其它的屬性可以指定,如params 、method 和headers 。這些屬性都可以達到縮小請求的映射範圍的目的。

  1. value屬性

        指定request的地址。在例1中,value="/viewUser",使用了value的簡寫方式。

        value 屬性支持有佔位符的路徑,此時需要結合@PathVariable註解,詳見《註解之@PathVariable》。

        value 屬性支持ANT風格的路徑。

        例2 ANT風格的路徑和多URI配置

複製代碼

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

複製代碼

         前面這段代碼中,如下的這些 URI 都會由 indexMultipleMapping() 來處理:

localhost:8080/home
localhost:8080/home/page
localhost:8080/home/pageabc
localhost:8080/home/view/
localhost:8080/home/view/view
localhost:8080/home/view2/msg

      這個示例同時說明了可以將多個請求映射到一個方法上去,只需要添加一個帶有請求路徑值列表的 @RequestMapping 註解就行了。

  1. params屬性

        用於定義請求的 URL 中必須包含的參數,或者不包含某些參數。

       例3 限定@RequestMapping 的params屬性

@RequestMapping (value= "/testParams" , params={ "param1=value1" , "param2" , "!param3" })
 public String testParams() {
       System. out .println( "test Params..........." );
       return "testParams" ;
}

        在上面的代碼中,我們用@RequestMapping 的params 屬性指定了三個參數,這些參數都是針對請求參數而言的,它們分別表示參數param1 的值必須等於value1,param2 必須存在,值無所謂,param3 必須不存在,只有當請求“/testParams”並且滿足指定的三個參數條件的時候才能訪問到該方法。所以當請求/testParams?param1=value1&param2=value2 的時候testParams函數能夠正確響應;當請求/testParams?param1=value1&param2=value2&param3=value3 的時候就無響應,因爲在@RequestMapping 的params 參數裏面指定了參數param3 是不能存在的。

  1. method屬性

        屬性類型包括GET, POST, HEAD, OPTIONS, PUT, PATCH, DELETE和TRACE等八種。可以爲多個方法映射相同的URI,Spring MVC 根據請求的 method 類型識別這些方法。若是沒指定method,則它可以處理method任何類型的請求,此時它的映射範圍是最大的。指定 method 是爲了細化映射,縮小處理方法的映射範圍。在例1中,函數viewUser可以響應get和post等請求。

        例4 設置get和delete請求

@RequestMapping (value= "testMethod" , method={RequestMethod. GET , RequestMethod. DELETE })
public String testMethod() {
       return "method" ;
}

        在上面的代碼中就使用method 參數限制請求方式,以GET 或DELETE 方法請求/testMethod 的時候才能訪問testMethod 方法。

  1. headers屬性

        用 myHeader = myValue 這樣的格式指定 header 元素的值。

       例5 header 屬性

    @RequestMapping (value= "testHeaders" , headers={ "host=localhost" , "Accept" })
    public String testHeaders() {
       return "headers" ;
    }

        在上面的代碼中當請求/testHeaders 的時候只有當請求頭包含Accept 信息,且請求的host 爲localhost 的時候才能正確的訪問到testHeaders 方法。

  1. produces和consumes屬性

        用來限定請求的媒體類型,二者用法類似,下面以consumes屬性爲例。此測試用例僅僅可以同時處理post請求中的 JSON 和 XML 內容。

       例6 consumes屬性

複製代碼

    @PostMapping(value = "/cons", consumes = {
            "application/JSON",
            "application/XML"
    })
    public User getConsumes(Long ownerId) {
        User user = new User();
        user.setId(ownerId);
        user.setName("Consumes attribute --> Lucy");
        return user;
    }

複製代碼

 

Reference

https://www.cnblogs.com/jpfss/p/8047628.html

Using the Spring @RequestMapping Annotation

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章