天天看點

Spring MVC 中的常用注解整理@Controller@Component@Repository@RequestMapping@Resource 和 @Autowired@PathVariable@RequestHeader@CookieValue@RequestParam@RequestBody@ResponseBody@ExceptionHandler@ControllerAdvice@InitBinder

現将

Spring MVC

中常用注解的使用整理如下.

@Controller

@Controller

注解可以标記一個類, 指明該類是一個控制器(Controller).

要想使

Spring

能夠識别出使用

@Controller

标記的類使一個控制器, 還需要進行相應的配置, 有兩種配置方式:

1、在

Spring MVC

的配置檔案中定義一個

MyController(這是我們自定義的控制器,用@Controller标記)

bean

對象.

<bean class="com.tao.myapp.web.controller.MyController"/>
           

2、 在

Spring MVC

的配置檔案中開啟注解自動掃描, 讓

Spring

自動的去指定的包下面掃描

@Controller

注解的類.

<context:component-scan base-package="com.tao.myapp.web.controller"/>
           

context:component-scan

預設掃描的注解類型是

@Component

, 不過, 在

@Component

語義基礎上細化後的

@Repository

,

@Service

@Controller

也同樣可以被

context:component-scan

掃描識别.

@Component

這個注解是一個通用的注解, 表示

Spring

中的一個元件, 當我們不太清楚一個類要歸到哪個層的元件中去的時候,可以使用這個注解, 不過通常

不建議使用

.

@Repository

這個注解用于

dao

層, 通常注解到

daoImpl

類上面.

@RequestMapping

這個注解是一個用來處理請求位址映射的注解, 可用于類或方法上. 用于類上, 表示類中的所有響應請求的方法都是以該位址作為父路徑; 用于方法上, 表示特定而url請求将會被該方法處理.

@RequestMapping

的屬性如下:

1、

value

method

  • value: 指定請求的

    url

    路徑. 在使用的時候

    value

    字段可以省略,

    url

    用引号括起來.

    value

    還支援通配符

    "*"

    "**"

    .
@Controller  
@RequestMapping("/myapp")  
public class MyController {  

    /** 可以通過 http://localhost:8080/myapp/haha/test 通路 */
    @RequestMapping("*/test")  
    public String test() {  
       System. out .println( "-----myapp test-----" );  
       return "test" ;  
    }  
}  
           
  • method: 指定請求的

    method

    類型,

    GET

    POST

    PUT

    DELETE

    等. 也可以通過

    @GetMapping

    @PostMapping

    等注解替換.
@RequestMapping(value = "/testMethod" , method = {RequestMethod.GET, RequestMethod.DELETE})
    public String testMethod() {  
       return "method";  
    } 
           

2、

consumes

produces

  • consumes: 指定請求的送出的内容的類型(

    Content-Type

    ), 例如

    application/json

    ,

    text/html

    .
  • produces: 指定傳回的内容類型, 僅當

    request

    請求頭中的(

    Accept

    )類型中包含該指定類型才傳回.

3、

params

headers

  • params: 指定

    request

    中必須包含某些參數值時, 才讓該方法處理.
@RequestMapping(value = "/testParams", params = {"param1=value1", "param2", "!param3"})
    public String testParams() {  
       System.out.println("-----------test Params-----------");  
       return "testParams";  
    }  
           

如上例所示,

params

屬性指定了三個參數, 這些參數都是針對請求參數而言的, 它們分别表示參數

param1

的值必須等于

value1

; 參數

param2

必須存在, 值無所謂; 參數

param3

必須不存在. 隻有當請求

/testParams

并且滿足指定的三個參數條件的時候才能通路到該方法. 是以當請求

/testParams?param1=value1&param2=value2

的時候能夠正确通路到該

testParams()

方法, 當請求

/testParams?param1=value1&param2=value2&param3=value3

的時候就不能夠正常的通路到該方法. 因為在

params

參數裡面指定了參數

param3

是不能存在的.

  • headers: 指定

    request

    中必須包含某些指定的

    header

    值, 才能讓該方法處理請求.
@RequestMapping(value = "/testHeaders" , headers = {"host=localhost" ,"Accept"})
    public String testHeaders() {  
       return "headers";  
    }  
           

headers

屬性的用法和功能與

params

屬性相似.

在上面的代碼中當請求

/testHeaders

的時候, 隻有當請求頭包含

