Serialize Java 8 Stream with Jersey(使用 Jersey 序列化 Java 8 流)
问题描述
如何使用 Jersey 序列化 Java 8 java.util.Stream<T>
.我尝试编写 MessageBodyWriter
,但我需要知道如何为我的 使用新的
.MessageBodyWriter
组合(装饰)现有 MessageBodyWriters
流
流<字符串>得到(){返回一些字符串流}公共<T>类 StreamMessageBodyWriter<Stream<T>>实现 MessageBodyWriter<Stream<T>>{公共无效 writeTo(.......){//如何获取将为类型 T 编写的 MessageBodyWriter 的句柄,//这样我就可以'收集''java.util.Stream<T>'并将其写入//输出流}}
但我需要知道如何为我的
使用新的Stream
MessageBodyWriter
组合(装饰)现有MessageBodyWriters
您可以只注入
Providers
并使用getMessagBodyWriter(...)
,传入所需的详细信息以查找该类型的特定编写器.例如@Provider公共类 StreamBodyWriter 实现 MessageBodyWriter
;{@语境私人提供者提供者;@覆盖public boolean isWriteable(Class<?> type, Type genericType,Annotation[] 注释,MediaType mediaType) {返回 Stream.class.isAssignableFrom(type);}@覆盖public long getSize(Stream stream, Class<?> type, Type genericType,Annotation[] 注释,MediaType mediaType) { return -1;}@覆盖public void writeTo(Stream stream, Class<?> type, Type genericType,Annotation[] 注释,MediaType mediaType,多值映射<字符串,对象>httpHeaders、OutputStream 实体流)抛出 IOException,WebApplicationException {对象 obj = stream.collect(Collectors.toList());类<?>objType = obj.getClass();MessageBodyWriter writer = providers.getMessageBodyWriter(objType,空,注释,媒体类型);writer.writeTo(obj, objType, null, 注释,媒体类型,httpHeaders,实体流);}} 如果您查看
writeTo
,首先我调用collect
然后获取返回的类型.然后查找该类型的编写器,然后简单地委托给编写器.这是一个测试
@Path(流")公共类 StreamResource {@得到@Produces(MediaType.APPLICATION_JSON)公共响应 getStream() {列出<人员>myList = Arrays.asList(新人(堆栈"),新人(溢出"),新人(山姆"));流<人>流 = myList.stream().filter(p -> p.name.startsWith(S"));返回 Response.ok(stream).build();}公共静态类人{公共字符串名称;public Person(String name) { this.name = name;}公共人(){}}}
<块引用>
C:>curl -v http://localhost:8080/api/stream
结果:[{name":Stack"},{name":Sam"}]
顺便说一句,如果您打算在编写器中操作 Stream,可以考虑使用 拦截器.真的不会有什么不同,但如果你想坚持单一职责原则,这就是 Interceptor
的用途,操纵请求正文.
注意:以上是标准的 JAX-RS
或者...
特别是对于 Jersey,您还可以注入 MessageBodyWorkers
,用于更具体的查找,甚至调用它的 writeTo
,如果存在,它将委托给所需的编写器.
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
}
}
but I need to know how to compose (decorate) existing
MessageBodyWriters
with a newMessageBodyWriter
for myStream
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);
}
}
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.
Here is a test
@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
Result:
[{"name":"Stack"},{"name":"Sam"}]
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.
Note: the above is standard JAX-RS
Alternatively...
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 流的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:使用 Jersey 序列化 Java 8 流
基础教程推荐
- 在 Libgdx 中处理屏幕的正确方法 2022-01-01
- 如何使用 Java 创建 X509 证书? 2022-01-01
- 降序排序:Java Map 2022-01-01
- FirebaseListAdapter 不推送聊天应用程序的单个项目 - Firebase-Ui 3.1 2022-01-01
- 无法使用修饰符“public final"访问 java.util.Ha 2022-01-01
- “未找到匹配项"使用 matcher 的 group 方法时 2022-01-01
- Java Keytool 导入证书后出错,"keytool error: java.io.FileNotFoundException &拒绝访问" 2022-01-01
- Java:带有char数组的println给出乱码 2022-01-01
- 设置 bean 时出现 Nullpointerexception 2022-01-01
- 减少 JVM 暂停时间 >1 秒使用 UseConcMarkSweepGC 2022-01-01