java - Spring Boot 和 Thymeleaf 在字段错误时返回 400 错误
问题描述
我将 Spring Boot 2.3.1 和 Thymeleaf 用于一个简单的注册应用程序,因此用户可以创建Member
模型并将其保存到数据库中。我正在使用该javax.validation
框架来确保字段不为空,并且在模型有效时它可以正常工作,但是缺少字段的无效模型会将我踢出,并在我的默认error.html
页面上显示 400 错误代码,而不是将用户带回我可以在其中显示字段级错误的注册表单(例如,“需要用户名”)。
该模型很简单,如下所示:
@Entity
@Table(name="member")
public class Member {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
private Long id;
@Email
@NotEmpty
private String username;
@NotEmpty
@Column(name="password", nullable = false)
private String password;
// ... getters and setters
控制器如下所示:
@PostMapping("/register")
public ModelAndView registerMember(HttpServletRequest request, HttpServletResponse response,
@ModelAttribute @Valid Member member, ModelMap model, BindingResult result){
log.info("Attempting to register a user");
// some other error checking not related to javax.validation ...
memberService.save(member);
return new ModelAndView("/success", model);
}
最后,(简化的)HTML/Thymeleaf 表单看起来像这样(register.html
):
<form th:action="@{/register}" th:object="${member}" method="post">
<input type="text" class="form-control" placeholder="Email" id="username" th:field="*{username}">
<input type="password" placeholder="Enter your Password" id="password" class="form-control" th:field="*{password}">
<input type="submit" class="btn btn-primary btn-block btn-login">
</form>
在表单上提交值为 forusername
并且password
一切正常,但如果我省略其中任何一个,就像username
我得到以下WARN
日志语句:
Resolved [org.springframework.validation.BindException: org.springframework.validation.BeanPropertyBindingResult: 4 errors
Field error in object 'member' on field 'username': rejected value []; codes [NotEmpty.member.username,NotEmpty.username,NotEmpty.java.lang.String,NotEmpty]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [member.username,username]; arguments []; default message [username]]; default message [must not be empty]
但是随后服务器返回 400 错误并呈现error.html
页面而不是返回表单,同样重要的是我registerMember()
在控制器中的方法根本没有被调用。它完全通过了我的逻辑,因此我什至无法使用BindingResult
.
如果我省略@Valid
模型上的注释,@ModelAttribute Member member
那么我的方法被调用但没有javax.validation
使用和BindingResult.getErrorCount()
is 0
,因此破坏了使用它的全部意义(我必须手动验证自己)。
知道如何让其@Valid
完成工作并返回/register
端点以显示字段级错误吗?
解决方案
您可以通过以下方式解决此问题。
- 您需要将方法签名从
public ModelAndView registerMember(HttpServletRequest请求,HttpServletResponse响应,@ModelAttribute @Valid Member成员,ModelMap模型,BindingResult结果)
对此
public ModelAndView registerMember(HttpServletRequest request, HttpServletResponse response,@ModelAttribute @Valid Member member, BindingResult result, ModelMap model)
因为绑定结果应该立即到@Valid 对象。
在此之后,您可以出错并发送所需的表格,如下所示
if (bindingResult.hasErrors()) {
return "register";
}
- 您可以控制处理异常的建议
@RestControllerAdvice @EnableWebMvc
公共类 ExceptionAdvice {
@ExceptionHandler(MethodArgumentNotValidException.class)
public Response handleInvaldException (MethodArgumentNotValidException ex, Response response) {
Map < String, String > errors = new HashMap < > ();
ex.getBindingResult().getAllErrors().forEach((err) - > {
String fieldName = ((FieldError) err).getField();
String errorMessage = err.getDefaultMessage();
errors.put(fieldName, errorMessage);
});
response.setData(errors);
retr
}
}
推荐阅读
- android - 不允许旋转 android 应用程序
- r - 如何绘制关于阿姆斯特丹邮政编码/社区的地图和数据
- oracle - oracle pl/sql utl_file ORA-29280: 无效的目录路径和 ORA-29280: 无效的目录对象
- javascript - Html - Javascript:Mysql不会将数据保存在数据库中
- django - Django 创建多对多关系
- jekyll - 如何禁用 github 页面中的排版?
- laravel - 根据 laravel 中的认证用户返回结果
- android - Firestore 查询缓存
- php - yajra 中的 Undefiend 变量
- arrays - 向 numpy 数组添加新列会更改初始数组