springmvc 注解總結


引用自:https://www.cnblogs.com/xiaoxi/p/5718894.html

 

1、@RequestMapping
@RequestMapping
RequestMapping是一個用來處理請求地址映射的注解(將請求映射到對應的控制器方法中),可用於類或方法上。用於類上,表示類中的所有響應請求的方法都是以該地址作為父路徑。
RequestMapping請求路徑映射,如果標注在某個controller的類級別上,則表明訪問此類路徑下的方法都要加上其配置的路徑;最常用是標注在方法上,表明哪個具體的方法來接受處理某次請求。

復制代碼
@Controller
@RequestMapping(value="/book")
public class BookController {
    @RequestMapping(value="/title")
    public String getTitle(){
        return "title";
    }           
    
    @RequestMapping(value="/content")
    public String getContent(){
        return "content";
    } 
} 
復制代碼

由於BookController類加了value="/book"的@RequestMapping的注解,所以相關路徑都要加上"/book",即請求的url分別為:
(1)http://localhost:8080/book/title 
(2)http://localhost:8080/book/content
"@RequestMapping"的value值前后是否有“/”對請求的路徑沒有影響,即value="book" 、"/book"、"/book/"其效果是一樣的。

RequestMapping的屬性
value:指定請求的實際url
(1)普通的具體值。如前面的value="/book"。
(2)含某變量的一類值。

@RequestMapping(value="/get/{bookId}")
public String getBookById(@PathVariable String bookId,Model model){
    model.addAttribute("bookId", bookId);
    return "book";
} 

路徑中的bookId可以當變量,@PathVariable注解即提取路徑中的變量值。
(3)ant風格
@RequestMapping(value="/get/id?"):可匹配“/get/id1”或“/get/ida”,但不匹配“/get/id”或“/get/idaa”;
@RequestMapping(value="/get/id*"):可匹配“/get/idabc”或“/get/id”,但不匹配“/get/idabc/abc”;
@RequestMapping(value="/get/id/*"):可匹配“/get/id/abc”,但不匹配“/get/idabc”;
@RequestMapping(value="/get/id/**/{id}"):可匹配“/get/id/abc/abc/123”或“/get/id/123”,也就是Ant風格和URI模板變量風格可混用。
(4)含正則表達式的一類值
@RequestMapping(value="/get/{idPre:\\d+}-{idNum:\\d+}"):可以匹配“/get/123-1”,但不能匹配“/get/abc-1”,這樣可以設計更加嚴格的規則。
可以通過@PathVariable 注解提取路徑中的變量(idPre,idNum)
(5)或關系
@RequestMapping(value={"/get","/fetch"} )即 /get或/fetch都會映射到該方法上。

method:指定請求的method類型, GET、POST、PUT、DELETE等;
@RequestMapping(value="/get/{bookid}",method={RequestMethod.GET,RequestMethod.POST})

params:指定request中必須包含某些參數值是,才讓該方法處理。
@RequestMapping(params="action=del"),請求參數包含“action=del”,如:http://localhost:8080/book?action=del

復制代碼
@Controller
@RequestMapping("/owners/{ownerId}")
public class RelativePathUriTemplateController {

  @RequestMapping(value = "/pets/{petId}", method = RequestMethod.GET, params="myParam=myValue")
  public void findPet(@PathVariable String ownerId, @PathVariable String petId, Model model) {    
    // implementation omitted
  }
}
復制代碼

 僅處理請求中包含了名為“myParam”,值為“myValue”的請求。

headers:指定request中必須包含某些指定的header值,才能讓該方法處理請求。
@RequestMapping(value="/header/id", headers = "Accept=application/json"):表示請求的URL必須為“/header/id 且請求頭中必須有“Accept =application/json”參數即可匹配。

