2014-07-21 44 views
2

我有一套使用jersey开发的web服务,目前的web服务以JSON的格式发送和接收数据。为了提高处理时间和内存需求方面的性能,我们正在试验Protobufavro如何从泽西岛发送/接收avro格式的数据?

我发现了一些教程,说明将protobuf集成到这样的Web服务中是多么容易。但是我无法找到这样一本教程或者任何能够给我们提供关于我们是否可以使用jerseyavro格式发送/接收数据的想法的书。

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

回答

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; 
    } 

}