使用jax-rs,我成功地实现了一个异常的异常,该异常不需要比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.
我尝试过的不起作用的方法:
像这样的通用性包装地图。与上述相同的结果:
new generentity>(errorresponse){}
我尝试的工作工作:
将地图包裹在自定义的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 \.-]*)*\/?$""
}
]
}
}
我可以忍受这个,但真的很想知道为什么即使将其包裹在通用实体中,也无法处理地图。
欢迎所有答复。
地图和通用性都失败的原因是因为没有与之关联的JAXB定义。当您用@XmlRootElement
注释的POJO包裹地图时;它能够正确搭配。