spring mvc 中的@modelattributes

@ModelAttribute一个具有如下三个作用:
①绑定请求参数到命令对象:放在功能处理方法的入参上时,用于将多个请求参数绑定到一个命令对象,从而简化绑定流程,而且自动暴露为模型数据用于视图页面展示时使用;
②暴露表单引用对象为模型数据:放在处理器的一般方法(非功能处理方法)上时,是为表单准备要展示的表单引用对象,如注册时需要选择的所在城市等,而且在执行功能处理方法(@RequestMapping注解的方法)之前,自动添加到模型对象中,用于视图页面展示时使用;
③暴露@RequestMapping方法返回值为模型数据:放在功能处理方法的返回值上时,是暴露功能处理方法的返回值为模型数据,用于视图页面展示时使用。

1 暴露表单引用对象为模型数据
    在 controller 中所有的方法执行前执行

比如是为表单准备要展示的表单引用对象,如注册时需要选择的所在城市等,而且在执行功能处理方法

@ModelAttribute("cityList")
public List<String> cityList() {
    return Arrays.asList("北京", "山东");
}

比如:
 /** 
     * 获得所有Addresses,并使他们成为一个model.  
     * 注意@ModelAttribute作用于method级别上时.会在@Controller执行时加载 
     * method里的方法.即在@Controller执行时@ModelAttribute添加参数. 
     * 返回于该@Controller返回的所有JSP页面. 
     */  
    @ModelAttribute("addresses")  
    public List<Address> getAllAddresses() {  
        return addressService.getAll();  
    }  
  
    /** 
     * 处理和检索一个包含addresses 的JSP Page . 
     */  
    @RequestMapping(value = "list1", method = RequestMethod.GET)  
    public String getAllUsingModelAttribute() {  
        logger.debug("Received request to show all addresses page");  
  
        // 他会解析 /WEB-INF/jsp/addressespage.jsp  
        return "addressespage";  
    }  
  
    /** 
     * 处理和检索一个包含addresses 的JSP Page . 
     *  
     * @return the name of the JSP page 
     */  
    @RequestMapping(value = "list2", method = RequestMethod.GET)  
    public String getAllUsingModel(Model model) {  
        logger.debug("Received request to show all addresses page");  
  
        // 检索所有的address并装入model返回addressespage.jsp  
        model.addAttribute("addresses", addressService.getAll());  
        model.addAttribute("greetings", "I came from Model not ModelAttribute");  
  
        // This will resolve to /WEB-INF/jsp/addressespage.jsp  
        return "addressespage";  
    }  


则访问
http://localhost:8080/spring-jsp/address/list1
时,会自动先执行
public List<Address> getAllAddresses() 方法,并且放到
addresses中,交给JSP页面取出

而在http://localhost:8080/spring-jsp/address/list2 中
则只是用
model.addAttribute实现

2) 模式2:method parameter级(即方法里所带的参数)
   如果你的方法参数里带有@ModelAttribute的参数.表示从JSP Page传回的参数并自动的转化为java对象
 
/**
	 * 检索修改页面
	 */
	@RequestMapping(value = "/edit/{id}", method = RequestMethod.GET)
	public String getEdit(@PathVariable Integer id, Model model) {
		/*
		 * @PathVariable表示指定@RequestMapping的URL模板中{}里的值 
		 * 相当于以前我们URL后面传的参数如XX?id=XXXX .
		 * 但是现在我们可以用 XX/id/XX来代替. 
		 * 这个就是REST风格的URL,我们可以实现非常复杂的URL模板
		 */

		logger.debug("Received request to show edit page");

		/*
		 * 根据ID检索出对应的Person,然后把检索出来的Person放入一个叫
		 * "personAttribute"的model中.
		 * 这样editpage.jsp就会接收一个 名为personAttribute的参数.
		 * 相当于request.setAttribute("XX",XX)
		 */
		model.addAttribute("personAttribute", personService.get(id));

		// This will resolve to /WEB-INF/jsp/editpage.jsp
		return "editpage";
	}

	/**
	 * 保存修改结果
	 */
	@RequestMapping(value = "/edit/{id}", method = RequestMethod.POST)
	public String saveEdit(@ModelAttribute("personAttribute") Person person,
			@PathVariable Integer id, Model model) {
		logger.debug("Received request to update person");

		// 我们从页面接收到了一个名为"personAttribute"的model并命名为person
		// 同样我们也获得了指定的id.
		person.setId(id);

		// 更新person
		personService.edit(person);

		// 在更新后我们重新显示所有Person 的页面
		model.addAttribute("persons", personService.getAll());

		// This will resolve to /WEB-INF/jsp/personspage.jsp
		return "personspage";
	}


对于前端的页面JSP
编辑个人信息的页面:
 
<form:form modelAttribute="personAttribute" method="POST" action="${saveUrl}">  
    <table>  
        <tr>  
            <td><form:label path="id">Id:</form:label></td>  
            <td><form:input path="id" disabled="true"/></td>  
        </tr>  

   所以说,在参数中,加了@modelattributes后,
  public String saveEdit(@ModelAttribute("personAttribute") Person person,  
      @PathVariable Integer id, Model model) {
中 表示从JSP 页面返回的一个叫"personAttribute"的值.并自动的转化为Person对象.

3 其他
   匿名绑定命令参数
public String test4(@ModelAttribute UserModel user, Model model)

public String test5(UserModel user, Model model)
此时我们没有为命令对象提供暴露到模型数据中的名字,此时的名字是什么呢?Spring Web MVC自动将简单类名(首字母小写)作为名字暴露,如“cn.javass.chapter6.model.UserModel”暴露的名字为“userModel”。
public @ModelAttribute List<String> test6()

public @ModelAttribute List<UserModel> test7()
对于集合类型(Collection接口的实现者们,包括数组),生成的模型对象属性名为“简单类名(首字母小写)”+“List”,如List<String>生成的模型对象属性名为“stringList”,List<UserModel>生成的模型对象属性名为“userModelList”。

其他情况一律都是使用简单类名(首字母小写)作为模型对象属性名,如Map<String, UserModel>类型的模型对象属性名为“map”。

@ModelAttribute
    public Account addAccount(@RequestParam String number) {
       return accountManager.findAccount(number);
    }


这种情况,model属性的名称没有指定,它由返回类型隐含表示,如这个方法返回Account类型,那么这个model属性的名称是account。
    这个例子中model属性名称有返回对象类型隐含表示,model属性对象就是方法的返回值。它无须要特定的参数。

猜你喜欢

转载自jackyrong.iteye.com/blog/2276673