zoukankan      html  css  js  c++  java
  • @ModelAttribute 的使用

    @ModelAttribute注解可被应用在 方法方法参数 上。

    对方法使用 @ModelAttribute 注解:

    注解在方法上的@ModelAttribute说明了方法的作用是用于添加一个或多个属性到model上。这样的方法能接受与@RequestMapping注解相同的参数类型,只不过不能直接被映射到具体的请求上。

    @ModelAttribute 方法会先被调用

    在同一个控制器中,注解了@ModelAttribute的方法实际上会在@RequestMapping方法之前被调用。以下是几个例子:

    package com.pudding.controller;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.web.bind.annotation.ModelAttribute;
    import org.springframework.web.bind.annotation.RequestMapping;
    
    @Controller
    public class ModelAttributeController {
    
    	@ModelAttribute
    	public void init(Model model) {
    		System.out.println("@RequestMapping方法");
    	}
    
    	@RequestMapping("/model-attribute")
    	public String get() {
    		System.out.println("@ModelAttribute方法");
    
    		return "model-attribute";
    	}
    
    }
    

    控制台输出的结果如下:

    无返回值的 @ModelAttribute 方法

    一般被 @ModelAttribute 注解的无返回值控制器方法被用来向 Model 对象中设置参数,在控制器跳转的页面中可以取得 Model 中设置的参数:

    ModelAttributeController.java:

    package com.pudding.controller;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.web.bind.annotation.ModelAttribute;
    import org.springframework.web.bind.annotation.RequestMapping;
    
    @Controller
    public class ModelAttributeController {
    
    	@ModelAttribute
    	public void init(Model model) {
    		model.addAttribute("arg", "model中设置的参数");
    	}
    
    	@RequestMapping("/model-attribute")
    	public String get() {
    
    		return "model-attribute";
    	}
    
    }
    

    model-attribute.jsp

    <%@ page language="java" contentType="text/html; charset=UTF-8"
    	pageEncoding="UTF-8"%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>Insert title here</title>
    </head>
    <body>
    	<input type="text" value=${ arg } />
    </body>
    </html>
    

    访问路径:http://localhost:8080/model-attribute,页面效果如下:

    可以发现,我们在被 @RequestMapping 标注的方法中并没有设置任何参数,但是页面却取得了在 @ModelAtribute 标注的方法设置的参数。由此可知,可以使用 @ModelAttribute 标注的方法来设置其他 @ReqeustMapping 方法的公用参数,这样就不用每一个方法都设置共同的 Model 参数。

    package com.pudding.controller;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.web.bind.annotation.ModelAttribute;
    import org.springframework.web.bind.annotation.RequestMapping;
    
    @Controller
    public class ModelAttributeController {
    
    	@ModelAttribute
    	public void init(Model model) {
    		model.addAttribute("arg", "model中设置的参数");
    	}
    
    	@RequestMapping("/model-attribute")
    	public String get() {
    
    		return "model-attribute";
    	}
    
    	@RequestMapping("/demo")
    	public String demo() {
    		return "demo";
    	}
    
    }
    

    在 demo.jsp 和 model-attribute.jsp 中都可以获得名为 "arg" 的 Model 参数。

    有返回值的 @ModelAttribute 方法

    有返回值的 @ModelAttribute 方法和没有返回值的 @ModelAttribute 方法的区别就是,没有返回值的 @ModelAttribute 方法使用 model.addAttribute(String key, Object value); 来向 Model 中增加参数。而有返回值的 @ModelAttribute 方法则直接将需要增加的参数返回。

    package com.pudding.controller;
    
    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 com.pudding.bean.User;
    
    @Controller
    public class ModelAttributeController {
    
    	@ModelAttribute
    	public User init(Model model) {
    		User user = new User("小明", 18);
    		return user;
    	}
    
    	@RequestMapping("/model-attribute")
    	public String get() {
    
    		return "model-attribute";
    	}
    
    }
    

    上面的代码的作用是,向 Model 中增加了 key 为 "user" value 为 user 对象的键值对。这个 user 对象中有 username = "小明",age = 18 的属性。

    使用 @ModelAttribute("key") 来显示指定属性名

    属性名没有被显式指定的时候又当如何呢?在这种情况下,框架将根据属性的类型给予一个默认名称。举个例子,若方法返回一个User类型的对象,则默认的属性名为"user"。你可以通过设置@ModelAttribute注解的值来改变默认值。当向Model中直接添加属性时,请使用合适的重载方法addAttribute(..)-即,带或不带属性名的方法。

    以下代码将会向 Model 中设置一个 key 为 "person" ,value 为 user对象的键值对:

    package com.pudding.controller;
    
    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 com.pudding.bean.User;
    
    @Controller
    public class ModelAttributeController {
    
    	@ModelAttribute("person")
    	public User init(Model model) {
    		User user = new User("小明", 18);
    		return user;
    	}
    
    	@RequestMapping("/model-attribute")
    	public String get() {
    
    		return "model-attribute";
    	}
    
    }
    

    @ModelAttribute 和 @RequestMapping 注解在同一个方法上

    如果 @ModelAttribute 和 @RequestMapping 注解在同一个方法上,那么代表给这个请求单独设置 Model 参数。此时返回的值是 Model 的参数值,而不是跳转的地址。跳转的地址是根据请求的 url 自动转换而来的。比如下面的例子中跳转页面不是 HelloWorld.jsp 而是 model-attribute.jsp。并且参数只有在 model-attribute.jsp 中能够取得,而 demo.jsp 中不能取得。

    package com.pudding.controller;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.web.bind.annotation.ModelAttribute;
    import org.springframework.web.bind.annotation.RequestMapping;
    
    @Controller
    public class ModelAttributeController {
    
    	@ModelAttribute("message")
    	@RequestMapping("/model-attribute")
    	public String init(Model model) {
    		return "HelloWorld";
    	}
    
    	@RequestMapping("/demo")
    	public String get() {
    
    		return "demo";
    	}
    
    }
    

    在方法参数上使用 @ModelAttribute 注解:

    如上一小节所解释,@ModelAttribute注解既可以被用在方法上,也可以被用在方法参数上。这一小节将介绍它注解在方法参数上时的用法。

    数据绑定

    注解在方法参数上的@ModelAttribute说明了该方法参数的值将由model中取得。如果model中找不到,那么该参数会先被实例化,然后被添加到model中。在model中存在以后,请求中所有名称匹配的参数都会填充到该参数中。这在Spring MVC中被称为数据绑定,一个非常有用的特性,节约了你每次都需要手动从表格数据中转换这些字段数据的时间。

    和 BindingResult 配合使用

    使用 @ModelAttribute 进行数据绑定之后,可以使用 BindingResult 来返回数据验证结果。数据验证可以使用 hibernate validation@Valid 标签或者 spring Validator 校验机制的 @Validated 配合 BindingResult 使用。 或者自定义校验器来返回 BindingResult 对象来进行校验。你可以通过Spring的 <errors> 表单标签来在同一个表单上显示错误信息。

    @Valid 校验器:

    @RequestMapping(path = "/owners/{ownerId}/pets/{petId}/edit", method = RequestMethod.POST)
    public String processSubmit(@Valid @ModelAttribute("pet") Pet pet, BindingResult result) {
    
        if (result.hasErrors()) {
            return "petForm";
        }
    
        // ...
    
    }
    

    @Validated 校验器:

    @RequestMapping(path = "/owners/{ownerId}/pets/{petId}/edit", method = RequestMethod.POST)
    public String processSubmit(@Validated @ModelAttribute("pet") Pet pet, BindingResult result) {
    
        if (result.hasErrors()) {
            return "petForm";
        }
    
        // ...
    
    }
    

    自定义校验器:

    @RequestMapping(path = "/owners/{ownerId}/pets/{petId}/edit", method = RequestMethod.POST)
    public String processSubmit(@ModelAttribute("pet") Pet pet, BindingResult result) {
    
        // 自己编写一个校验方法来处理 result 对象
        new PetValidator().validate(pet, result);
        if (result.hasErrors()) {
            return "petForm";
        }
    
        // ...
    
    }
    
  • 相关阅读:
    spring @component的作用
    Spring 开启Annotation <context:annotation-config> 和 <context:component-scan>诠释及区别
    servlet中实现页面跳转return “r:”和return “f:
    MyEclipse中SVN的使用方法 此博文包含图片 (2012-04-19 12:18:35)
    MyEclipse使用总结——MyEclipse10安装SVN插件
    javaweb学习总结(九)—— 通过Servlet生成验证码图片
    Spring-springmvc-mybatis整合
    MyBatis连接SQLServer数据库
    mybatis入门基础(二)----原始dao的开发和mapper代理开发
    MyBatis入门基础(一)
  • 原文地址:https://www.cnblogs.com/lemon-coke-pudding/p/12740365.html
Copyright © 2011-2022 走看看