spring MVC註解深入研究

可健康了發表於2016-09-05

@Controller @Service  @Controller和 @Component
註冊一個action 到spring 上下文中,bean 的ID 預設為類名稱開頭字母小寫。
@Repository、@Service 和@Controller。這 3 個註解和 @Component 是等效的,但是從註解類的命名上,很容易看出這 3 個註解分別和持久層、業務層和控制層(Web 層)相對應。雖然目前這 3 個註解和 @Component 相比沒有什麼新意,但 Spring 將在以後的版本中為它們新增特殊的功能。所以,如果 Web 應用程式採用了經典的三層分層結構的話,最好在持久層、業務層和控制層分別採用@Repository、@Service 和 @Controller 對分層中的類進行註解,而用 @Component 對那些比較中立的類進行註解。

 例:

@Controller
public class Apple extends Friut {}

 

@Autowired
以byType的方式對類成員變數、方法及建構函式進行標註,完成自動裝配的工作。Spring 將直接採用 Java 反射機制對 類 中的 私有成員變數進行自動注入。所以對成員變數使用 @Autowired 後,可將它們的getter和setter 方法刪除。
例:

public class Boss { 
@Autowired 
private Car car; 

@Autowired 
private Office office; 
}

 

也可以對set方法和建構函式使用@ Autowired註解 ,等同於上文

public class Boss { 
  private Car car; 
  private Office office; 

  @Autowired 
  public void setCar(Car car) { 
    this.car = car; 
  } 

  @Autowired 
  public void setOffice(Office office) { 
    this.office = office; 
  } 
}

public class Boss { 
  private Car car; 
  private Office office; 

  @Autowired 
  public Boss(Car car ,Office office){ 
    this.car = car; 
    this.office = office ; 
  } 
}

 

如何使用Autowired 的required引數

@Autowired(required = false) 
public void setOffice(Office office) { 
  this.office = office; 
}

一般情況下,使用 @Autowired 的地方都是需要注入 Bean 的,使用了自動注入而又允許不注入的情況一般僅會在開發期或測試期碰到(如為了快速啟動 Spring 容器,僅引入一些模組的 Spring 配置檔案),所以 @Autowired(required = false) 會很少用到。

 

@Resource
@Resource 的作用相當於 @Autowired,只不過 @Autowired 按 byType 自動注入,而 @Resource 預設按 byName 自動注入。@Resource 有兩個屬性是比較重要的,分別是 name 和 type,Spring 將 @Resource 註解的 name 屬性解析為 Bean 的名字,而 type 屬性則解析為 Bean 的型別。所以如果使用 name 屬性,則使用 byName 的自動注入策略,而使用 type 屬性時則使用 byType 自動注入策略。如果既不指定 name 也不指定 type 屬性,這時將通過反射機制使用 byName 自動注入策略。
例:

public class Boss { 
  // 自動注入型別為 Car 的 Bean 
  @Resource 
  private Car car; 

  // 自動注入 bean 名稱為 office 的 Bean 
  @Resource(name = "office") 
  private Office office; 
}

 

@PostConstruct 和 @PreDestroy
只需要在方法前標註 @PostConstruct 或 @PreDestroy,這些方法就會在 Bean 初始化後或銷燬之前被 Spring 容器執行, 常用於對靜態變數的處理

public class Boss { 
  private static Car car = initCar(); 

  @Resource(name = "office") 
  private Office office; 

  @PostConstruct 
  public void initCar(){ 
    System.out.println("postConstruct1"); 
  } 

  @PreDestroy 
  public void preDestroy1(){ 
    System.out.println("preDestroy1"); 
  } 
}

 

@RequestMapping
將URL對映到類或方法上。

@RequestMapping(value="/car")
public class Car { 
  @RequestMapping(value="/getName")
  public String myCarName(){
    return “audi”;
  }
} 

通過http://{ ip:port/上下文}/car/getName 來請求該方法