復制代碼
@Controller
@RequestMapping("/owners/{ownerId}")
public class RelativePathUriTemplateController {

@RequestMapping(value = "/pets", method = RequestMethod.GET, headers="Referer=http://www.ifeng.com/")
  public void findPet(@PathVariable String ownerId, @PathVariable String petId, Model model) {    
    // implementation omitted
  }
}
復制代碼

 僅處理request的header中包含了指定“Refer”請求頭和對應值為“http://www.ifeng.com/”的請求。

consumes:指定處理請求的提交內容類型(Content-Type),例如application/json, text/html。

@Controller
@RequestMapping(value = "/pets", method = RequestMethod.POST, consumes="application/json")
public void addPet(@RequestBody Pet pet, Model model) {    
    // implementation omitted
}

 方法僅處理request Content-Type為“application/json”類型的請求。
produces: 指定返回的內容類型,僅當request請求頭中的(Accept)類型中包含該指定類型才返回。 

@Controller
@RequestMapping(value = "/pets/{petId}", method = RequestMethod.GET, produces="application/json")
@ResponseBody
public Pet getPet(@PathVariable String petId, Model model) {    
    // implementation omitted
}

 方法僅處理request請求中Accept頭中包含了"application/json"的請求,同時暗示了返回的內容類型為application/json;

2、@RequestParam綁定單個請求參數值
@RequestParam用於將請求參數區數據映射到功能處理方法的參數上。

public String requestparam1(@RequestParam String username)

 請求中包含username參數(如/requestparam1?username=zhang),則自動傳入。

@RequestParam有以下三個參數:
value:參數名字,即入參的請求參數名字,如username表示請求的參數區中的名字為username的參數的值將傳入;
required:是否必須,默認是true,表示請求中一定要有相應的參數,否則將拋出異常;
defaultValue:默認值,表示如果請求中沒有同名參數時的默認值,設置該參數時,自動將required設為false。

public String requestparam4(@RequestParam(value="username",required=false) String username)

表示請求中可以沒有名字為username的參數,如果沒有默認為null,此處需要注意如下幾點:
原子類型:必須有值,否則拋出異常,如果允許空值請使用包裝類代替。
Boolean包裝類型:默認Boolean.FALSE,其他引用類型默認為null。

如果請求中有多個同名的應該如何接收呢?如給用戶授權時,可能授予多個權限,首先看下如下代碼:

public String requestparam7(@RequestParam(value="role") String roleList)

如果請求參數類似於url?role=admin&rule=user,則實際roleList參數入參的數據為“admin,user”,即多個數據之間使用“,”分割;我們應該使用如下方式來接收多個請求參數:

public String requestparam7(@RequestParam(value="role") String[] roleList)

或者

public String requestparam8(@RequestParam(value="list") List<String> list)  

3、@PathVariable綁定URI模板變量值
@PathVariable用於將請求URL中的模板變量映射到功能處理方法的參數上。

@RequestMapping(value="/users/{userId}/topics/{topicId}")
public String test(
       @PathVariable(value="userId") int userId, 
       @PathVariable(value="topicId") int topicId)   

 如請求的URL為“控制器URL/users/123/topics/456”,則自動將URL中模板變量{userId}和{topicId}綁定到通過@PathVariable注解的同名參數上,即入參后userId=123、topicId=456。

4、@ModelAttribute

ModelAttribute可以應用在方法參數上或方法上,他的作用主要是當注解在方法參數上時會將注解的參數對象添加到Model中;當注解在請求處理方法Action上時會將該方法變成一個非請求處理的方法,但其它Action被調用時會首先調用該方法。

4.1 @ModelAttribute注釋一個方法

被@ModelAttribute注釋的方法表示這個方法的目的是增加一個或多個模型(model)屬性。這個方法和被@RequestMapping注釋的方法一樣也支持@RequestParam參數,但是它不能直接被請求映射。實際上,控制器中的@ModelAttribute方法是在同一控制器中的@RequestMapping方法被調用之前調用的。

