Spring Security 6+Thymeleaf注册表单:POST请求出现403错误
问题排查与解决方案
核心问题1:请求参数无法绑定到RegistrationRequest(所有字段为null)
你的RegistrationRequest类仅添加了@Getter注解,缺少setter方法。Spring MVC在绑定表单参数时,需要通过setter方法为对象属性赋值,没有setter的话,无法将表单提交的参数注入到实例中,导致所有字段值为null。
解决办法
给RegistrationRequest添加@Setter注解,或者直接使用Lombok的@Data注解(@Data包含了@Getter、@Setter、@ToString等常用注解):
import lombok.*; @Data @EqualsAndHashCode @ToString public class RegistrationRequest { private String email; private String name; private String password; private String passwordRepeat; }
或者单独添加@Setter:
@Getter @Setter @AllArgsConstructor @NoArgsConstructor @EqualsAndHashCode @ToString public class RegistrationRequest { private String email; private String name; private String password; private String passwordRepeat; }
核心问题2:空指针异常(NPE)
日志中的Cannot invoke "String.length()" because "password" is null异常,是因为参数绑定失败导致password为null,在userService.register方法中调用了password.length()这类依赖非null字符串的操作。解决参数绑定问题后,该异常会自动消失。
额外建议
在业务层添加非空校验,避免后续类似问题:
// 在userService的register方法中添加校验 public void register(RegistrationRequest request) { if (request.getPassword() == null || request.getPassword().isEmpty()) { throw new IllegalArgumentException("密码不能为空"); } // 其他业务逻辑 }
关于403拦截问题
从你提供的日志Secured POST /register可以看出,当前Security配置已经允许/register的POST请求访问,之前的403问题应该已经解决。如果后续再出现403,可以确认:
requestMatchers中的路径是否正确(当前配置的/register已经包含所有HTTP方法)- CSRF是否确实禁用(你的配置中已经通过
csrf(AbstractHttpConfigurer::disable)禁用)
额外优化建议
在控制器的processRegisterRequest方法中,先判断BindingResult是否存在校验错误,再执行业务逻辑:
@PostMapping(value="register") public String processRegisterRequest(@ModelAttribute RegistrationRequest registrationRequest, BindingResult result) { System.out.println("DEBUG: " + registrationRequest.getName() + registrationRequest.getEmail() + registrationRequest.getPassword()); System.out.println(result.getAllErrors()); // 如果有校验错误,返回注册页面 if (result.hasErrors()) { return "user/user-add"; } userService.register(registrationRequest); return "user/registration-success"; }
内容的提问来源于stack exchange,提问作者sirmeowsalot
相关产品推荐
相关产品推荐

