使用@Context注入javax.ws.rs SecurityContext时遇实例化异常求助
看起来你是在Spring MVC控制器里误用了JAX-RS的注解体系,导致了这个错误。我来帮你拆解问题并给出解决办法:
为什么会报错?
你用了javax.ws.rs.core.SecurityContext(JAX-RS规范的类),并通过JAX-RS的@Context注解注入,但你的控制器是Spring MVC的(用了@RequestMapping)。Spring MVC根本不认识JAX-RS的@Context注解,它会把SecurityContext当成一个普通的模型属性参数,尝试去实例化它——但SecurityContext是一个接口,没有无参构造函数,自然就抛出了NoSuchMethodException。
解决办法
根据你的项目场景,有几个可行的方案:
方案1:用Spring Security的安全上下文(如果项目集成了Spring Security)
如果你的项目用了Spring Security,直接通过SecurityContextHolder获取当前认证信息,或者直接注入Authentication对象:
@RequestMapping(value = "/movie/search") public String getMovies(@RequestParam(name = "search") String search, Model model) throws IOException { // 获取当前用户的认证信息 Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); // 从authentication中提取你需要的token(这里需要你自己实现提取逻辑) String token = extractTokenFromAuth(authentication); String res = s.getMovies(search, token); List<Movie> movies = parser.JsonToObject(res); model.addAttribute("movies", movies); return "movieList"; }
或者更直接的,直接注入Authentication:
@RequestMapping(value = "/movie/search") public String getMovies(@RequestParam(name = "search") String search, Model model, Authentication authentication) throws IOException { String token = extractTokenFromAuth(authentication); // 后续逻辑同上 }
方案2:通过HttpServletRequest获取token(如果token存在于请求头)
如果你的token是放在请求头里(比如常见的Authorization: Bearer xxx),直接注入HttpServletRequest来获取:
@RequestMapping(value = "/movie/search") public String getMovies(@RequestParam(name = "search") String search, Model model, HttpServletRequest request) throws IOException { // 从请求头提取token String token = request.getHeader("Authorization"); // 处理Bearer前缀(如果有的话) if (token != null && token.startsWith("Bearer ")) { token = token.substring(7); } String res = s.getMovies(search, token); List<Movie> movies = parser.JsonToObject(res); model.addAttribute("movies", movies); return "movieList"; }
方案3:切换到JAX-RS框架(如果一定要用JAX-RS的SecurityContext)
如果你必须使用JAX-RS的SecurityContext,那需要把你的控制器改成JAX-RS的资源类,使用Jersey、RESTEasy这类JAX-RS实现框架,此时@Context注解才会被正确识别并注入对应的实例。
关键提醒
别把JAX-RS和Spring MVC的注解体系混在一起用!两者的上下文注入、控制器规范完全不同,混用必然出问题。
内容的提问来源于stack exchange,提问作者Dino