當它定義在類級別時,標明該控制器處理所有的請求都被對映到 /car路徑下。@RequestMapping中可以使用 method 屬性標記其所接受的方法型別,如果不指定方法型別的話,可以使用 HTTP GET/POST 方法請求資料,但是一旦指定方法型別,就只能使用該型別獲取資料。支援方法共有四種:GET, POST, PUT, DELETE

@RequestMapping(value="/getName", method = RequestMethod.GET)
public String getName(String userName) {
  return userName;
}

 

繫結 @RequestMapping引數
使用 @PathVariable 註解方法引數並將其繫結到URI模板變數的值上

@RequestMapping(value="/departments/{departmentId}/employees/{employeeId}") 
public String findEmployee( @PathVariable String departmentId, 
                 @PathVariable String employeeId){ 

  System.out.println("Find employee with ID: " + employeeId + 
  " from department: " + departmentId); 
  return "someResult"; 
}

 

支援正規表示式

@RequestMapping(value="/{textualPart:[a-z-]+}.{numericPart:[\\d]+}") 
public String regularExpression( @PathVariable String textualPart, 
                    @PathVariable String numericPart){ 

  System.out.println("Textual part: " + textualPart + ", numeric part: " + numericPart); 
  return "someResult"; 
}

 

@RequestParam
可以把請求引數傳遞給請求方法
例: http://{ ip:port/上下文}/car/getName?ownerId=5

@RequestMapping(value="/car")
public class Car { 
  @RequestMapping(value
="/getName")   public String myCarName(@RequestParam("ownerId") int ownerId){     return “audi”;   } }

 

@ModelAttribute
@ModelAttribute有三種用法:
1、註解方法
當它作用在方法上時,標明該方法的目的是新增一個或多個模型屬性(model attributes)。該方法支援與@RequestMapping一樣的引數型別,但並不能直接對映成請求。controller中的@ModelAttribute方法會在所有@RequestMapping方法呼叫之前而呼叫,因此要小心使用。

利用這個特徵進行許可權驗證, index方法執行之前會先執行preRun方法

@Controller
@RequestMapping(value="/test")
public class PassportController {
  @ModelAttribute
  public void preRun() {
    if(user != “admin”){
      throw Exception(“沒有許可權”);
    }
  }
  @RequestMapping(method=RequestMethod.GET)
  public String index() {
    return "login/index";
  } 
}

2、註解方法中的入參
用於將多個請求引數繫結到一個命令物件,將這個物件新增到request作用域,從而簡化繫結流程,而且自動暴露為模型資料用於jsp展示時使用

@RequestMapping(value="test")
public String test(@ModelAttribute("user") UserModel user){
  User.setName(“aaa”);
}

此時可以在檢視頁面使用${user.name}來獲取繫結的命令物件的屬性

 

3、註解方法的返回值,效果同上,將返回值新增到request作用域,jsp頁面中可以通過${user.name}的方式直接呼叫,@ModelAttribute 註解的返回值會覆蓋@RequestMapping 註解方法中的@ModelAttribute 註解的同名命令物件。

public @ModelAttribute("user2") UserModel test3(@ModelAttribute("user2") UserModel user) 

 

@RequestBody
讀取Request請求的body部分資料,使用系統預設配置的HttpMessageConverter進行解析,然後把相應的資料繫結到要返回的物件上 ,再把HttpMessageConverter返回的物件資料繫結到 controller中方法的引數上。

 

@ResponseBody
將Controller的方法返回的物件,通過適當的HttpMessageConverter轉換為指定格式後,寫入到Response物件的body資料區。

 

@ExceptionHandler和@ControllerAdvice
@ExceptionHandler 註解到方法上,出現異常時會執行該方法。 @ControllerAdvice 使一個Contoller成為全域性的異常處理類,類中用@ExceptionHandler方法註解的方法可以處理所有Controller發生的異常。

 