被@ModelAttribute注釋的方法用於填充model屬性,例如,為下拉菜單填充內容,或檢索一個command對象(如,Account),用它來表示一個HTML表單中的數據。
一個控制器可以有任意數量的@ModelAttribute方法。所有這些方法都在@RequestMapping方法被調用之前調用。
有兩種類型的@ModelAttribute方法。一種是:只加入一個屬性,用方法的返回類型隱含表示。另一種是:方法接受一個Model類型的參數,這個model可以加入任意多個model屬性。

(1)@ModelAttribute注釋void返回值的方法

復制代碼
@Controller
@RequestMapping(value="/test")
public class TestController {
    
    /**
     * 1.@ModelAttribute注釋void返回值的方法
      * @param abc
     * @param model
     */
    @ModelAttribute
    public void populateModel(@RequestParam String abc, Model model) {
        model.addAttribute("attributeName", abc);
    }
    
    @RequestMapping(value = "/helloWorld")
    public String helloWorld() {
       return "test/helloWorld";
    }
}
復制代碼

這個例子,在獲得請求/helloWorld 后,populateModel方法在helloWorld方法之前先被調用,它把請求參數(/helloWorld?abc=text)加入到一個名為attributeName的model屬性中,在它執行后helloWorld被調用,返回視圖名helloWorld和model已由@ModelAttribute方法生產好了。
這個例子中model屬性名稱和model屬性對象由model.addAttribute()實現,不過前提是要在方法中加入一個Model類型的參數。

(2)@ModelAttribute注釋返回具體類的方法

復制代碼
/**
 * 2.@ModelAttribute注釋返回具體類的方法
 * @param id
 * @return
 */
@ModelAttribute
public User getUserInfo(String id){
    if(id!=null && !id.equals("")){
        return userService.getUserInfo(id);
    }
    return null;
}
復制代碼

這種情況,model屬性的名稱沒有指定,它由返回類型隱含表示,如這個方法返回User類型,那么這個model屬性的名稱是user。
這個例子中model屬性名稱有返回對象類型隱含表示,model屬性對象就是方法的返回值。它無須要特定的參數。

(3)@ModelAttribute(value="")注釋返回具體類的方法

復制代碼
@Controller
@RequestMapping(value="/test")
public class TestController {
    
    /**
     * 3.@ModelAttribute(value="")注釋返回具體類的方法
      * @param abc
     * @return
     */
    @ModelAttribute("str")
    public String getParam(@RequestParam String param) {
        return param;
    }
    
    @RequestMapping(value = "/helloWorld")
    public String helloWorld() {
       return "test/helloWorld";
    }
}
復制代碼

這個例子中使用@ModelAttribute注釋的value屬性,來指定model屬性的名稱。model屬性對象就是方法的返回值。它無須要特定的參數。

完整的代碼:

復制代碼
package demo.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

import demo.model.User;
import demo.service.IUserService;

@Controller
@RequestMapping(value="/test")
public class TestController {
    
    @Autowired
    private IUserService userService;
    
    /**
     * 1.@ModelAttribute注釋void返回值的方法
      * @param abc
     * @param model
     */
    @ModelAttribute
    public void populateModel(@RequestParam String abc, Model model) {
        model.addAttribute("attributeName", abc);
    }
    
    /**
     * 2.@ModelAttribute注釋返回具體類的方法
      * @param id
     * @return
     */
    @ModelAttribute
    public User getUserInfo(String id){
        if(id!=null && !id.equals("")){
            return userService.getUserInfo(id);
        }
        return null;
    }
    
    /**
     * 3.@ModelAttribute(value="")注釋返回具體類的方法
      * @param abc
     * @return
     */
    @ModelAttribute("str")
    public String getParam(@RequestParam String param) {
        return param;
    }
    
    @RequestMapping(value = "/helloWorld")
    public String helloWorld() {
       return "test/helloWorld";
    }
}
復制代碼

Jsp前台取值:

