如何从jersey以avro格式发送/接收数据?

时间:2014-07-21 12:45:14

标签: json performance protocol-buffers jersey-2.0 avro

我有一组使用jersey开发的网络服务,目前网络服务以JSON格式发送和接收数据。为了提高处理时间和所需内存的性能,我们正在试验Protobufavro

我找到了一些教程,说明将protobuf集成到此类Web服务中是多么容易。但是我无法找到这样的教程或任何一本书,它们至少可以让我们知道我们是否可以使用avrojersey格式发送/接收数据。

我想知道如何使用avrojersey格式发送/接收数据。

1 个答案:

答案 0 :(得分:1)

我有类似的问题,我很惊讶其他人在两年内没有解决方案。我们正在使用Jersey 2.x,并使用Provider来处理Avro。

如果您生成代码,则此代码段有效。如果你不这样做,你必须使用 GenericDatumReader/WriterGenericRecord代替SpecificDataReader/WriterSpecificRecord

另请注意,Avro规范称使用avro/binary作为内容类型,尽管有一个6岁的JIRA ticket要更改它,因为它是无效的类型。

我将其剥离以使其简单,因此其中没有错误处理。如果您有一个共同的ExceptionMapper来捕获一般例外,请小心,因为它不知道如何生成avro二进制文件。

@Provider
@Consumes("avro/binary")
@Produces("avro/binary")
public class AvroProvider <T extends SpecificRecord> implements MessageBodyWriter<T>, MessageBodyReader<T>
{
    public boolean isWriteable(final Class<?> type, final Type genericType, final Annotation[] annotations,
            final MediaType mediaType)
    {
        return SpecificRecord.class.isAssignableFrom(type);
    }

    public boolean isReadable(final Class<?> type, final Type genericType, final Annotation[] annotations,
            final MediaType mediaType)
    {
        return true;
    }

    @Override
    public T readFrom(Class<T> type, Type genericType, Annotation[] annotations, MediaType mediaType,
            MultivaluedMap<String, String> httpHeaders, InputStream entityStream)
            throws IOException, WebApplicationException
    {
        DatumReader<T> reader = new SpecificDatumReader<>(type);
        Decoder decoder = DecoderFactory.get().binaryDecoder(entityStream, null);
        return reader.read(null, decoder);
    }

    @SuppressWarnings("unchecked")
    @Override
    public void writeTo(T message, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType,
            MultivaluedMap<String, Object> httpHeaders, OutputStream entityStream)
            throws IOException, WebApplicationException
    {
      DatumWriter<T> datumWriter = new SpecificDatumWriter<>((Class<T>)type);
      Encoder encoder = EncoderFactory.get().binaryEncoder(entityStream, null);
      datumWriter.write(message, encoder);
      encoder.flush();
    }

    @Override
    public long getSize(T message, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType)
    {
        return -1;
    }

}