如何在 Spring Boot Data Rest 控制器中 return RFC-7807 格式的验证错误?
How can I return validation errors in a RFC-7807 format in Spring Boot Data Rest controllers?
我有一个 Spring 存储库
@RepositoryRestResource
public interface MongoIntegrationTokenRepository extends MongoRepository<IntegrationToken, String>, CrudRepository<IntegrationToken, String> {}
我已经添加了验证配置以添加验证支持并且我的实体具有验证注释:
@Configuration
class MyRestMvcConfiguration implements RepositoryRestConfigurer {
private final LocalValidatorFactoryBean localValidatorFactoryBean;
@Autowired
public MyRestMvcConfiguration(LocalValidatorFactoryBean localValidatorFactoryBean) {
this.localValidatorFactoryBean = localValidatorFactoryBean;
}
@Override
public void configureValidatingRepositoryEventListener(
ValidatingRepositoryEventListener validatingRepositoryEventListener) {
validatingRepositoryEventListener.addValidator("beforeCreate", localValidatorFactoryBean);
validatingRepositoryEventListener.addValidator("beforeSave", localValidatorFactoryBean);
validatingRepositoryEventListener.addValidator("beforeSave", localValidatorFactoryBean);
}
}
当运行创建操作时,如果有任何验证错误,实体创建失败但JSON响应不包含任何错误详细信息。
A POST 到我端点的无效数据只是 returns:
{
"message": "Server Error",
"details": [
"Validation failed"
]
}
我想 return RFC7807 format. This should be possible via Spring HATEOAS or by this popular library by Zalando https://github.com/zalando/problem-spring-web 中的验证错误,但我不确定它们需要如何连接或应该使用哪种方法。
我在 Github 上找到了这个单独的例子。 https://github.com/marciovmartins/problem-spring-web-starter-expanded/blob/aed5825c958fad93f4aaad022689958926cf3b4a/src/main/kotlin/com/github/marciovmartins/problem/spring/web/expanded/ProblemExceptionHandler.kt 并在 Java 中重写了它。这个好像可以。
import java.util.List;
import java.util.stream.Collectors;
import org.springframework.data.rest.core.RepositoryConstraintViolationException;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.context.request.NativeWebRequest;
import org.zalando.problem.Problem;
import org.zalando.problem.ThrowableProblem;
import org.zalando.problem.spring.web.advice.ProblemHandling;
import org.zalando.problem.violations.Violation;
@ControllerAdvice
public class ProblemControllerAdvice implements ProblemHandling {
@ExceptionHandler
public ResponseEntity<Problem> handleRepositoryConstraintViolationException(RepositoryConstraintViolationException exception, NativeWebRequest request) {
List<Violation> violationList = exception.getErrors().getAllErrors()
.stream()
.map(objectError -> {
if (objectError instanceof FieldError) {
return new Violation(((FieldError) objectError).getField(), objectError.getDefaultMessage());
}
return new Violation(null, objectError.getDefaultMessage());
})
.collect(Collectors.toList());
ThrowableProblem problem = Problem.builder()
.withTitle("Constraint Violation")
.withStatus(defaultConstraintViolationStatus())
.with("violations", violationList)
.build();
return create(problem, request);
}
}
我有一个 Spring 存储库
@RepositoryRestResource
public interface MongoIntegrationTokenRepository extends MongoRepository<IntegrationToken, String>, CrudRepository<IntegrationToken, String> {}
我已经添加了验证配置以添加验证支持并且我的实体具有验证注释:
@Configuration
class MyRestMvcConfiguration implements RepositoryRestConfigurer {
private final LocalValidatorFactoryBean localValidatorFactoryBean;
@Autowired
public MyRestMvcConfiguration(LocalValidatorFactoryBean localValidatorFactoryBean) {
this.localValidatorFactoryBean = localValidatorFactoryBean;
}
@Override
public void configureValidatingRepositoryEventListener(
ValidatingRepositoryEventListener validatingRepositoryEventListener) {
validatingRepositoryEventListener.addValidator("beforeCreate", localValidatorFactoryBean);
validatingRepositoryEventListener.addValidator("beforeSave", localValidatorFactoryBean);
validatingRepositoryEventListener.addValidator("beforeSave", localValidatorFactoryBean);
}
}
当运行创建操作时,如果有任何验证错误,实体创建失败但JSON响应不包含任何错误详细信息。
A POST 到我端点的无效数据只是 returns:
{
"message": "Server Error",
"details": [
"Validation failed"
]
}
我想 return RFC7807 format. This should be possible via Spring HATEOAS or by this popular library by Zalando https://github.com/zalando/problem-spring-web 中的验证错误,但我不确定它们需要如何连接或应该使用哪种方法。
我在 Github 上找到了这个单独的例子。 https://github.com/marciovmartins/problem-spring-web-starter-expanded/blob/aed5825c958fad93f4aaad022689958926cf3b4a/src/main/kotlin/com/github/marciovmartins/problem/spring/web/expanded/ProblemExceptionHandler.kt 并在 Java 中重写了它。这个好像可以。
import java.util.List;
import java.util.stream.Collectors;
import org.springframework.data.rest.core.RepositoryConstraintViolationException;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.context.request.NativeWebRequest;
import org.zalando.problem.Problem;
import org.zalando.problem.ThrowableProblem;
import org.zalando.problem.spring.web.advice.ProblemHandling;
import org.zalando.problem.violations.Violation;
@ControllerAdvice
public class ProblemControllerAdvice implements ProblemHandling {
@ExceptionHandler
public ResponseEntity<Problem> handleRepositoryConstraintViolationException(RepositoryConstraintViolationException exception, NativeWebRequest request) {
List<Violation> violationList = exception.getErrors().getAllErrors()
.stream()
.map(objectError -> {
if (objectError instanceof FieldError) {
return new Violation(((FieldError) objectError).getField(), objectError.getDefaultMessage());
}
return new Violation(null, objectError.getDefaultMessage());
})
.collect(Collectors.toList());
ThrowableProblem problem = Problem.builder()
.withTitle("Constraint Violation")
.withStatus(defaultConstraintViolationStatus())
.with("violations", violationList)
.build();
return create(problem, request);
}
}