1. 程式人生 > 實用技巧 >SpringMVC中@ModelAttribute註解的使用

SpringMVC中@ModelAttribute註解的使用

在SpringMVC的Controller中使用@ModelAttribute時,其位置包括下面三種:

  • 應用在方法上

  • 應用在方法的引數上

  • 應用在方法上,並且方法也使用了@RequestMapping

一、應用在方法上

首先說明一下,被@ModelAttribute註解的方法會在Controller每個方法執行之前都執行,因此對於一個Controller中包含多個URL的時候,要謹慎使用。

1、使用@ModelAttribute註解無返回值的方法

@Controller
@RequestMapping(value = "/modelattribute")
public class ModelAttributeController {

    @ModelAttribute
    public void myModel(@RequestParam(required = false) String abc, Model model) {
        model.addAttribute("attributeName", abc);
    }

    @RequestMapping(value = "/method")
    public String method() {
        return "method";
    }
}

  

這個例子,在請求/modelattribute/method?abc=aaa後,會先執行myModel方法,然後接著執行method方法,引數abc的值被放到Model中後,接著被帶到method方法中。

當返回檢視/modelattribute/method時,Model會被帶到頁面上,當然你在使用@RequestParam的時候可以使用required來指定引數是否是必須的。

如果把myModelmethod合二為一,程式碼如下,這也是我們最常用的方法:


@RequestMapping(value = "/method")
public String method(@RequestParam(required = false
) String abc, Model model) { model.addAttribute("attributeName", abc); return "method"; }

2、使用@ModelAttribute註解帶有返回值的方法

@ModelAttribute
public String myModel(@RequestParam(required = false) String abc) {
    return abc;
}

@ModelAttribute
public Student myModel(@RequestParam(required = false) String abc) {
    Student student = new Student(abc);
    return student;
}

@ModelAttribute
public int myModel(@RequestParam(required = false) int number) {
    return number;
}

  

對於這種情況,返回值物件會被預設放到隱含的Model中,在Model中的key返回值首字母小寫value為返回的值。

上面3種情況等同於:

model.addAttribute("string", abc);
model.addAttribute("int", number);
model.addAttribute("student", student);

  

在jsp頁面使用${int}表示式時會報錯:javax.el.ELException: Failed to parse the expression [${int}]
解決辦法:
在tomcat的配置檔案conf/catalina.properties新增配置org.apache.el.parser.SKIP_IDENTIFIER_CHECK=true

如果只能這樣,未免太侷限了,我們很難接受keystringintfloat等等這樣的。

想自定義其實很簡單,只需要給@ModelAttribute新增value屬性即可,如下:

@ModelAttribute(value = "num")
public int myModel(@RequestParam(required = false) int number) {
    return number;
}

  

這樣就相當於model.addAttribute("num", number);

二、使用@ModelAttribute註解的引數

@Controller
@RequestMapping(value = "/modelattribute")
public class ModelAttributeParamController {

    @ModelAttribute(value = "attributeName")
    public String myModel(@RequestParam(required = false) String abc) {
        return abc;
    }

    @ModelAttribute
    public void myModel3(Model model) {
        model.addAttribute("name", "zong");
        model.addAttribute("age", 20);
    }

    @RequestMapping(value = "/param")
    public String param(@ModelAttribute("attributeName") String str,
                       @ModelAttribute("name") String str2,
                       @ModelAttribute("age") int str3) {
        return "param";
    }
}

  

從程式碼中可以看出,使用@ModelAttribute註解的引數,意思是從前面的Model中提取對應名稱的屬性。

這裡提及一下@SessionAttributes的使用:

  • 如果在類上面使用了@SessionAttributes("attributeName")註解,而本類中恰巧存在attributeName,則會將attributeName放入到session作用域。
  • 如果在類上面使用了@SessionAttributes("attributeName")註解,SpringMVC會在執行方法之前,自動從session中讀取keyattributeName的值,並注入到Model中。所以我們在方法的引數中使用ModelAttribute("attributeName")就會正常的從Model讀取這個值,也就相當於獲取了session中的值。
  • 使用了@SessionAttributes之後,Spring無法知道什麼時候要清掉@SessionAttributes存進去的資料,如果要明確告知,也就是在方法中傳入SessionStatus物件引數,並呼叫status.setComplete就可以了。

三、應用在方法上,並且方法上也使用了@RequestMapping

@Controller
@RequestMapping(value = "/modelattribute")
public class ModelAttributeController {

    @RequestMapping(value = "/test")
    @ModelAttribute("name")
    public String test(@RequestParam(required = false) String name) {
        return name;
    }
}

  

這種情況下,返回值String(或者其他物件)就不再是檢視了,而是放入到Model中的值,此時對應的頁面就是@RequestMapping的值test
如果類上有@RequestMapping,則檢視路徑還要加上類的@RequestMapping的值,本例中檢視路徑為modelattribute/test.jsp

作者:Java_Explorer
連結:https://www.jianshu.com/p/0ec4e7afb7ed
來源:簡書
著作權歸作者所有。商業轉載請聯絡作者獲得授權,非商業轉載請註明出處。