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

Spring Boot多Rest Controller异常:ViewController无法返回视图

问题分析:独立ViewController无法返回视图的原因

我在独立文件中编写了两个Rest Controller,AuthController代码如下:

@RestController
@RequestMapping("/api/auth")
public class AuthController {
@PostMapping("login")
    public ResponseEntity<JwtAuthResponeDto> login(@RequestBody LoginDto loginDto){
        Authentication authentication = authenticationManager.authenticate(
                new UsernamePasswordAuthenticationToken(
                loginDto.getUsername(),
                loginDto.getPassword()));
        SecurityContextHolder.getContext().setAuthentication(authentication);
        String token = jwtTokenProvider.generateToken(authentication);
        return new ResponseEntity<>(new JwtAuthResponeDto(token), HttpStatus.OK);
    }

    @PostMapping("register")
    public ResponseEntity<String> register(@RequestBody RegisterDto registerDto) {
        if (userRepository.existsByUsername(registerDto.getUsername())) {
            return new ResponseEntity<>("Username is taken!", HttpStatus.BAD_REQUEST);
        }

        UserEntity user = new UserEntity();
        user.setUsername(registerDto.getUsername());
        user.setPassword(passwordEncoder.encode((registerDto.getPassword())));

        RoleEntity role = roleRepository.findByName("role_user").get();
        user.setRoles(Collections.singletonList(role));

        userRepository.save(user);

        return new ResponseEntity<>("User registered success!", HttpStatus.OK);
    }}

ViewController代码如下:

@RestController
@RequestMapping("/views")
public class ViewController {
 
    @GetMapping("login")
    public ModelAndView login(){
        return new ModelAndView("login");
    }
}

问题现象

当前ViewController无法返回login视图,但将该@GetMapping方法移至AuthController中则可正常运行。访问/views/login时浏览器无内容,终端仅输出以下日志:

2023-06-12 13:20:59.994  INFO 10516 --- [nio-8081-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
2023-06-12 13:20:59.995  INFO 10516 --- [nio-8081-exec-1] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
2023-06-12 13:21:00.003  INFO 10516 --- [nio-8081-exec-1] o.s.web.servlet.DispatcherServlet        : Completed initialization in 3 ms

原因解析

核心问题出在ViewController使用的@RestController注解上:

  • @RestController是@Controller和@ResponseBody的复合注解,它会强制将控制器中所有方法的返回值默认序列化为JSON/XML格式的响应体,而不是将返回值解析为视图名称去查找对应的页面模板。
  • 当把返回ModelAndView的方法移到AuthController时,Spring MVC对ModelAndView对象有特殊处理逻辑:即使控制器标注了@RestController,ModelAndView作为视图容器对象,不会被@ResponseBody序列化,而是正常触发视图解析流程,所以能渲染login视图。
  • 但在独立的ViewController中,@RestController的@ResponseBody规则完全生效,Spring会尝试把ModelAndView对象序列化为JSON(但该对象的序列化结果可能是空结构或浏览器无法解析的内容),导致浏览器没有显示预期的视图页面。

解决方法

将ViewController上的@RestController替换为@Controller注解:

@Controller
@RequestMapping("/views")
public class ViewController {
 
    @GetMapping("login")
    public ModelAndView login(){
        return new ModelAndView("login");
    }
}

这样Spring MVC会正确识别方法返回的ModelAndView为视图请求,进而查找并渲染login模板页面。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 12:13:17