Accept

資訊, 且請求的

host

localhost

的時候才能正确的通路到

testHeaders()

方法.

@Resource

@Autowired

@Resource

@Autowired

都是做

bean

的注入時使用.

@Resource

不是

Spring

的注解, 它的包是

javax.annotation.Resource

.

兩者都可以寫在字段和setter方法上. 兩者如果都寫在字段上, 那麼就不需要再寫setter方法.

1、

@Autowired

@Autowired

Spring

提供的注解, 所在的包為

org.springframework.beans.factory.annotation.Autowired

.

@Autowired

注解是按照類型(

byType

) 裝配依賴對象的, 預設情況下它要求依賴對象必須存在, 如果允許null值, 可以設定它的

required

屬性為

false

. 如果我們想使用按照名稱(

byName

) 來裝配, 可以結合

@Qualifier

注解一起使用.

2、

@Resource

@Resource

預設按照名稱(

byName

) 來自動注入.

@Resource

有兩個重要的屬性:

name

type

.

Spring

@Resource

注解的

name

屬性解析為

bean

的名字, 而

type

屬性則解析為

bean

的類型. 是以, 如果使用

name

屬性, 則使用

byName

的自動注入政策; 而使用

type

屬性時則使用

byType

自動注入政策. 如果既不指定

name

也不指定

type

屬性, 這時将通過反射機制使用

byName

自動注入政策.

最好是将

@Resource

放在

setter

方法上, 因為這樣更符合面向對象的思想, 通過

set

get

去操作屬性, 而不是直接去操作屬性.

@Resource

的作用相當于

@Autowired

, 隻不過

@Autowired

預設是按照

byType

自動注入.

@PathVariable

這個注解用于将請求

url

中的模闆變量映射到處理方法的參數上, 也就是說從請求的路徑上取出需要的參數.

@Controller    
    public class TestController {    

        @RequestMapping(value = "/user/{userId}/roles/{roleId}", method = RequestMethod.GET)
        public String getLogin(
            @PathVariable("userId") String userId, 
            @PathVariable("roleId") String roleId) {

            System.out.println("User Id : " + userId);
            System.out.println("Role Id : " + roleId);
            return "hello";
        }

        @RequestMapping(value = "/javabeat/{regexp1:[a-z-]+}", method = RequestMethod.GET)    
        public String getRegExp(@PathVariable("regexp1") String regexp1) {    

            System.out.println("URI Part 1 : " + regexp1);
            return "hello";
        }    
    }  
           
@Controller  
    @RequestMapping("/test/{variable1}")  
    public class MyController {  

        @RequestMapping("/showView/{variable2}")  
        public ModelAndView showView(
            @PathVariable("variable1") String variable1, 
            @PathVariable("variable2") int variable2) {

        ModelAndView modelAndView = new ModelAndView();  
        modelAndView.setViewName("viewName");  
        modelAndView.addObject("需要放到 model 中的屬性名稱", "對應的屬性值,它是一個對象");  
        return modelAndView;  
        }  
    }  
           

@RequestHeader

這個注解可以将

Request

請求(

HTTP請求

)中的

header

請求頭部分的屬性值綁定到處理方法的參數上.

Host                    localhost:    
Accept                  text/html,application/xhtml+xml,application/xml;q=    
Accept-Language         fr,en-gb;q=,en;q=    
Accept-Encoding         gzip,deflate    
Accept-Charset          ISO--,utf-;q=,*;q=    
Keep-Alive                  


    @RequestMapping("/displayHeaderInfo")      
    public void displayHeaderInfo(
        @RequestHeader("Accept-Encoding") String encoding, 
        @RequestHeader("Keep-Alive") long keepAlive) {

        System.out.println("Accept-Encoding : " + encoding);
        System.out.println("Keep-Alive : " + keepAlive);
    }    
           

上面的代碼, 通過使用

@RequestHeader

header

部分的

Accept-Encoding

的值綁定到參數

encoding

上了; 把

Keep-Alive

的值綁定到參數

keepAlive

上了.

@CookieValue

這個注解可以将

Request

請求(

HTTP請求

)的

header

頭部資訊中關于

Cookie

的值綁定到方法的參數上.

假設有如下

Cookie

值:

JSESSIONID=415A4AC178C59DACE0B2C9CA727CDD84

@RequestMapping("/displayHeaderInfo")
    public void displayHeaderInfo(@CookieValue("JSESSIONID") String cookie) {

        System.out.println("Cookie : " + cookie);
    }
           

@RequestParam

這個注解主要用于在

Spring MVC

背景控制層擷取請求參數.

通常在

Controller

中擷取請求參數有兩種方法:

1. request.getParameter(“參數名”)

2. 使用

@RequestParam

注解

@RequestParam

有三個常用參數:

value = “isApp”, required = false, defaultValue = “0”
  • value

    : 參數名字, 即前端傳入的請求中參數的名字.
  • required

    : 是否必須, 預設是true, 表示請求中一定要有相應的參數, 否則将報404錯誤碼.
  • defaultValue

    : 參數的預設值, 表示如果請求中沒有同名參數時的預設值, 預設值可以是SpEL表達式, 如“

    #{systemProperties['java.vm.version']}

    ”.

假設請求的url為

localhost:8080/myapp/test/?userName=zhangsan

@GetMapping("/requestParm")
    public void getRequestParm(@RequestParam(value = "username", required = false, defaultValue = "admin") String username) {

        System.out.println("username : " + username);
    }
           
注意: 如果設定了

defaultValue

的值, 它将預設的設定

required

的值為

false

.

@RequestBody

這個注解用于将

Controller

的方法參數, 根據

HTTP Request Header

Content-Type

的内容, 通過适當的

HttpMessageConverter

轉換為

Java

類.

POST

或者

PUT

的資料是

JSON

格式或者

XML

格式, 而不是普通的鍵值對形式的時候使用這個注解.

@RequestMapping(value = "/testRequestBody", method = RequestMethod.POST)
    @ResponseBody
    public Person testRequestBody(@RequestBody Person p) {

        System.out.println("creating a person : " + p);
        return p;
    }
           

對應的前端

ajax

請求:

$.ajax({
        url: "testRequestBody",
        data: '{"name":"小紅","age":12}', //要用雙引号!!
        contentType: "application/json;charset=utf-8", // 因為上面是json資料

        type: "POST",
        headers: {
            // Accept: "application/xml",
            Accept: "application/json",
        },
        success: function (data, textStatus) {
            console.log(data);
            alert(data);
        },
        error: function (data, textStatus, errorThrown) {
            console.log(data);
        },
    });
           

@ResponseBody

該注解用于将

Controller

的方法傳回的對象, 根據

HTTP Request Header

Accept

的内容, 通過适當的

HttpMessageConverter

轉換為指定格式後, 寫入到

Response

對象的

body

資料區.

當傳回的資料不是

html

标簽的頁面, 而是其他某種格式的資料時( 如

json

xml

等 )使用.

@ExceptionHandler

注解到方法上,出現異常時會執行該方法.

@ControllerAdvice

這個注解能夠使一個

Contoller

成為全局的異常處理類, 類中用

@ExceptionHandler

注解的方法可以處理所有

Controller

發生的異常.

@ControllerAdvice  
    public class GlobalExceptionHandler {

        private final Logger logger = LoggerFactory.getLogger(getClass());  

        @ExceptionHandler(BusinessException.class)
        @ResponseBody
        public ResponseMsg businessError(BusinessException exception) {

            logger.info("Request raised a BusinessException, business code is {}", exception.getCode());
            return new ResponseMsg(exception.getCode(), exception.getMessage());
        }

        @ExceptionHandler(Exception.class)
        @ResponseBody
        public ResponseMsg sysError(Exception exception) {

            String msg = "出錯了";
            if(exception instanceof MaxUploadSizeExceededException) {
                msg = "上傳檔案過大";  
            }
            //exception.printStackTrace();
            logger.error("Request raised " + exception.getClass().getSimpleName(), exception);
            return new ResponseMsg(GeneralConst.SYS_ERROR, msg);
        }
    }  
           

@InitBinder

使用

@InitBinder

來處理Date類型的參數.

//the parameter was converted in initBinder
    @RequestMapping("/date")
    public String date(Date date) {
        System.out.println(date);
        return "hello";
    }

    //At the time of initialization,convert the type "String" to type "date"
    @InitBinder
    public void initBinder(ServletRequestDataBinder binder) {
        binder.registerCustomEditor(Date.class, new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd"), true));
    }
           

參考:

https://blog.csdn.net/chenpeng19910926/article/details/70837756

繼續閱讀