使用JAX-RS,我已经成功实现了ExceptionMapper for Exceptions,它不需要比HTTP状态代码更复杂的响应,如下所示。
@Provider
public class ISBNNotFoundManager implements ExceptionMapper<ISBNNotFoundException>{
@Override
public Response toResponse(ISBNNotFoundException exception) {
return Response.status(NOT_FOUND).build();
}
}
这可以按预期工作。
但是,当bean验证失败时,我想回复一些更有用的东西。以下代码段会导致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中包装地图就像这样。与上面相同的结果:
new GenericEntity&gt;(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 \\.-]*)*\\/?$\""
}
]
}
}
我可以忍受这个,但我真的很想知道为什么它不能处理Map,即使它包含在Generic Entity中。
欢迎所有回复。
答案 0 :(得分:1)
Map和GenericEntity的编组失败的原因是因为没有与它们相关联的JAXB定义。当你将地图包裹在用@XmlRootElement
注释的POJO中时;它能够正确地编组它。