【问题标题】:using validators in spring-data-rest returns http 500 instead of 400在 spring-data-rest 中使用验证器返回 http 500 而不是 400
【发布时间】:2014-03-28 14:13:36
【问题描述】:

我正在尝试让 spring-data-rest 中的验证工作。从文档中,您只需要提供一个验证器,我已经让它工作了,但是当一个验证约束被成功捕获/处理时,我会得到一个带有堆栈跟踪的 500 错误页面。

在配置类 RepositoryRestMvcConfiguration 它有一个validationExceptionHandler,看起来它应该得到这样的验证错误以返回400而不是500。它也是一个延迟加载的bean。

我的设置不正确吗?还是有其他方法可以让 spring-data-rest 返回 400 而不是 500?

我正在使用 spring-data-rest 2.0.0 版本

tomcat 返回的堆栈跟踪:

HTTP Status 500 - Request processing failed; nested exception is javax.validation.ConstraintViolationException: Validation failed for classes [test.domain.Account] during persist time for groups [javax.validation.groups.Default, ]

org.springframework.web.util.NestedServletException: Request processing failed; nested exception is javax.validation.ConstraintViolationException: Validation failed for classes [test.domain.Account] during persist time for groups [javax.validation.groups.Default, ]
List of constraint violations:[
    ConstraintViolationImpl{interpolatedMessage='size must be between 0 and 10', propertyPath=login, rootBeanClass=class test.domain.Account, messageTemplate='{javax.validation.constraints.Size.message}'}
]
    org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:965)
    org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:855)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:647)
    org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:829)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
    org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)

账户实体:

@Entity
public class Account {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    Long id;

    @Column(unique = true)
    @Size(max = 10)
    String login;

}

RestMvcConfig:

@Configuration
public class RestExporterRestConfig extends RepositoryRestMvcConfiguration {}

【问题讨论】:

  • 它应该返回 400,因为它来自客户端的错误请求。您可以使用 response.setStatus(400); 来设置状态;
  • 是的,我同意它应该返回 400,我提出的问题是我认为 spring-data-rest 没有通过返回 400 来正确处理这些验证错误,所以我认为我错过了配置或validationExceptionHandler bean中的某些内容没有被加载或使用。
  • 由于服务器端的异常,您将获得 500(这是非常合适的)。此外,您应该处理此异常并手动将状​​态码设置为 400。
  • 这就是为什么我认为 RepositoryRestMvcConfiguration 中的 validationExceptionHandler 应该在做的原因,原因是 javax.validation.ConstraintViolationException 类型,它应该把它变成 400。所以要么是 bean未加载或从未使用过。我将尝试将 tomcat 设置为调试模式,看看该 bean 是否真的被初始化了。

标签: spring spring-mvc spring-data-rest


【解决方案1】:

似乎已经开始工作了;我必须重写 validatingRepositoryEventListener() 并手动将验证器添加到侦听器;

@Configuration
public class RestExporterRestConfig extends RepositoryRestMvcConfiguration {

    @Bean
    public Validator validator() {
        return new LocalValidatorFactoryBean();
    }

    @Bean
    @Override
    public ValidatingRepositoryEventListener validatingRepositoryEventListener() {
        ValidatingRepositoryEventListener listener = new ValidatingRepositoryEventListener();
        configureValidatingRepositoryEventListener(listener);
        listener.addValidator("afterCreate", validator());
        listener.addValidator("beforeCreate", validator());
        return listener;
    }

}

我现在得到如下返回的 400;

400 Bad Request
{"errors":
    [{  "entity":"Account",
        "message":"size must be between 0 and 10",
        "invalidValue":"login 0dsfdsfdsfdsfdsfdsfdsfds",
        "property":"login"
    }]
}

【讨论】:

  • 您是否遇到过更多麻烦?我有这个设置,但只能得到某些字段的上述响应。对于其他领域,我仍然收到 ConstraintViolationException。
【解决方案2】:

以前的答案对我不起作用,我认为由于 Spring Data Rest 的变化,所以这里有一个更新的答案,它与 JPA 和 MongoDb 一起工作,以节省其他人在这方面花费大量时间。

必须将此添加到我的 build.gradle 依赖项中

    compile('org.hibernate:hibernate-validator:4.2.0.Final')

还有这个配置类

@Configuration
public class CustomRepositoryRestConfigurerAdapter extends RepositoryRestConfigurerAdapter {


   @Bean
   public Validator validator() {
       return new LocalValidatorFactoryBean();
   }

   @Override
   public void configureValidatingRepositoryEventListener(ValidatingRepositoryEventListener validatingListener) {
       validatingListener.addValidator("afterCreate", validator());
       validatingListener.addValidator("beforeCreate", validator());
       validatingListener.addValidator("afterSave", validator());
       validatingListener.addValidator("beforeSave", validator());
   }
}

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2022-09-28
  • 2014-08-10
  • 1970-01-01
  • 2019-01-22
  • 2018-01-17
  • 2016-05-28
  • 1970-01-01
  • 2015-05-07
相关资源
最近更新 更多