復制代碼
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head> 
    <title>helloWorld</title>
  </head>
  
  <body>
       1.The attributeValue is:  ${attributeName}
       <br/><br/>
       
       2.用戶信息:<br/>
       姓名:${user.user_name}<br/>
       年齡:${user.user_age}<br/>
       郵箱:${user.user_email}<br/><br/>
      
      3.The param is:  ${str}
  </body>
</html>
復制代碼

頁面效果圖:

URL格式:http://localhost/SSMDemo/test/helloWorld?abc=text&id=1&param=aaa 注:當url或者post中不包含參數abc和參數param時,會報錯。

(4)@ModelAttribute和@RequestMapping同時注釋一個方法

復制代碼
@Controller
@RequestMapping(value="/test")
public class TestController {

    @RequestMapping(value = "/helloWorld")
    @ModelAttribute("attributeName")
    public String helloWorld() {
       return "hi";
    }
}
復制代碼

這時這個方法的返回值並不是表示一個視圖名稱,而是model屬性的值,視圖名稱由RequestToViewNameTranslator根據請求"/helloWorld"轉換為helloWorld。Model屬性名稱由@ModelAttribute(value=””)指定,相當於在request中封裝了key=attributeName,value=hi。

Jsp頁面:

復制代碼
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head> 
    <title>helloWorld</title>
  </head>
  
  <body>
      The attributeValue is:  ${attributeName}
  </body>
</html>
復制代碼

 4.2 @ModelAttribute注釋一個方法的參數

@ModelAttribute注釋方法的一個參數表示應從模型model中取得。若在model中未找到,那么這個參數將先被實例化后加入到model中。若在model中找到,則請求參數名稱和model屬性字段若相匹配就會自動填充。這個機制對於表單提交數據綁定到對象屬性上很有效。

當@ModelAttribute注解用於方法參數時,它有了雙重功能,即“存/取”。首先,它從模型中取出數據並賦予對應的參數,如果模型中尚不存在,則實例化一個,並存放於模型中;其次,一旦模型中已存在此數據對象,接下來一個很重要的步驟便是將請求參數綁定到此對象上(請求參數名映射對象屬性名),這是Spring MVC提供的一個非常便利的機制--數據綁定。

@RequestMapping(value = "/login.htm", method = RequestMethod.GET)
public String doLogin(@ModelAttribute("baseMember") BaseMember member) {
    member.setLoginName("loginName");
    return "home";
}

上述代碼中,如果模型中尚不存在鍵名為“baseMember”的數據,則首先會調用BaseMember類的默認構造器創建一個對象,如果不存在默認構造器會拋出異常。因此,給實體類提供一個默認構造器是一個好的編程習慣。當請求路徑的請求參數或提交的表單與BaseMember的屬性名匹配時,將自動將其值綁定到baseMember對象中,非常的便利!這可能是我們使用@ModelAttribute最主要的原因之一。比如:請求路徑為http://localhost:8080/spring-web/login.htm?loginName=myLoginName,baseMember對象中的loginName屬性的值將被設置為myLoginName。

4.3 @ModelAttribute注解的使用場景 
當@ModelAttribute注解用於方法時,與其處於同一個處理類的所有請求方法執行前都會執行一次此方法,這可能並不是我們想要的,因此,我們使用更多的是將其應用在請求方法的參數上,而它的一部分功能與@RequestParam注解是一致的,只不過@RequestParam用於綁定單個參數值,而@ModelAttribute注解可以綁定所有名稱匹配的,此外它自動將綁定后的數據添加到模型中,無形中也給我們提供了便利,這也可能是它命名為ModelAttribute的原因。

5、SessionAttributes

在默認情況下,ModelMap中的屬性作用域是request級別,也就是說,當本次請求結束后,ModelMap 中的屬性將銷毀。如果希望在多個請求中共享ModelMap中的屬性,必須將其屬性轉存到session 中,這樣 ModelMap 的屬性才可以被跨請求訪問。
Spring 允許我們有選擇地指定 ModelMap 中的哪些屬性需要轉存到 session 中,以便下一個請求屬對應的 ModelMap 的屬性列表中還能訪問到這些屬性。這一功能是通過類定義處標注 @SessionAttributes 注解來實現的。

