Spring MVC之@ModelAttribute注解的使用

  1. @ModelAttribute注解的作用

    Spring MVC提供了几种将数据添加到模型的方式:使用ModelMap/Model类型的方法参数、方法体内创建ModelAndView实例,如下代码片段所示:

        @RequestMapping(value = "/login.htm", method = RequestMethod.GET)
        public String doLogin(ModelMap modelMap) {
            BaseMember mockMember = new BaseMember();
            mockMember.setLoginName("mockLoginName");
    
            // 向模型添加数据
            modelMap.addAttribute("member", mockMember);
            return "home";
        }

    ModelMap类型的方法参数

        @RequestMapping(value = "login2.htm", method = RequestMethod.GET)
        public ModelAndView doLogin2() {
            BaseMember mockMember = new BaseMember();
            mockMember.setLoginName("mockLoginName");
    
            // 创建ModelAndView实例
            ModelAndView mav = new ModelAndView();
            mav.addObject("member", mockMember);
            mav.setViewName("home");
    
            return mav;
        }

    方法体内的ModelAndView实例

    除了以上两种方式之外,Spring MVC还提供了一种基于注解的方式,即使用@ModelAttribute,如下代码片段所示:

        @RequestMapping(value = "login3.htm", method = RequestMethod.GET)
        public String doLogin3(@ModelAttribute("member") BaseMember mockMember){
            mockMember.setLoginName("mockLoginName");
            return "home";
        }

    @ModelAttribute注解

  2. @ModelAttribute注解的用法

    有两种使用@ModelAttribute注解的方法,一种是用于方法,另一种是用于方法的参数。

    • 用于方法本身

      当@ModelAttribute注解用于方法时,表明了该方法的作用是向模型中存放一个或多个数据,例如:

          @ModelAttribute
          public BaseMember addBaseMember() {
              BaseMember mockMember = new BaseMember();
              mockMember.setLoginName("mockMemberName");
      
              return mockMember;
          }

      方法的返回值将被存放在模型中。而如我们所了解的,模型中的数据都是以键值对的形式存储,但我们似乎并没有为返回值提供键名?这种情况下,一个基于返回值类型的名称将会作为键名,例如方法返回值是一个BaseMember类型的对象,此时“baseMember”将作为默认的键名。通常情况下,这种约定带来了一定程度上的便利,但是当模型中的数据并不全是由我们控制时,这回带来意想不到的问题,因此,较好的方式是显示的提供键名,例如:

          @ModelAttribute("mockBaseMember")
          public BaseMember addBaseMember() {
              BaseMember mockMember = new BaseMember();
              mockMember.setLoginName("mockMemberName");
      
              return mockMember;
          }

      由于方法只能有一个返回值,因此这种形式只能往模型中加入一个数据,我们还有另一种更加通用的方式:

          @ModelAttribute
          public void populateModel(Model model) {
              BaseMember mockMember = new BaseMember();
              mockMember.setLoginName("mockMemberName");
              model.addAttribute("mockMember", mockMember);
      
              // 其它需要加入到模型的数据
              model.addAttribute("currentDate", new Date());
          }

      以这种方式,我们可以往模型中加入多个需要的数据,仅仅只需要提供一个Model/ModelMap类型的方法参数即可。

    • 用于方法的参数

      当@ModelAttribute注解用于方法参数时,它有了双重功能,即“存/取”。首先,它从模型中取出数据并赋予对应的参数,如果模型中尚不存在,则实例化一个,并存放于模型中;其次,一旦模型中已存在此数据对象,接下来一个很重要的步骤便是将请求参数绑定到此对象上(请求参数名映射对象属性名),这是Spring MVC提供的一个非常便利的机制--数据绑定,之后将专门用一篇文章讨论此话题。

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

      上述代码中,如果模型中尚不存在键名为“baseMember”的数据,则首先会调用BaseMember类的默认构造器创建一个对象,如果不存在默认构造器会抛出异常。

      严重: Servlet.service() for servlet dispatcher threw exception
      java.lang.NoSuchMethodException: org.just4fun.spring.web.domain.BaseMember.<init>()
          at java.lang.Class.getConstructor0(Unknown Source)
              ......

      因此,给实体类提供一个默认构造器是一个好的编程习惯。当请求路径的请求参数或提交的表单与BaseMember的属性名匹配时,将自动将其值绑定到baseMember对象中,非常的便利!这可能是我们使用@ModelAttribute最主要的原因之一。比如:请求路径为http://localhost:8080/spring-web/login2.htm?loginName=myLoginName,baseMember对象中的loginName属性的值将被设置为myLoginName。

  3. @ModelAttribute注解的使用场景

    正如第2节讨论的,当@ModelAttribute注解用于方法时,与其处于同一个处理类的所有请求方法执行前都会执行一次此方法,这可能并不是我们想要的,因此,我们使用更多的是将其应用在请求方法的参数上,而它的一部分功能与@RequestParam注解是一致的,只不过@RequestParam用于绑定单个参数值,而@ModelAttribute注解可以绑定所有名称匹配的,此外它自动将绑定后的数据添加到模型中,无形中也给我们提供了便利,这也可能是它命名为ModelAttribute的原因。
