问题还是出在@SessionAttributes注解,非常冷门,建议不要使用,一了百了。

HttpSessionRequiredException,出现在pojo入参的过程中。

一、问题场景

使用@SessionAttributes注解,在pojo入参的过程中,报出:org.springframework.web.HttpSessionRequiredException: Session attribute ‘user’ required – not found in session错误。

二、spring mvc pojo入参的流程

spring mvc 确定目标方法pojo类型入参的过程:

(1)确定一个key

  1. 如果目标方法的pojo类型的参数没有使用@ModelAttribute作为修饰,则key为pojo类名第一个字母的小写。
  2. 如果使用了@ModelAttribute来修饰,则key为@ModelAttribute注解的value属性值。

(2)在implicitModel中查找key对应的对象,如果存在,则作为入参传入

如果在@ModelAttribute标记的方法在Map中保存过,且key和(1)确定的key一致,则会获取到对象。

(3)如果implicitModel中不存在key对应的对象,则检查当前的Handler是否使用@SessionAttribytes注解

如果使用了该注解,并且@SessionAttribytes注解的value属性值中包含了key,则会从httpsession中取获取对应的value值。

若存在,则直接传入到目标方法的入参中。若不存在则抛出异常(这次bug的核心就是这个)。

(4)如果Handler没有使用@SessionAttribytes注解,或者@SessionAttribytes注解的value值中不包含key

会通过反射来创建pojo类型的参数,传入为目标方法的参数。

(5)spring mvc会把key和pojo类型的对象保存在implicitModel中

进而会保存到request中。

知道了流程就好解决问题了。

三、解决方法

(1)具体解决

检查当前的Handler是否使用@SessionAttribytes注解,如果使用了该注解,并且@SessionAttribytes注解的value属性值中包含了key,则会从httpsession中取获取对应的value值。

若存在则直接传入到目标方法的入参中,若不存在则抛出异常。

所以把相同的key从@SessionAttribytes中去掉就好了。直接把

改成:

结果为:

1

因为链接无参,所以请求全部都是null。

通过访问:http://localhost:8080/5.4springmvc/testModelAttribute?id=1&username=godlikexie&password=666,这样就能附上参数。

(2)如果不需要@SessionAttribytes注释,干脆删掉吧。

基本上没什么用。

(3)反正要从httpsession中获取user对象,只要先把user放进httpsession中就可以?

直接访问http://localhost:8080/5.4springmvc/testModelAttribute不成功,是因为当前http session中没有user对象。

那么先访问http://localhost:8080/5.4springmvc/testSessionAttributes,把user放进http session,再访问http://localhost:8080/5.4springmvc/testModelAttribute,是不是能获取呢?

是可以的,因为http session中有值了,但是没有从根本上解决这个问题…..

四、解决方法

解决问题的最好办法就是不要使用。

发表评论

电子邮件地址不会被公开。 必填项已用*标注