使用Jersey序列化Java 8流 [英] Serialize Java 8 Stream with Jersey
问题描述
如何使用Jersey序列化Java 8 java.util.Stream< T>
。我试着写一个 MessageBodyWriter
,但我需要知道如何用新的<组合(装饰)现有的 MessageBodyWriters
code> MessageBodyWriter 我的流
。
How can I serialize a Java 8 java.util.Stream<T>
with Jersey. I tried to write a MessageBodyWriter
, but I need to know how to compose (decorate) existing MessageBodyWriters
with a new MessageBodyWriter
for my Stream
.
Stream<String> get(){
return some stream of strings
}
public <T> class StreamMessageBodyWriter<Stream<T>>
implements MessageBodyWriter<Stream<T>> {
public void writeTo(.......){
//How can I get the handle to MessageBodyWriter that will write for type T,
//so that I can 'collect' the 'java.util.Stream<T>' and write it to
//OutputStream
}
}
推荐答案
但我需要知道如何撰写(装饰)现有的
MessageBodyWriters
我的流
你可以注入 提供商
并使用 getMessagBodyWriter(...)
,将所需的详细信息传递给looku p该类型的特定编写者。例如
You can just inject Providers
and use getMessagBodyWriter(...)
, passing in the required details to lookup the specific writer for that type. For example
@Provider
public class StreamBodyWriter implements MessageBodyWriter<Stream> {
@Context
private Providers providers;
@Override
public boolean isWriteable(Class<?> type, Type genericType,
Annotation[] annotations, MediaType mediaType) {
return Stream.class.isAssignableFrom(type);
}
@Override
public long getSize(Stream stream, Class<?> type, Type genericType,
Annotation[] annotations, MediaType mediaType) { return -1; }
@Override
public void writeTo(Stream stream, Class<?> type, Type genericType,
Annotation[] annotations, MediaType mediaType,
MultivaluedMap<String, Object> httpHeaders, OutputStream entityStream)
throws IOException, WebApplicationException {
Object obj = stream.collect(Collectors.toList());
Class<?> objType = obj.getClass();
MessageBodyWriter writer = providers.getMessageBodyWriter(objType,
null, annotations, mediaType);
writer.writeTo(obj, objType, null, annotations,
mediaType, httpHeaders, entityStream);
}
}
如果你看 writeTo
,首先我调用 collect
然后获取返回的类型。然后查找该类型的编写器,然后简单地委托给编写者。
If you look at the writeTo
, first I call collect
then get the returned type. Then lookup the writer for that type, then simply delegate to the writer.
这是一个测试
@Path("stream")
public class StreamResource {
@GET
@Produces(MediaType.APPLICATION_JSON)
public Response getStream() {
List<Person> myList = Arrays.asList(
new Person("Stack"),
new Person("Overflow"),
new Person("Sam"));
Stream<Person> stream = myList.stream()
.filter(p -> p.name.startsWith("S"));
return Response.ok(stream).build();
}
public static class Person {
public String name;
public Person(String name) { this.name = name; }
public Person() {}
}
}
C:\> curl -v http:// localhost:8080 / api / stream
结果:
[{name:Stack},{name:Sam}]
顺便说一句,如果您打算在编写器中操作Stream,可能会考虑使用拦截器。真的不会有所作为,但如果你想坚持单一责任原则,这就是拦截器
用于操纵请求体。
As an aside, if you plan on manipulating the Stream in the writer, maybe look into using an Interceptor. Won't make a difference really, but if you want to stick to the Single Responsibility Principle, this is what the Interceptor
is for, manipulating the request body.
注意:以上是标准的JAX-RS
Note: the above is standard JAX-RS
特别是对泽西岛,你也可以注入 MessageBodyWorkers
,用于更具体的查找,甚至调用其 writeTo
,如果有人存在,将委托给所需的作家。
Specifically with Jersey, you can also inject MessageBodyWorkers
, for more specific lookup, and even calling its writeTo
, which will delegate to the required writer, if one exsists.
这篇关于使用Jersey序列化Java 8流的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!