【问题标题】:Spring MVC 3 validation with annotations - not showing form:errors带有注释的 Spring MVC 3 验证 - 不显示表单:错误
【发布时间】:2012-03-29 05:43:39
【问题描述】:

我已经坚持了大约一个小时,这不是我第一次这样做,但我无法弄清楚。

它应该向我显示表单错误,而不是抛出这个异常。

LE:同时我设法解决了异常,但我仍然看不到错误。它们没有被渲染

org.springframework.web.util.NestedServletException:请求处理失败;嵌套异常是 org.springframework.validation.BindException: org.springframework.validation.BeanPropertyBindingResult: 1 错误 字段“名称”上的对象“类别”中的字段错误:拒绝值 [jk];代码 [Range.category.name,Range.name,Range.java.lang.String,Range];参数 [org.springframework.context.support.DefaultMessageSourceResolvable: 代码 [category.name,name];论据 [];默认消息 [名称],25,3];默认消息 [gfhghj] org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:894) org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:789) javax.servlet.http.HttpServlet.service(HttpServlet.java:637) javax.servlet.http.HttpServlet.service(HttpServlet.java:717) org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:311) org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:116) org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:83) org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323) org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:113) org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323) org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:101) org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323) org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:113) org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323) org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:54) org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323) org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:45) org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323) org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilter(BasicAuthenticationFilter.java:150) org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323) org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:182) org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323) org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:105) org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323) org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87) org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323) org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:173) org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346) org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:259) org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:77) org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76) org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88) org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)

@Controller
@RequestMapping("/category")
public class CategoryController {

@Autowired
StockGateway stockGateway;

@RequestMapping(value = "add", method = RequestMethod.POST)
public String addCategory(@Valid @ModelAttribute("category") CategoryAdd category, ModelMap model,
        BindingResult binding) {

    if (binding.hasErrors()) {
        return "category.add";
    }
    CategoryDTO dto = Converter.toCategory(category);
    try {
        stockGateway.createCategory(dto);
    } catch (StockGatewayException e) {
        e.printStackTrace();
    }
    return "redirect:/category/add";

}

@RequestMapping(value = "add", method = RequestMethod.GET)
public String initView(ModelMap model) {
    model.put("category", new CategoryAdd());
    return "category.add";
}

}

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<div xmlns:jsp="http://java.sun.com/JSP/Page" 
xmlns:spring="http://www.springframework.org/tags"
 xmlns:c="http://java.sun.com/jsp/jstl/core" 
 xmlns:security = "http://www.springframework.org/security/tags"
 xmlns:util="urn:jsptagdir:/WEB-INF/tags/util"
 xmlns:form="http://www.springframework.org/tags/form"
 version="2.0">

<security:authorize access="hasRole('ROLE_STOCK')" var="isStock">
    <form:form modelAttribute="category"  method="POST" action="add"  >
            <table>
            <tr>
                <td>Name  :</td> <td> <form:input path="name" /></td>
            </tr>
            <tr>
                <td></td> <td> <form:errors path="name" cssClass="error" /></td>
            </tr>
            </table>
            <form:button>Add</form:button>
    </form:form>
</security:authorize>

public class CategoryAdd {

@Range(min= 3 , max = 25, message="gfhghj")
private String name;



public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

【问题讨论】:

  • 你确定binding.hasErrors() 是真的吗?
  • 是的。我正在使用瓷砖。这和它有什么关系吗?
  • 是的,如果binding.hasErrors() 为假,您将被重定向到 GET 而不是从 POST 返回,此时任何请求数据都会丢失。更不用说实际上没有错误:)
  • 您是否尝试将 @Range 放在 getter 上?

标签: java spring spring-mvc


【解决方案1】:

所以完整的解决方案是:

public String addCategory(@Valid CategoryAdd category,BindingResult result,
        Map map
        ) {

    if (result.hasErrors()) {
        map.put("categoryAdd", (CategoryAdd)result.getTarget());
        return "category.add";
    }
    CategoryDTO dto = Converter.toCategory(category);
    try {
        stockGateway.createCategory(dto);
    } catch (StockGatewayException e) {
        e.printStackTrace();
    }
    return "redirect:/category/add";

请注意,我将参数 ModelMap 更改为 Map,如果结果有错误,我会从结果中放回模型。

现在 WTF: BindingResult 有一个字段 objectName,它的值是类的名称。 您必须将 modelAttribute/commandName 设置为此。与 BindingResult 中的 objectName 相同,否则不会呈现错误。 所以要匹配它:

    <form:form modelAttribute="categoryAdd" commandName="categoryAdd"  method="POST" action="add"  >

有谁知道我们如何更改 BindingResult 中的 objectName?默认情况下,它将采用类的名称。

【讨论】:

  • 你可以直接使用类别参数而不是map.put("categoryAdd", (CategoryAdd)result.getTarget());map.put("category", category); -- 顺便说一句,模型属性名称应该是“category”而不是“category.add”
  • 模型名称现在是 categoryAdd 到处满足 form:errors。 category.add 是视图名称
  • 这是否与 url 映射有关,当我们有请求映射时,我们有类似 RequestMapping(value="/add", method = RequestMethodType.POST) 但我没有看到任何“/ “在您的映射中。这有什么区别吗?只是猜测。
  • @Blitzkr1eg 尝试创建一个用@ModelAttribute 注释的方法,它返回一个new CategoryAdd()
【解决方案2】:

似乎依赖于必须在映射控制器方法中列出参数的顺序。
例如:

public String addCategory(@Valid CategoryAdd category,BindingResult result, 
Map map)

会起作用,而:

public String addCategory(@Valid CategoryAdd category, Map map, 
BindingResult result)

不会。我不完全理解为什么会这样,尤其是编译时没有任何问题。

【讨论】:

  • 谢谢。我有完全相同的问题,无法弄清楚。经过大量搜索后,我发现了这一点,事实证明我必须在参数列表中的BindingResult 之后有我的Model
  • 订单似乎是个问题。我在 bindingResult 之前有 HttpServletRequest,这使它出错
  • Errors 或 BindingResult 参数必须遵循立即绑定的模型对象,因为方法签名可能具有多个模型对象,并且 Spring 将为它们中的每一个创建一个单独的 BindingResult 实例,因此以下示例不起作用:docs.spring.io/spring/docs/current/spring-framework-reference/…
  • 只是想说这很有帮助。很多解决方案,但订单最终成为我的实际问题。
  • 好的,谢谢。但我想知道为什么并得出结论,可能在有 2 个表单和 2 个 BindingResults 的情况下,我们可以决定将错误放在其中的哪个,所以 Spring 选择 @Valid 之后的参数。
猜你喜欢
  • 1970-01-01
  • 2010-10-04
  • 2011-07-21
  • 1970-01-01
  • 2012-09-09
  • 1970-01-01
  • 1970-01-01
  • 2011-02-21
  • 1970-01-01
相关资源
最近更新 更多