@RequestMapping 中的@SessionAtribute 调用问题

Posted

技术标签:

【中文标题】@RequestMapping 中的@SessionAtribute 调用问题【英文标题】:@SessionAtribute call issue in @RequestMapping 【发布时间】:2018-09-28 01:01:53 【问题描述】:

我使用 Spring Security 进行身份验证。因为我想访问用户对象,所以我将这个身份验证保存在 @SessionAttribut 中。

建议方法

@ControllerAdvice(basePackages= "com.sencerseven.blog.admin","com.sencerseven.blog.controller")
@SessionAttributes("User")
public class SessionScope 

    @Autowired
    private UserService userService;

    @ModelAttribute("User")
    public User session() 
        Authentication authentication = 
        SecurityContextHolder.getContext().getAuthentication();

            if(authentication != null) 
                User user = userService.getByEmail(authentication.getName());
                if(user != null) 
                    return user;    
                

            
            return null;
    


控制器

@Controller
@RequestMapping("/post")
public class PostController 


@RequestMapping(value= "/post")
public ModelAndView postPage(@SessionAttribute("User")User tempUser,@PathVariable("post")String tempPostName ) throws NotFoundException  
 ...
 .....



@PostMapping("addcomment")
@ResponseBody
public String saveComment(@SessionAttribute("User")User tempUser,@RequestParam("post_id")int id,@RequestParam("comment")String tempComment) 
 ....
 .....




@SessionAttribute("User") 在 PostPage 方法中返回 null,页面抛出异常

 java.lang.NullPointerException at com.sencerseven.blog.controller.PostController.postPage(PostController.jav   a:54) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at 

.但是SaveComment方法是正确的。SaveComment访问用户对象中的@SessionAttribute("User")它不是null返回。

为什么?我该如何解决这个问题?

【问题讨论】:

由于 session() 在身份验证失败时返回 null,也许它就在这里。尝试返回默认用户或打印日志来验证这一点。 使用不在它周围的框架。 Spring Security 允许您简单地注入 Authentication 对象或您自己的用户,您不需要自己将其添加到会话中。请参阅 docs.spring.io/spring-security/site/docs/current/reference/html/… 并使用它而不是解决它。 另外,正如我在您的另一个(现已删除?)问题中提到的那样,@SessionAttributes@SessionAttribute 是不同的东西,不应该这样使用。跨度> 【参考方案1】:

Spring Security 已经支持这种开箱即用的功能(如文档中的 here 所述)。你试图在你自己的实现中硬塞,让事情变得复杂。不要使用@SessionAttribute,而是使用@AuthenticationPrincipal 注解让Spring Security 找到并注入用户。

所以基本上删除您的SessionScope 控制器建议并在您的控制器上用@AuthenticationPrincipal 替换@SessionAttribute

@Controller
@RequestMapping("/post")
public class PostController 


    @RequestMapping(value= "/post")
    public ModelAndView postPage(@AuthenticationPrincipal User tempUser, @PathVariable("post") String tempPostName ) throws NotFoundException  
        ...
    

    @PostMapping("addcomment")
    @ResponseBody
    public String saveComment(@AuthenticationPrincipal User tempUser, @RequestParam("post_id") int id, @RequestParam("comment") String tempComment) 
        ...
           

您必须确保您自己的 User 也是 Spring Security 使用的 User。如果不是这种情况,请使用自定义 AuthenticationSuccessHandler 而不是控制器建议,它将您自己的 User 添加到 Session 一次(而不是在每个请求上)。

【讨论】:

以上是关于@RequestMapping 中的@SessionAtribute 调用问题的主要内容,如果未能解决你的问题,请参考以下文章

@RequestMapping 中的@SessionAtribute 调用问题

获取RequestMapping注解中的属性

SpringMVC中的@Controller和@RequestMapping到底什么鬼?

SpringMVC中的@Controller和@RequestMapping到底什么鬼?

SpringMVC中的注解

如何仅将 /[^/]+ 中的路径与 Spring @RequestMapping 匹配?