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>'并将其写入//输出流}}但我需要知道如何为我的
使用新的StreamMessageBodyWriter组合(装饰)现有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
MessageBodyWriterswith a newMessageBodyWriterfor 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 流
- Eclipse 插件更新错误日志在哪里? 2022-01-01
- C++ 和 Java 进程之间的共享内存 2022-01-01
- 将log4j 1.2配置转换为log4j 2配置 2022-01-01
- 如何使用WebFilter实现授权头检查 2022-01-01
- Java包名称中单词分隔符的约定是什么? 2022-01-01
- 从 finally 块返回时 Java 的奇怪行为 2022-01-01
- Safepoint+stats 日志,输出 JDK12 中没有 vmop 操作 2022-01-01
- Jersey REST 客户端:发布多部分数据 2022-01-01
- value & 是什么意思?0xff 在 Java 中做什么? 2022-01-01
- Spring Boot连接到使用仲裁器运行的MongoDB副本集 2022-01-01