復制代碼
package demo.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.SessionAttributes;

import demo.model.User;

@Controller
@RequestMapping(value="/demo1")
//(1)將ModelMap中屬性名為currUser的屬性放到Session屬性列表中,以便這個屬性可以跨請求訪問
@SessionAttributes("currUser")
public class Demo1Controller {
    
    @RequestMapping(value="/getUser")
    public String getUser(ModelMap model){
        User user=new User();
        user.setUser_name("zhangsan");
        user.setUser_age(25);
        user.setUser_email("zhangsan@sina.com");
        //(2)向ModelMap中添加一個屬性
         model.addAttribute("currUser",user);
        return "/demo/user";
    }
    
    @RequestMapping(value="/getUser1")
    public String getUser1(ModelMap model){
        User user=(User)model.get("currUser");
        System.out.println(user.getUser_name());
        System.out.println(user.getUser_age());
        System.out.println(user.getUser_email());
        return "demo/user1";
    }
}
復制代碼

我們在(2)處添加了一個 ModelMap 屬性,其屬性名為 currUser,而(1)處通過 @SessionAttributes 注解將 ModelMap 中名為 currUser 的屬性放置到 Session 中,所以我們不但可以在 getUser() 請求所對應的 JSP 視圖頁面中通過 request.getAttribute(“currUser”) 和 session.getAttribute(“currUser”) 獲取 user 對象,還可以在下一個請求(getUser1())所對應的 JSP 視圖頁面中通過 session.getAttribute(“currUser”) 或 session.getAttribute(“currUser”)訪問到這個屬性。

 這里我們僅將一個 ModelMap 的屬性放入 Session 中,其實 @SessionAttributes 允許指定多個屬性。你可以通過字符串數組的方式指定多個屬性,如 @SessionAttributes({“attr1”,"attr2”})。此外,@SessionAttributes 還可以通過屬性類型指定要 session 化的 ModelMap 屬性,如 @SessionAttributes(types = User.class),當然也可以指定多個類,如 @SessionAttributes(types = {User.class,Dept.class}),還可以聯合使用屬性名和屬性類型指定:@SessionAttributes(types = {User.class,Dept.class},value={“attr1”,"attr2”})。

user.jsp頁面:

復制代碼
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%@ page import="demo.model.User" %>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    <title>My JSP 'index.jsp' starting page</title>
  </head>
  <body><br>
      <%User user=(User)session.getAttribute("currUser");%>
      用戶名:<%=user.getUser_name() %><br/>
      年齡:<%=user.getUser_age() %><br/>
      郵箱:<%=user.getUser_email() %><br/><br/>
      <a href="<%=path %>/demo1/getUser1">跳轉</a>
  </body>
</html>
復制代碼

 通過@ModelAttribute綁定

@SessionAttributes 是用來在 controller 內部共享 model 屬性的。我們可以在需要訪問 Session 屬性的 controller 上加上 @SessionAttributes,然后在 action 需要的 User 參數上加上 @ModelAttribute,並保證兩者的屬性名稱一致。SpringMVC 就會自動將 @SessionAttributes 定義的屬性注入到 ModelMap 對象,在 setup action 的參數列表時,去 ModelMap 中取到這樣的對象,再添加到參數列表。只要我們不去調用 SessionStatus 的 setComplete() 方法,這個對象就會一直保留在 Session 中,從而實現 Session 信息的共享。

復制代碼
@Controller  
@SessionAttributes("currentUser")  
public class GreetingController{   
    @RequestMapping  
    public void hello(@ModelAttribute("currentUser") User user){   
    //user.sayHello()   
    }   
}  
復制代碼

