首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用泽西序列化Java 8流

用泽西序列化Java 8流
EN

Stack Overflow用户
提问于 2015-03-24 04:24:54
回答 2查看 2.1K关注 0票数 6

如何将Java 8 java.util.Stream<T>与泽西序列化。我试着编写一个MessageBodyWriter,但我需要知道如何用一个新的MessageBodyWriter来为MessageBodyWriters编写(装饰)现有的Stream

代码语言:javascript
复制
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
  }
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-03-24 06:54:12

但是我需要知道如何用一个新的MessageBodyWriters来为我的Stream编写(装饰)现有的MessageBodyWriter

您只需注入Providers并使用getMessagBodyWriter(...),传递所需的详细信息来查找该类型的特定编写器。例如

代码语言:javascript
复制
@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,然后得到返回的类型。然后查找该类型的编写器,然后将其委托给作者。

这是一个测试

代码语言:javascript
复制
@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"}]

顺便说一句,如果您打算在编写器中操作流,可以考虑使用拦截器。不会产生真正的影响,但是如果您想坚持单一责任原则,这就是Interceptor的目的,操作请求主体。

注:以上为标准JAX-RS。

或者..。

特别是在泽西岛,您还可以注入MessageBodyWorkers,以便进行更具体的查找,甚至调用它的writeTo,如果存在,它将委托给所需的编写器。

票数 4
EN

Stack Overflow用户

发布于 2017-02-08 23:32:09

为了符合使用流的目的(不使用stream.collect(Collectors.toList())),有一篇有趣的文章展示了如何从数据库序列化大型数据

就像这样..。

代码语言:javascript
复制
@GET
@Produces( "application/json" )
public Response streamGeneratedUuids() {

    return getNoCacheResponseBuilder( Response.Status.OK ).entity( new StreamingOutput() {

        @Override
        public void write( OutputStream os ) throws IOException, WebApplicationException {
            try (PrintWriter writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(os))) ) {
                //iterate the java.util.stream and write to the OutputStream
                writer.print("....");       
            }
        }
    }).build();
}

它不是用MessageBodyWriter实现的,但在我看来是可以适应的。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29225009

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档