@RestController (spring 3.1 以上)
使一個類以Rest風格返回請求資料, 它與@Controller的差別在於使用@Controller標註的類別最後會回傳一個String,然後透過viewResolver組裝出完整的view page路徑後將這個view呈現在前端頁面中。而使用 @RestController標註表示此類別最後會回傳一個POJO物件而非一個頁面,因此也不需要透過viewResolver來幫忙組裝回傳值。
通過jackson套件,可以將RestController回傳的domain物件以JSON或XML格式的方式返回前端。

@RestController
public class HelloWorldRestController {
   
   @RequestMapping("/hello/{player}")
   public Message message(@PathVariable String player) {
        Message msg = new Message(player, "Hello, " + player);
     return msg;
   }
}

 

VO欄位驗證
@AssertFalse
驗證的資料型別 :Boolean,boolean
說明 :驗證註解的元素值是false


@AssertTrue
驗證的資料型別 :Boolean,boolean
說明 :驗證註解的元素值是true


@NotNull
驗證的資料型別 :任意型別 
說明 :驗證註解的元素值不是null


@Null
驗證的資料型別 :任意型別 
說明 :驗證註解的元素值是null


@Min(value=值)
驗證的資料型別 :BigDecimal,BigInteger, byte,short, int, long,等任何Number或CharSequence(儲存的是數字)子型別 
說明 :驗證註解的元素值大於等於@Min指定的value值


@Max(value=值)
驗證的資料型別 :和@Min要求一樣 
說明 :驗證註解的元素值小於等於@Max指定的value值


@DecimalMin(value=值)
驗證的資料型別 :和@Min要求一樣
說明 :驗證註解的元素值大於等於@ DecimalMin指定的value值


@DecimalMax(value=值)
驗證的資料型別 :和@Min要求一樣
說明 :驗證註解的元素值小於等於@ DecimalMax指定的value值


@Digits(integer=整數位數, fraction=小數位數)
驗證的資料型別 :和@Min要求一樣
說明 :驗證註解的元素值的整數位數和小數位數上限


@Size(min=下限, max=上限)
驗證的資料型別 :字串、Collection、Map、陣列等
說明 :驗證註解的元素值的在min和max(包含)指定區間之內,如字元長度、集合大小


@Past
驗證的資料型別 :java.util.Date,java.util.Calendar,Joda Time類庫的日期型別
說明 :驗證註解的元素值(日期型別)比當前時間早


@Future
驗證的資料型別 :與@Past要求一樣
說明 :驗證註解的元素值(日期型別)比當前時間晚


@NotBlank
驗證的資料型別 :CharSequence子型別
說明 :驗證註解的元素值不為空(不為null、去除首位空格後長度為0),不同於@NotEmpty,@NotBlank只應用於字串且在比較時會去除字串的首位空格


@Length(min=下限, max=上限) 
驗證的資料型別 : CharSequence子型別
說明 :驗證註解的元素值長度在min和max區間內


@NotEmpty
驗證的資料型別 :CharSequence子型別、Collection、Map、陣列
說明 :驗證註解的元素值不為null且不為空(字串長度不為0、集合大小不為0)


@Range(min=最小值, max=最大值)
驗證的資料型別 :BigDecimal,BigInteger,CharSequence, byte, short, int, long等原子型別和包裝型別
說明 :驗證註解的元素值在最小值和最大值之間


@Email(regexp=正規表示式,flag=標誌的模式)
驗證的資料型別 :CharSequence子型別(如String)
說明 :驗證註解的元素值是Email,也可以通過regexp和flag指定自定義的email格式


@Pattern(regexp=正規表示式,flag=標誌的模式)
驗證的資料型別 :String,任何CharSequence的子型別
說明 :驗證註解的元素值與指定的正規表示式匹配


@Valid
驗證的資料型別 :任何非原子型別
說明 :指定遞迴驗證關聯的物件;如使用者物件中有個地址物件屬性,如果想在驗證使用者物件時一起驗證地址物件的話,在地址物件上加@Valid註解即可級聯驗證

相關文章