我开发了一个 Java REST 服务,使用 JSON-B 将传入的有效负载映射到 POJO。
现在我想做的是验证传入的有效负载,可能是针对 JSON 模式,但到目前为止我还没有找到任何这种意义上的东西......
是否可以覆盖默认的 JSON-B 映射过程,从而捕获任何映射异常并自行处理?
我开发了一个 Java REST 服务,使用 JSON-B 将传入的有效负载映射到 POJO。
现在我想做的是验证传入的有效负载,可能是针对 JSON 模式,但到目前为止我还没有找到任何这种意义上的东西......
是否可以覆盖默认的 JSON-B 映射过程,从而捕获任何映射异常并自行处理?
为此,您可以注册自己的 JAX-RS 提供程序,该提供程序执行 JSON(反)序列化并在那里处理任何错误。
例如:
@Consumes({ "*/*" })
@Provider
public class JsonBProvider implements MessageBodyReader<Object> {
private static final Jsonb jsonb = JsonbBuilder.create();
@Override
public boolean isReadable(Class<?> type, Type genericType,
Annotation[] annotations,
MediaType mediaType) {
return true;
}
@Override
public Object readFrom(Class<Object> clazz, Type genericType, Annotation[] annotations,
MediaType mediaType, MultivaluedMap<String, String> httpHeaders,
InputStream entityStream)
throws IOException, WebApplicationException {
try {
return this.jsonb.fromJson(entityStream, clazz);
} catch (Exception e) {
// Do your custom handling here
}
}
}
这将覆盖通过 JAX-RS 和 JSON-B 发生的反序列化。
注意:如果你也想对序列化做同样的事情,你可以MessageBodyWriter<Object>
用类似的方式实现。
验证和反序列化是分开的问题,所以我只会在我真的需要时将它们联系在一起,例如,如果你真的必须使用 JSON 模式。但是,如果您可以自由选择自己的方式来声明约束,我建议使用 bean 验证,例如像这样的 JAX-RS 资源(注意@Valid
注释):
@Path("ping")
public class PingBoundary {
@POST
public String ping(@NotNull @Valid Person addressee) {
return "Hi " + addressee.getName() + "!";
}
}
还有一个像这样的有效负载类(使用lombok @Data 注释):
@Data
public class Person {
private String name;
@Min(0)
private short age;
}
传递一个无效age
的 -2 会给你400 Bad Request
一个有用的响应体:
{
"classViolations": [],
"exception": null,
"fieldViolations": [],
"parameterViolations": [
{
"constraintType": "PARAMETER",
"message": "must be greater than or equal to 0",
"path": "ping.addressee.age",
"value": "-2"
}
],
"propertyViolations": [],
"returnValueViolations": []
}
请注意,您应该传递-parameters
给编译器,否则path
将是ping.arg0.age
.