Spring WebFlux项目注册表单提交未触发RegistrationController的register方法
问题根因梳理
你遇到的注册流程不执行、无报错的核心问题是多个响应式API使用错误、MVC注解混用导致的:
- 控制器注解错误:
RegistrationController使用了@RestController,该注解会自动给所有方法加上@ResponseBody,直接将返回值序列化为响应体,不会解析为Thymeleaf视图,导致注册提交后直接返回token字符串而非跳转页面,触发自定义错误处理器。 - 响应式流处理错误:
RegistrationService.reg()方法中直接将Mono<String>类型的token拼接到链接字符串,没有订阅获取实际值,导致响应式流中断,后续逻辑不执行。 - 参数绑定错误:
RegistrationRequest的setter方法返回值为String不符合JavaBean规范,Spring无法正确绑定表单参数。 - 实体类错误注入:
RegistrationService中错误将实体类ConfirmationToken作为Bean注入,会导致容器启动异常/依赖注入失败。 - 无重定向逻辑:注册成功后没有执行重定向,不符合POST-REDIRECT-GET规范,也触发了你推测的状态码异常问题。
分步修复方案
1. 修复RegistrationController注解
将@RestController改为@Controller,支持返回Thymeleaf视图:
// 修改前:@RestController @Controller @RequestMapping("/registration") @AllArgsConstructor public class RegistrationController {
同时修改register方法的返回逻辑,成功后重定向,失败返回注册页:
@PostMapping("/register") public Mono<String> register(@ModelAttribute("user") @Valid RegistrationRequest user, BindingResult bindingResult, Model model) { if (bindingResult.hasErrors()) { System.out.println("binding result has errors"); return Mono.just("registration"); } // 注册成功后重定向,携带success参数 return registrationService.reg(user) .thenReturn("redirect:/registration?success"); }
2. 修复RegistrationService的响应式逻辑
首先删除错误注入的ConfirmationToken,调整reg方法的流处理:
@Service @AllArgsConstructor public class RegistrationService { // 删除这行:@Autowired private ConfirmationToken confirmationToken; private ConfirmationTokenService confirmationTokenService; private ApplicationUserService applicationUserService; private EmailService emailService; // 补全邮件服务的Bean注入 public Mono<String> reg(RegistrationRequest request) { return applicationUserService.signUpUser( new ApplicationUser( request.getUsername(), request.getPassword(), request.getEmail(), UserRole.ROLE_USER ) ).flatMap(token -> { // 拿到实际的token值后再拼接链接、发送邮件 String link = "http://localhost:8081/registration/confirm?token=" + token; emailService.send(request.getEmail(), buildEmail(request.getUsername(), link)); return Mono.just(token); }); } // 补全buildEmail方法实现 private String buildEmail(String username, String link) { return "你好" + username + ",请点击链接完成注册:" + link; } }
3. 修复RegistrationRequest的setter方法
将所有setter的返回值改为void,符合JavaBean规范:
// 修改前:public String setUsername(final String username) public void setUsername(final String username) { this.username = username; } // 其余三个setter同理全部改为void返回
4. 优化SecurityConfig权限规则
删除重复冲突的权限配置:
// 移除原配置里/login和/css/*的角色校验,这两个路径已经配置了permitAll .pathMatchers("/input").hasRole("USER")
验证方式
修复后启动项目提交注册表单:
- 表单参数校验失败会停留在注册页,控制台打印错误日志
- 校验通过会执行注册逻辑,发送确认邮件,跳转回注册页显示注册成功提示
- 不会再触发自定义错误处理器的-1状态码返回
内容的提问来源于stack exchange,提问作者Macster
相关产品推荐
相关产品推荐