时间: 2024-08-11 14:12:41

Spring MVC之@ModelAttribute注解的使用的相关文章

Spring MVC 中采用注解方式 Action中跳转到另一个Action的写法

Spring MVC 中采用注解方式 Action中跳转到另一个Action的写法 在Action中方法的返回值都是字符串行,一般情况是返回某个JSP,如: return "xx":意思是返回到某个JSP页面上 如果想在此Action中跳转到另一个Action中怎样做呢? return "redirect://.do?" 例如: @RequestMapping(params = "action=delete") public String del

Spring MVC的常用注解

1.@Controller 控制器Controller 负责处理由DispatcherServlet 分发的请求,它把用户请求的数据经过业务处理层处理之后封装成一个Model ,然后再把该Model 返回给对应的View 进行展示. @COntroller用于标记一个类,即控制类,spring使用扫描机制查找应用程序中所有基于注解的控制类.分发处理器会扫描使用了该注解的类的方法,并检测该方法是否使用了@RequestMapping注解,而使用@RequestMapping注解的方法才是真正处理请

Spring MVC中基于注解的 Controller

终于来到了基于注解的 Spring MVC 了.之前我们所讲到的 handler,需要根据 url 并通过 HandlerMapping 来映射出相应的 handler 并调用相应的方法以响应请求.实际上,ControllerClassNameHandlerMapping, MultiActionController 和选择恰当的 methodNameResolver(如 InternalPathMethodNameResolver) 就已经可以在很大程度上帮助我们省去不少的 XML 配置,谁让

Spring MVC常用的注解类

一.注解类配置 要使用springmvc的注解类,需要在springmvc.xml配置文件中用context:component-scan/扫描: ? 二.五大重要的注解类 1.RequestMapping注解 RequestMapping注解类的使用方法 在Controller控制器类的类定义和方法定义处都可以标注@RequestMapping注解 DispatcherServlet截获请求后,就可以通过控制器上的@RequestMapping提供的映射信息确定请求所对应的处理方法 packa

二、Spring MVC之常用注解

Spring MVC中常用的注解有以下几个:@Controller, @RequestMapping, @PathVariable, @CookieValue, @SessionAttributes.@ResponseBody.@RequestHeader和@ModelAttribute @Controller 上一节创建一个新的项目就用到了@Controller注解.通过这个注解,就可以让组件扫描将一个类识别为控制器组件并进行注册. 注册后,控制器映射到URL上的方法就可以进行请求处理. @R

【Spring MVC】 - @ModelAttribute使用

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

Spring MVC 常用的注解

@Controller @Controller 负责注册一个bean 到spring 上下文中,bean 的ID 默认为 类名称开头字母小写,你也可以自己指定,如下 方法一: @Controller public class TestController {} 方法二:            @Controller("tmpController") public class TestController {} @RequestMapping [email protected]用来定义访

四、Spring MVC的RequestParam注解

前面的章节,有提到可以通过@PathVariable注解来映射restful风格的url中的值到方法中去,本章就看看如果不使用restful风格的url来怎么进行参数的传递. RequestParam就是来实现参数传递的,能够把用户的输入绑定到后台的方法上面.它有三个主要的属性: value:定义参数的名称 required:定义参数是否是必须的,默认是true defaultValue:定义参数的默认值 下面结合具体的示例代码来看一下如何使用: 1.下面的这段代码定义了三个参数,一个name,

Spring MVC拦截器+注解方式实现防止表单重复提交

原理:在新建页面中Session保存token随机码,当保存时验证,通过后删除,当再次点击保存时由于服务器端的Session中已经不存在了,所有无法验证通过. 注,如果是集群的方式,则需要将token放入到缓存中即可. 注解Token代码:java源码  Java代码 复制代码 收藏代码 1[email protected](ElementType.METHOD) 2[email protected] (RetentionPolicy.RUNTIME) 3.public @interface T