我有一个类似的问题,我很惊讶两年来没有其他人找到解决方案。我们使用的是 Jersey 2.x,我使用了 Provider 来处理 Avro。
如果您生成代码,则此 sn-p 有效。如果你不这样做,你必须使用
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;
}
}