使用嵌套流来传输REST响应

时间:2016-08-24 15:56:28

标签: rest jersey jackson streaming jax-rs

我有一个场景,我想在实施和尝试不同的解决方案之前获得更广泛的意见。

我实现的REST服务将为包含多个二进制数据字段和简单字符串的模型提供服务。一种简单的方法就是实现包含我的String,byte []字段的POJOS等.Jackson然后使用base64为我序列化它。一块蛋糕。

但我想将其作为流服务。二进制字段非常庞大,并且已经作为从我服务中的另一个外部资源传入的流处理。因此,将它们读入字节数组然后让杰克逊将它们转换为base64将会产生不可接受的性能损失。

也许我可以在POJO中简单地使用OutputStream对象。这会让杰克逊流过(虽然编码为base64)或者它是否会首先读取整个流?也许杰克逊根本不支持这个?

另一种选择可能是使用多部分响应,但不确定Jersey是否也不会缓冲它?

或者唯一的方法就是使用某种自定义的jackson序列化器? 我可以使用StreamingOutput来执行此操作吗?

如果它只是一个blob我会简单地将它作为一个八位字节流返回并且很高兴,但如上所述,我有一个带有几个二进制和非二进制字段的数据模型,我真的想将它全部返回一个电话。

那么你怎么说?什么是实现目标的最简单/最好的方式?

1 个答案:

答案 0 :(得分:0)

所以如果有人有兴趣的话,我找到了可行的方法。

在DTO类中,我可以使用InputStream类型的字段并将它们设置为使用自定义序列化程序:

public class ModelDTO {
    private String someString;
    private String someOtherString;
    @JsonSerialize(using = InputStreamSerializer.class)
    private InputStream firstBlob;
    @JsonSerialize(using = InputStreamSerializer.class)
    private InputStream secondBlob;
...
}

序列化器:

public class InputStreamSerializer extends JsonSerializer<InputStream> {

    @Override
    public void serialize(InputStream inputStream, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
        jsonGenerator.writeBinary(Base64Variants.MIME_NO_LINEFEEDS, inputStream, -1);
    }
}

我还没有完全确认它,但是我可以看到杰克逊只会使用一个缓冲区将它写入OutputStream,因此如果它非常大,则不会缓冲整个传入流。

所以这是解决我问题的一个(非常简单的)解决方案,但是如果有人有其他建议我很乐意听到它们。