我認爲Cepr0的PUT和POST測試工作,因爲當你發送一個PUT請求給一個不存在的實體時,Spring Data Rest在後臺使用create方法。 假設有一個id = 100沒有用戶: 叫「把用戶/ 100」是與調用「POST用戶/」
當您發送PUT對現有的實體,它會產生討厭的TransactionSystemException。
我現在也在與Data Rest異常處理做鬥爭,並且存在很多不一致。
這是我目前的RestErrorAttributes類,它解決了我的大部分問題,但是在接下來的日子裏我很喜歡其他人。 :)
@Component
@Slf4j
public class RestErrorAttributes extends DefaultErrorAttributes implements MessageSourceAware {
private MessageSource messageSource;
@Override
public void setMessageSource(MessageSource messageSource) {
this.messageSource = messageSource;
}
/** {@inheritDoc} */
@Override
public Map<String, Object> getErrorAttributes(RequestAttributes requestAttributes, boolean includeStackTrace) {
final Map<String, Object> errorAttributes = super.getErrorAttributes(requestAttributes, includeStackTrace);
// Translate default message by Locale
String message = errorAttributes.get("message").toString();
errorAttributes.put("message",
messageSource.getMessage(message, null, message, LocaleContextHolder.getLocale()));
// Extend default error message by field-errors
addConstraintViolationDetails(errorAttributes, requestAttributes);
return errorAttributes;
}
private void addConstraintViolationDetails(Map<String, Object> errorAttributes,
RequestAttributes requestAttributes) {
Throwable error = getError(requestAttributes);
if (error instanceof ConstraintViolationException) {
errorAttributes.put("errors",
RestFieldError.getErrors(((ConstraintViolationException) error).getConstraintViolations()));
}
else if (error instanceof RepositoryConstraintViolationException) {
errorAttributes.put("errors", RestFieldError
.getErrors(((RepositoryConstraintViolationException) error).getErrors().getAllErrors()));
}
}
/** {@inheritDoc} */
@Override
public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler,
Exception ex) {
try {
Throwable cause = ex;
while (cause instanceof Exception) {
// Handle AccessDeniedException - It cannot be handled by
// ExceptionHandler
if (cause instanceof AccessDeniedException) {
response.sendError(HttpStatus.FORBIDDEN.value(), cause.getMessage());
super.resolveException(request, response, handler, (Exception) cause);
return new ModelAndView();
}
// Handle exceptions from javax validations
if (cause instanceof ConstraintViolationException) {
response.sendError(HttpStatus.UNPROCESSABLE_ENTITY.value(), "validation.error");
super.resolveException(request, response, handler, (Exception) cause);
return new ModelAndView();
}
// Handle exceptions from REST validator classes
if (cause instanceof RepositoryConstraintViolationException) {
response.sendError(HttpStatus.UNPROCESSABLE_ENTITY.value(), "validation.error");
super.resolveException(request, response, handler, (Exception) cause);
return new ModelAndView();
}
cause = ((Exception) cause).getCause();
}
} catch (final Exception handlerException) {
log.warn("Handling of [" + ex.getClass().getName() + "] resulted in Exception", handlerException);
}
return super.resolveException(request, response, handler, ex);
}
@Getter
@AllArgsConstructor
public static class RestFieldError {
private String field;
private String code;
private String message;
public static List<RestFieldError> getErrors(Set<ConstraintViolation<?>> constraintViolations) {
return constraintViolations.stream().map(RestFieldError::of).collect(Collectors.toList());
}
public static List<RestFieldError> getErrors(List<ObjectError> errors) {
return errors.stream().map(RestFieldError::of).collect(Collectors.toList());
}
private static RestFieldError of(ConstraintViolation<?> constraintViolation) {
return new RestFieldError(constraintViolation.getPropertyPath().toString(),
constraintViolation.getMessageTemplate(), constraintViolation.getMessage());
}
private static RestFieldError of(ObjectError error) {
return new RestFieldError(error instanceof FieldError ? ((FieldError) error).getField() : null,
error.getCode(), error.getDefaultMessage());
}
}
}
的可能的複製[PUT和POST失敗未知性質春天不同的行爲(http://stackoverflow.com/questions/34545997/put-and-post-fail-on -unknown-properties-spring-different-behavior) – pvpkiran
你可以共享restcontroller類嗎? – barbakini
我正在使用Spring Data Rest,因此Spring在運行時生成端點,因此不需要實現自定義控制器 –