@SessionAttributes清除
@SessionAttributes需要清除時,使用SessionStatus.setComplete();來清除。注意,它只清除@SessionAttributes的session,不會清除HttpSession的數據。故如用戶身份驗證對象的session一般不用它來實現,還是用session.setAttribute等傳統的方式實現。

6、@Responsebody與@RequestBody

@Responsebody表示該方法的返回結果直接寫入HTTP response body中。一般在異步獲取數據時使用,在使用@RequestMapping后,返回值通常解析為跳轉路徑,加上@Responsebody后返回結果不會被解析為跳轉路徑,而是直接寫入HTTP response body中。比如異步獲取json數據,加上@Responsebody后,會直接返回json數據。
@RequestBody將HTTP請求正文插入方法中,使用適合的HttpMessageConverter將請求體寫入某個對象。

復制代碼
$("#btn2").click(function(){
    var url='<%=request.getContextPath()%>/User/addUserInfo';
    var data={"user_name":$("#userName").val(),"user_sex":$("#userSex").val(),"user_age":$("#userAge").val(),
    "user_email":$("#userEmail").val(),"user_telephone":$("#userTelephone").val(),"user_education":$("#userEducation").val(),
    "user_title":$("#userTitle").val()};   

     $.ajax({
       type:'POST',
       contentType : 'application/json',   
      url:url,
      dataType:"json",
      data:JSON.stringify(data),
      async:false,
      success:function(data){
          alert("新增成功!");      
      },
      error: function(XMLHttpRequest, textStatus, errorThrown){
           alert(XMLHttpRequest.status);
           alert(XMLHttpRequest.readyState);
           alert(textStatus);
      }
    })
})
復制代碼
復制代碼
@RequestMapping(value="/addUserInfo",method=RequestMethod.POST)
@ResponseBody
 //將請求中的data寫入UserModel對象中
public String addUserInfo(@RequestBody UserModel user){
    System.out.println("user_name--------"+user.getUser_name());
    System.out.println("user_sex--------"+user.getUser_sex());
    System.out.println("user_age--------"+user.getUser_age());
    System.out.println("user_email--------"+user.getUser_email());
    System.out.println("user_title--------"+user.getUser_title());
    System.out.println("user_education--------"+user.getUser_education());
    System.out.println("user_telephone--------"+user.getUser_telephone());
    //不會被解析為跳轉路徑,而是直接寫入HTTP response body中
    return "{}";
}
復制代碼

@RequestBody 將HTTP請求正文轉換為適合的HttpMessageConverter對象。
@ResponseBody 將內容或對象作為 HTTP 響應正文返回,並調用適合HttpMessageConverter的Adapter轉換對象,寫入輸出流。

@RequestBody
作用: 
 i) 該注解用於讀取Request請求的body部分數據,使用系統默認配置的HttpMessageConverter進行解析,然后把相應的數據綁定到要返回的對象上;
 ii) 再把HttpMessageConverter返回的對象數據綁定到 controller中方法的參數上。
使用時機:
A) GET、POST方式提時, 根據request header Content-Type的值來判斷:
application/x-www-form-urlencoded, 可選(即非必須,因為這種情況的數據@RequestParam, @ModelAttribute也可以處理,當然@RequestBody也能處理);
multipart/form-data, 不能處理(即使用@RequestBody不能處理這種格式的數據);
其他格式, 必須(其他格式包括application/json, application/xml等。這些格式的數據,必須使用@RequestBody來處理);
 
B) PUT方式提交時, 根據request header Content-Type的值來判斷:
application/x-www-form-urlencoded, 必須;
multipart/form-data, 不能處理;
其他格式, 必須;
說明:request的body部分的數據編碼格式由header部分的Content-Type指定;

@ResponseBody
作用: 
 該注解用於將Controller的方法返回的對象,通過適當的HttpMessageConverter轉換為指定格式后,寫入到Response對象的body數據區。
使用時機:
 返回的數據不是html標簽的頁面,而是其他某種格式的數據時(如json、xml等)使用;


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM