我在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对象?
答案 0 :(得分:2)
StreamingOutput
是一个帮助类,允许我们直接写入响应输出流,但不打算从响应中重新创建,因此没有读取器将字节流转换为{{1 }}。我们可以简单地从响应中获得StreamingOutput
。
InputStream
完整示例:
Response response = target.request().get();
InputStream is = response.readEntity(InputStream.class);
只有Maven依赖
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));
}
}
结果: