我在Spring中实现了一个自定义的Validator,它在被重写的Jackson de-serializer中调用。如果验证失败,我希望HTTP响应代码是我的ControllerAdvice中定义的403 Forbidden。
但是,响应总是400 Bad Request。
display: inline
public class InterceptedDeserializer extends StdDeserializer<Object> implements ResolvableDeserializer
{
public InterceptedDeserializer(JsonDeserializer<?> defaultDeserializer)
{
super(Object.class);
this.defaultDeserializer = defaultDeserializer;
}
@Override public Object deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, My403Exception
{
this.classFieldValidator = ServletUtils.findWebApplicationContext().getBean(ClassFieldValidator.class);
Object deserializedObject = defaultDeserializer.deserialize(jp, ctxt);
Errors errors = new BeanPropertyBindingResult(deserializedObject, deserializedObject.getClass().getName());
classFieldValidator.validate(deserializedObject, errors);
if(errors.hasErrors() || errors.hasFieldErrors()){
throw new My403Exception("No funny business");
}
return deserializedObject;
}
}
@ControllerAdvice
public class ValidationControllerAdvice {
private static final Logger log = LoggerFactory.getLogger(ValidationControllerAdvice.class);
private final StringWriter sw = new StringWriter();
@ResponseBody
@ExceptionHandler(My403Exception.class)
@ResponseStatus(HttpStatus.FORBIDDEN)
public ErrorResponse my403Exception(My403Exception e) {
ErrorResponse errorResponse = new ErrorResponse();
errorResponse.setErrorCode("my403");
errorResponse.setDescription(e.getMessage());
errorResponse.setMessage(e.getMessage());
e.printStackTrace(new PrintWriter(sw));
String eStackTrace = sw.toString();
log.error("My403 error message: " + e.getMessage() + "\nException Class:" + e.getClass() + "\nStack Trace:" + eStackTrace);
return errorResponse;
}
}
@ResponseStatus(value = HttpStatus.FORBIDDEN)
public class My403Exception extends RuntimeException{
private String message;
public My403Exception(String message) {
super(message);
this.message = message;
}
public My403Exception() {
}
@Override
public String getMessage() {
return message;
}
}