【问题标题】:Spring MVC Thymeleaf error template overriding inline form error messagesSpring MVC Thymeleaf 错误模板覆盖内联表单错误消息
【发布时间】:2018-05-26 17:04:46
【问题描述】:

我正在使用 Thymeleaf 验证表单并显示未通过验证的字段的内联错误。我正在使用 Spring Boot 1.5.8。

我有一个将绑定到表单的User 对象。它有如下字段:usernameemail。这是表单声明,

<form role="form" class="form" method="post"
    th:action="@{'/admin/user/new'}" th:object="${user}">

我设置了一个这样的错误控制器,因为我想要一个捕获所有错误页面。我还在src/main/resources/templates/error.html 创建了一个模板。这是因为根据这个 github issue,错误页面上的安全上下文丢失了,尽管它表明应该在我的版本中修复该问题。如果没有此控制器,则会显示默认错误模板,但我无权访问安全上下文。有了这个控制器和error.html 模板,任何随机错误都将得到处理。

@Controller
public class ErrorController extends BasicErrorController {

    /**
     * This Bean declaration provides the Spring Security Context to 4xx responses. This is reported as
     * fixed in Spring Boot 2.0.0:
     *
     * https://github.com/spring-projects/spring-boot/issues/1048
     *
     * @param springSecurityFilterChain
     * @return
     */
    @Bean
    public FilterRegistrationBean getSpringSecurityFilterChainBindedToError(
                    @Qualifier("springSecurityFilterChain") Filter springSecurityFilterChain) {

            FilterRegistrationBean registration = new FilterRegistrationBean();
            registration.setFilter(springSecurityFilterChain);
            registration.setDispatcherTypes(EnumSet.allOf(DispatcherType.class));
            return registration;
    }

    @Autowired
    public ErrorController(ErrorAttributes errorAttributes) {
        super(errorAttributes, new ErrorProperties());
    }

    @RequestMapping(value = "/error")
    public String error(Model model) {
        return "/error";
    }

    @Override
    public String getErrorPath() {
        return "/__dummyErrorPath";
    }

}

对于此示例,我只是尝试验证 email 字段,并在验证失败时在该字段旁边显示一条消息。 User 上的 class 字段如下所示,

@NotNull
@Email
private String email;

Thymeleaf 字段如下所示,

<div th:fragment="email" class="form-group">
    <label>Email*</label>
    <input class="form-control" type="text" th:field="*{email}" th:required="required" />
    <span class="error" th:if="${#fields.hasErrors('email')}" th:errors="*{email}">...</span>
</div>

新的用户表单控制器方法如下所示,

@GetMapping("admin/user/new")
public String newUser(Model model, HttpServletRequest request) {
    model.addAttribute("user", new User());
    return "admin/user/new";
}

而对应的POST方法是这样的,

@PostMapping("admin/user/new")
public String newUser(@Valid @ModelAttribute User user, final ModelMap model, BindingResult bindingResult) {
    Assert.notNull(user, "User must not be null");
    if (bindingResult.hasErrors()) {
        return "admin/user/new";
    }
    userService.save(user);
    model.clear();
    return "redirect:/admin/user/list";
}

在这个 POST 方法中,我正在检查 BindingResult 是否有错误。如果是这样,我希望 admin/user/new 模板将与显示的内联错误消息一起呈现。但是,我的捕获所有错误模板正在呈现。 URL 仍然显示/admin/user/new,刷新页面仍然显示错误模板。

我的主要问题是如何使用捕获所有错误页面并在需要时仍显示内联错误(如果可能)?

【问题讨论】:

    标签: spring forms validation spring-mvc thymeleaf


    【解决方案1】:

    我认为BindingResult需要直接跟在参数列表中Valid注解的参数后面。

    Why does BindingResult have to follow @Valid?

    我会试试的

    【讨论】:

    • 谢谢@benashby,这正是问题所在。我把签名改成public String newUser(@Valid @ModelAttribute User user, BindingResult bindingResult, final ModelMap model) {
    【解决方案2】:

    在 html-view 中使用这个怎么样?

    <div th:if="${param.error}"
         th:text="${session['SPRING_SECURITY_LAST_EXCEPTION'].message}">
    </div>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-04-26
      • 1970-01-01
      • 1970-01-01
      • 2010-12-01
      • 1970-01-01
      相关资源
      最近更新 更多