我有一组使用jersey
开发的网络服务,目前网络服务以JSON
格式发送和接收数据。为了提高处理时间和所需内存的性能,我们正在试验Protobuf
和avro
。
我找到了一些教程,说明将protobuf
集成到此类Web服务中是多么容易。但是我无法找到这样的教程或任何一本书,它们至少可以让我们知道我们是否可以使用avro
以jersey
格式发送/接收数据。
我想知道如何使用avro
以jersey
格式发送/接收数据。
答案 0 :(得分:1)
我有类似的问题,我很惊讶其他人在两年内没有解决方案。我们正在使用Jersey 2.x,并使用Provider
来处理Avro。
如果您生成代码,则此代码段有效。如果你不这样做,你必须使用
GenericDatumReader/Writer
和GenericRecord
代替SpecificDataReader/Writer
和SpecificRecord
。
另请注意,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;
}
}