You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在@Controller中访问@ControllerAdvice中的用户配置对象?

解决@ControllerAdvice设置的模型属性在@Controller中为null的问题

兄弟,我太懂你这种明明JSP里能正常拿到用户配置,结果在Controller里调用就抛空指针的憋屈了!咱们先搞清楚为啥会出现这种情况,再给你几个靠谱的解决办法:

问题根源

你在@ControllerAdvice里用@ModelAttribute添加的用户配置(比如profile),是请求级别的模型属性——它会被添加到每个请求的Model对象中,供后续的视图(比如JSP)渲染时使用。但@Controller是Spring容器管理的单例Bean,如果你直接在Controller的字段上引用这个profile,Spring根本不会把请求模型里的属性赋值给这个字段,因为两者的生命周期完全不搭:Controller实例是全局唯一的,而profile是每个请求单独生成/绑定的,所以你的Controller字段自然就是null啦。

靠谱的解决方案

方案1:在Controller方法参数中直接获取Model属性

既然profile存在于请求的Model里,那在Controller的处理方法里,直接把Model或者HttpServletRequest作为参数传入,然后从中取出profile就行:

@Controller
public class YourController {
    @GetMapping("/your-path")
    public String handleRequest(Model model) {
        // 从Model中获取profile
        UserProfile profile = (UserProfile) model.getAttribute("profile");
        // 接下来就可以正常使用profile了
        return "your-view";
    }

    // 或者用HttpServletRequest获取
    @GetMapping("/another-path")
    public String anotherHandle(HttpServletRequest request) {
        UserProfile profile = (UserProfile) request.getAttribute("profile");
        // 业务逻辑处理
        return "another-view";
    }
}

方案2:把profile放到Session中,用@SessionAttribute获取

如果这个用户配置是登录用户的会话信息(比如用户登录后一直需要用到),那可以在@ControllerAdvice里把它存入Session,然后在Controller里用@SessionAttribute直接注入:

首先修改你的@ControllerAdvice类:

@ControllerAdvice
public class GlobalControllerAdvice {
    @ModelAttribute
    public void addUserProfile(HttpSession session) {
        // 这里替换成你的用户配置获取逻辑
        UserProfile profile = userProfileService.getCurrentUserProfile();
        session.setAttribute("profile", profile);
    }
}

然后在Controller里直接使用:

@Controller
public class YourController {
    @GetMapping("/session-path")
    public String handleSessionRequest(@SessionAttribute("profile") UserProfile profile) {
        // 直接使用profile,不用再担心null问题
        return "session-view";
    }
}

方案3:检查@ControllerAdvice的作用范围

最后别忘了检查你的@ControllerAdvice是不是被限定了作用范围!比如如果加了@ControllerAdvice(assignableTypes = SomeController.class),那只有SomeController能拿到这个属性,其他Controller自然就拿不到了。如果是全局生效的,直接用@ControllerAdvice不加任何参数就行。

避坑提醒

千万别在Controller的类字段上直接尝试注入profile!比如这种写法肯定会空指针:

@Controller
public class BadController {
    // 这种写法绝对不行!Controller是单例,profile是请求级别的,永远拿不到值
    private UserProfile profile;

    @GetMapping("/bad-path")
    public String badHandle() {
        profile.doSomething(); // 必抛NullPointerException
        return "bad-view";
    }
}

内容的提问来源于stack exchange,提问作者cape

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 07:29:20