2014-07-21 45 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; 
    } 

}