【问题标题】:Jersey2.13: MessageBodyReader not found for StreamingOutputJersey2.13:未找到 StreamingOutput 的 MessageBodyReader
【发布时间】:2015-01-28 11:37:37
【问题描述】:

我在 Response 对象中返回一个 StreamingOutput:

@GET
@Path("/downloadFile/{filename}")
@Produces(MediaType.TEXT_PLAIN)
public Response downloadFile(@PathParam("filename") String fileName) {

    LOG.debug("called: downloadFile({})", fileName);

    final File f = new File("/tmp/" + fileName);

    try {
        if (f.exists()) {
            StreamingOutput so = new StreamingOutput() {
                @Override
                public void write(OutputStream os) throws IOException,
                        WebApplicationException {
                    FileInputStream fis = new FileInputStream(f);
                    byte[] buffer = new byte[4 * 1024];
                    int bytesRead;
                    while ((bytesRead = fis.read(buffer)) != -1) {
                        LOG.debug("streaming file contents @{}", bytesRead);
                        os.write(buffer, 0, bytesRead);
                    }
                    fis.close();
                    os.flush();
                    os.close();
                }
            };

            return Response.ok(so, MediaType.TEXT_PLAIN).build();
        } else {
            return createNegativeXmlResponse("file not found or not readable: '"
                    + f.getPath() + "'");
        }
    } catch (Exception e) {
        return handle(e);
    }
}

客户端(Junit 测试用例):

@Test
public void testDownloadFile() throws Exception {
    Client client = ClientBuilder.newBuilder()
            .register(MultiPartFeature.class).build();
    WebTarget target = client.target(BASE_URI).path("/downloadFile/b.txt");
    Response r = target.request(MediaType.TEXT_PLAIN_TYPE).get();

    System.out.println(r.getStatus());

    Object o = r.readEntity(StreamingOutput.class);
    StreamingOutput so = (StreamingOutput) o;
}

服务器在 tomcat7 实例中运行。执行 r.readEntity 时我在客户端得到的是:

org.glassfish.jersey.message.internal.MessageBodyProviderNotFoundException: MessageBodyReader not found for media type=text/plain, type=interface javax.ws.rs.core.StreamingOutput, genericType=interface javax.ws.rs.core.StreamingOutput.
at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$TerminalReaderInterceptor.aroundReadFrom(ReaderInterceptorExecutor.java:230)
at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor.proceed(ReaderInterceptorExecutor.java:154)
...

如何从客户端的 Response 对象中获取 StreamingOutput 对象?

【问题讨论】:

    标签: java tomcat jersey jax-rs


    【解决方案1】:

    StreamingOutput 是一个帮助类,允许我们直接写入响应输出流,但并不意味着从响应中重新创建,因此没有读取器将字节流转换为StreamingOutput。不过,我们可以简单地从响应中获取InputStream

    Response response = target.request().get();
    InputStream is = response.readEntity(InputStream.class);
    

    完整示例:

    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.net.URL;
    import javax.imageio.ImageIO;
    import javax.swing.ImageIcon;
    import javax.swing.JLabel;
    import javax.swing.JOptionPane;
    import javax.ws.rs.GET;
    import javax.ws.rs.Path;
    import javax.ws.rs.Produces;
    import javax.ws.rs.WebApplicationException;
    import javax.ws.rs.core.Application;
    import javax.ws.rs.core.MediaType;
    import javax.ws.rs.core.Response;
    import javax.ws.rs.core.StreamingOutput;
    import org.glassfish.jersey.server.ResourceConfig;
    import org.glassfish.jersey.test.JerseyTest;
    import org.junit.Test;
    
    public class TestStreamingOutput extends JerseyTest {
    
        @Path("/streaming")
        public static class StreamingResource {
    
            @GET
            public StreamingOutput getImage() throws Exception {
                final InputStream is 
                        = new URL("http://i.stack.imgur.com/KSnus.gif").openStream();
                return new StreamingOutput() {
                    @Override
                    public void write(OutputStream out)
                            throws IOException, WebApplicationException {
                        byte[] buffer = new byte[4 * 1024];
                        int bytesRead;
                        while ((bytesRead = is.read(buffer)) != -1) {
                            out.write(buffer, 0, bytesRead);
                        }
                        out.flush();
                        out.close();
                        is.close();
                    }
                };
            }
        }
    
        @Override
        protected Application configure() {
            return new ResourceConfig(StreamingResource.class);
        }
    
        @Test
        public void test() throws Exception {
            Response response = target("streaming").request().get();
            InputStream is = response.readEntity(InputStream.class);
            ImageIcon icon = new ImageIcon(ImageIO.read(is));
            JOptionPane.showMessageDialog(null, new JLabel(icon));
        }
    }
    

    只有 Maven 依赖

    <dependency>
        <groupId>org.glassfish.jersey.test-framework.providers</groupId>
        <artifactId>jersey-test-framework-provider-grizzly2</artifactId>
        <version>2.13</version>
        <scope>test</scope>
    </dependency>
    

    结果:

    【讨论】:

      猜你喜欢
      • 2013-05-03
      • 2014-06-19
      • 1970-01-01
      • 2016-02-17
      • 1970-01-01
      • 1970-01-01
      • 2013-11-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多