Spring Rest Controller处理POST请求返回302但无实际操作问题排查
问题分析与解决方案
核心问题出在控制器注解使用错误,导致请求无法映射到处理方法,再加上Spring Security的默认拦截规则,最终出现了请求被重定向但业务代码完全未执行的情况。以下是具体修复步骤:
1. 修复控制器注解,确保请求能映射到处理方法
你在UserRestController上使用的@RestController("/users")是错误的:
@RestController的参数是Bean名称,不是路径前缀,路径前缀需要通过@RequestMapping("/users")单独指定。@RestController会自动给方法添加@ResponseBody,将返回值作为响应体返回,但你需要的是页面重定向(视图跳转),因此应该使用普通的@Controller。
修改后的控制器代码:
@Controller @RequestMapping("/users") public class UserRestController { private final UserService userService; // Spring 4.3+支持构造注入自动装配,可省略@Autowired public UserRestController(UserService userService) { this.userService = userService; } @PostMapping("/save") public String saveUser(@ModelAttribute("user") User user){ userService.save(user); return "redirect:/login"; } }
2. 修正Spring Security配置(若项目启用了Security)
Spring Security默认会拦截所有未认证的POST请求,并将其重定向到登录页,这也是你的断点未触发的原因之一。需要配置允许匿名访问注册相关接口:
@Configuration @EnableWebSecurity public class SecurityConfig { @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http // 配置请求授权规则 .authorizeHttpRequests(auth -> auth .requestMatchers("/register", "/users/save").permitAll() // 允许匿名访问注册页和接口 .anyRequest().authenticated() // 其他请求需认证 ) // 配置自定义登录页 .formLogin(form -> form .loginPage("/login") .permitAll() ) // CSRF配置:Thymeleaf表单会自动生成令牌,无需手动添加或禁用 .csrf(csrf -> csrf // 可选:若不需要保护注册接口,可忽略CSRF,不推荐 // .ignoringRequestMatchers("/users/save") ); return http.build(); } }
3. 移除不必要的手动配置
- Thymeleaf在使用
th:action的表单中会自动注入CSRF令牌,你之前手动添加的<input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}"/>可以删除。 - 表单提交是
application/x-www-form-urlencoded格式,@RequestBody仅用于接收JSON请求体,因此换回@ModelAttribute(甚至可以省略,Spring会自动绑定到User对象)。
验证
启动项目后重新提交注册表单,断点将正常触发,数据库会写入用户数据,之后页面会正确重定向到登录页。
内容的提问来源于stack exchange,提问作者Roei Shchory
相关产品推荐
相关产品推荐

