【发布时间】:2017-07-18 11:17:53
【问题描述】:
使用 JAX-RS,我已经成功地为不需要比 HTTP 状态代码更复杂的响应的异常实现了 ExceptionMapper,如下所示。
@Provider
public class ISBNNotFoundManager implements ExceptionMapper<ISBNNotFoundException>{
@Override
public Response toResponse(ISBNNotFoundException exception) {
return Response.status(NOT_FOUND).build();
}
}
这按预期工作。
但是,当 bean 验证失败时,我想用更有用的东西来响应。以下代码 sn-p 导致 MessageBodyProviderNotFoundException。
@Provider
public class ConstraintViolationExceptionMapper implements
ExceptionMapper<ConstraintViolationException> {
@Override
@Produces(MediaType.APPLICATION_JSON)
public Response toResponse(ConstraintViolationException exception) {
final Map<String, String> errorResponse =
exception.getConstraintViolations()
.stream()
.collect(
Collectors.toMap(o -> o.getPropertyPath().toString(), o -> o.getMessage()));
return Response.status(Response.Status.BAD_REQUEST).entity(errorResponse).build();
}
}
当发生 bean 验证时,响应包括 HTTP 响应代码 500,根本原因如下:
org.glassfish.jersey.message.internal.MessageBodyProviderNotFoundException:
MessageBodyWriter not found for media type=application/json,
type=class java.util.HashMap, genericType=class java.util.HashMap.
我试过的没有用:
-
像这样将地图包装在 GenericEntity 中。结果和上面一样:
新的 GenericEntity>(errorResponse) {}
我尝试了 DID 的工作:
-
将地图包裹在自定义的 POJO 中,DataIntegrityValidation,如下:
@XmlRootElement public class DataIntegrityValidation { private Map<String, String> errorResponse = new HashMap<>(); public Map<String, String> getErrorResponse() { return errorResponse; } public void setErrorResponse(Map<String, String> errorResponse) { this.errorResponse = errorResponse; } }
然后在 toResponse 方法中,我像这样将地图包装在 DataIntegrityValidation POJO 中,并将其添加到响应对象中。
DataIntegrityValidation dataIntegrityValidation =
new DataIntegrityValidation();
dataIntegrityValidation.setErrorResponse(errorResponse);
return
Response.status(Response.Status.BAD_REQUEST)
.entity(dataIntegrityValidation).build();
这给出了以下 JSON:
{
"errorResponse": {
"entry": [
{
"key": "saveBook.arg0.description",
"value": "size must be between 100 and 2147483647"
},
{
"key": "saveBook.arg0.published",
"value": "must be in the past"
},
{
"key": "saveBook.arg0.link",
"value": "must match \"^(https?:\\/\\/)?([\\da-z\\.-]+)\\.([a-z\\.]{2,6})([\\/\\w \\.-]*)*\\/?$\""
}
]
}
}
我可以忍受这个,但我真的很想知道为什么它不能处理地图,即使它被包装在通用实体中。
欢迎所有回复。
【问题讨论】:
标签: jax-rs