5

我开发了一个 Java REST 服务,使用 JSON-B 将传入的有效负载映射到 POJO。

现在我想做的是验证传入的有效负载,可能是针对 JSON 模式,但到目前为止我还没有找到任何这种意义上的东西......

是否可以覆盖默认的 JSON-B 映射过程,从而捕获任何映射异常并自行处理?

4

3 回答 3

1

为此,您可以注册自己的 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>用类似的方式实现。

于 2018-12-11T04:18:26.793 回答
0

验证和反序列化是分开的问题,所以我只会在我真的需要时将它们联系在一起,例如,如果你真的必须使用 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.

于 2019-06-16T05:15:02.953 回答
0

如果你真的坚持使用 JSON Schema,那么在反序列化的同时验证 JSON 文档可以通过使用Justify来实现。有一个绑定示例展示了如何将 JSON 验证器与 JSON-B 一起使用。我希望示例代码可以帮助你。

完全披露:我是图书馆的作者。

于 2019-06-18T12:08:27.203 回答