我有类似的问题,我很惊讶没有人在两年内有过解决方案。我们使用的是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;
}
}
来源
2016-09-13 15:55:06
max