内容字号:默认大号超大号

段落设置:段首缩进取消段首缩进

字体设置:切换到微软雅黑切换到宋体

SpringMVC SessionAttributes ModelAttribute注解

2018-08-04 18:12 出处:清屏网 人气: 评论(0

说明

本文主要针对 @SessionAttributes注解 和 @ModelAttribute注解的基础用法进行解析。至于为什么会将这两个注解放在一起,是因为它们之间还是有点影响的。

@SessionAttributes

光看这个注解的名字大概也就知道这个注解是用于往 Session 域中存数据的吧!这个注解是 Spring2.5版本才有的。

属性

① value:

一个字符串数组,表示存放到 Session 域中的属性名

② names: (这个属性是 4.2版本才有的)

和 value 属性一样,他们之间是彼此的别名而已

③ type:

一个 Class 数组,根据指定的类型,将模型中对应类型的数据放到 Session 域中

属性对应源码

用法

注意:@SessionAttributes 注解只能用在类上面。

 

package com.test;

import *;

@Controller
@SessionAttributes(value={"name", "age"}, types={String.class})    //value 换成 names 一样的效果
public class SessionAttribute {

    @RequestMapping("/testSessionAttribute1")
    public String testSessionAttribute1(Map<String, Object> map) {
        //name 属性被放入了 value 数组中,所以也就存入了 Session 域中
        map.put("name", "张三");
        //age 属性放入了 names 数组中,也一样存入了 Session 域中
        map.put("age", 19);
        //由于 types 数组中有 String.class,所以,address 属性也会放入 Session 域中
        map.put("address", "重庆市");
        
        return "success";
    }
}

页面显示:

注意:value 属性不能和 names 属性一起使用,如果一起使用了会出现下面异常信息

org.springframework.core.annotation.AnnotationConfigurationException: In annotation [org.springframework.web.bind.annotation.SessionAttributes] declared on class com.test.SessionAttribute and synthesized from [@org.springframework.web.bind.annotation.SessionAttributes(names=[age], value=[name], types=[class java.lang.String])], attribute 'names' and its alias 'value' are present with values of [{age}] and [{name}], but only one is permitted.

@ModelAttribute

修饰方法

注意:有 @ModelAttribute 注解修饰的方法,会在 Controller 中的每个方法执行之前都执行一次。

① 修饰没有返回值的方法

上面这个方法被 @ModelAttribute 注解所修饰,且没有返回值。但是,在方法的入参处有一个 map 集合,且在方法内部向 mpa 中放入了一个键值对。

执行完了 isNotReturn() 方法后,就会接着来到 isNotReturnTest() 方法,该方法重定向到了 success.jsp 页面,那么,map 集合中存放的数据也会在 request 域中被带到页面上。

最后从 request 域中获取 tom,页面输出:

上面两个方法可合并为一个方法:

执行该方法就会向 map 中放入一个键值对,并且转发到 success.jsp 页面,且将数据通过 request 域带到页面。

② 修饰有返回值的方法

  //修饰有返回值的方法
    @ModelAttribute(value="argtest")
    public String havaArg(Map<String, Object> map, Model model) {
        /*
         * 下面这种情况,返回值会被默认放到隐藏的 Model 中,在 Model 中的 key默认为 返回值的首字母小写,
         * 可以通过 ModelAttribute 注解的 value 属性设置
         * value 为返回的值
         * model.addAttribute("string", "值");
         */
        //map.put("arg", "修饰有返回值的方法");
        model.addAttribute("modelTest", "model 测试");
        
        return "修饰有返回值的方法";
    }

注释中已经说的很清楚了,上面方法中,返回了一个字符串,那么在 model 中就会以下面的方式将 这个字符串存入 model:

    model.addAttribute("string", 修饰有返回值的方法");

由于默认以返回值的首字母小写作为 key,这样可定有一定局限性,所以我们可以再 @ModelAttribute 注解中加上 value 属性标明返回值在 model 中的 key,还是上面的例子来说,加上 value 属性值后就是

    model.addAttribute("argtest", 修饰有返回值的方法");

 

修饰参数

  //修饰参数,就是从 Model 中获取对应的属性值
    @RequestMapping("/updateUserInfo")
    public String updateUserInfo(User user, 
            @ModelAttribute("modelTest") String modelTest, 
            @ModelAttribute(value="argtest") String argtest) {
        
        System.out.println("ModelAttribute修改参数:"+modelTest);
        System.out.println("ModelAttribute修改参数:"+argtest);
        
        return SUCCESS;
    }

上面方法输出内容如下:

这里输出的内容就是我们上面 做修饰有返回值方法时放入的值。那么, @ModelAttribute 注解修饰参数就代表从 Model 中获取对应属性名的值。

修饰被 @RequestMapping 注解修饰的方法

   @RequestMapping("/test2")
    @ModelAttribute
    public String test2() {
        System.out.println("修饰有 RequestMapping修饰的方法");
        
     //这里返回的 "success" 就不在代表视图了,而是 RequestMapping 注解的 value 属性值才代表视图
        return SUCCESS;
    }

可见上面 test2() 方法上有两个注解,那么, 这个方法就不会在每次访问 Controller 时都会执行 了。因为不是每次执行 Controller 都会执行该方法,所以, 返回的 "success"字符串也不会被放入 Model 中(就会是一个无效的操作) 。同时, 返回值 "success" 也不代表视图,此时对应的页面就是 RequestMapping 注解对应的值 "test2" ,所以,在访问 "/test2" 来到 test2() 方法后,返回回去的路径为 test2.jsp,由于没有该页面,出现 404。

上面内容讲解了 SessionAttributes 注解和 ModelAttribute 注解各自的基本用法,下面就来看看他俩放在一起使用可能会出现什么问题

SessionAttributes 注解和 ModelAttribute 注解一起使用

情况一

@Controller
@SessionAttributes(value= {"name"})
public class Test {
    
     //执行该 方法后,会将 name属性放入 Model 中和 Session 中
   //只要 ModelAttribute 属性值和 SessionAttributes 注解 value 属性其中一个属性值一致,那么,ModelAttribute 修饰方法返回值也会被放入 Session 中
    @ModelAttribute("name")
    public String getName() {
        
        return "李四";
    }
}

情况二

import *;

@Controller
@SessionAttributes(value= {"userInfo"})
public class Test {/*
        这段代码什么意思:
           页面上存在一个表单,当点击提交后,整个表单中的数据就会自动封装为一个 UserInfo 对象,并传递到 Handler 方法中,输出,最后跳转到 "success.jsp" 页面,同时将 UserInfo 对象
              放到 Session 域中
     */
    @RequestMapping("/test2")
    public String test2(@ModelAttribute("userInfo") UserInfo userInfo) {
        System.out.println("修改方法:"+userInfo);
        
        return "success";
    }
}

但是,上面代码执行会出错的。会抛出下面异常信息:

 org.springframework.web.HttpSessionRequiredException: Expected session attribute 'userInfo'  //Session 中不存在 userInfo 属性

解决办法

一、将 目标方法 即代码中 test2() 方法 的 @ModelAttribute("userInfo") 中的 userInfo 改名,只要不和 SessionAttributes 注解中的名字一样就可以了。

二、目标方法 即代码中 test2() 方法 的 @ModelAttribute("userInfo") 去掉,添加一个对应的被 ModelAttribute 修饰的方法。

import *;

@Controller
@SessionAttributes(value= {"userInfo"})
public class Test {
    @ModelAttribute
    public void getUserInfo(UserInfo userInfo, Model model) {
        model.addAttribute("userInfo", userInfo);
    }


    @RequestMapping("/test2")
    public String test2(UserInfo userInfo) {
        System.out.println("修改方法:"+userInfo);
        
        return "success";
    }
}

这里只做了一个简单的处理介绍,关于更详细的原因,我会在后面说明。还得下去多了解一下源码过程!

分享给小伙伴们:
本文标签: SpringMVCSessionAttriModelAttribu

相关文章

发表评论愿您的每句评论,都能给大家的生活添色彩,带来共鸣,带来思索,带来快乐。

CopyRight © 2015-2016 QingPingShan.com , All Rights Reserved.

清屏网 版权所有 豫ICP备15026204号