为什么使用 JAX-RS 与标准 servlet 时浏览器中的下载弹出窗口不显示?
当我尝试使用标准 servlet 方法时,浏览器中会显示弹出窗口,询问我是否打开 .xls 文件或保存它。
我通过 JAX-RS
尝试了完全相同的代码,浏览器弹出窗口不会以某种方式显示。有人遇到过这种情况吗?
不显示弹出窗口的 JAX-RS 方式:
@Path("excellaTest")
public class ExcellaTestResource {
@Context
private UriInfo context;
@Context
private HttpServletResponse response;
@Context
private HttpServletRequest request;
public ExcellaTestResource() {
}
@Path("horizontalProcess")
@GET
//@Produces("application/vnd.ms-excel")
@Produces("application/vnd.ms-excel")
public void getProcessHorizontally() {
try {
URL templateFileUrl = this.getClass().getResource("myExcelTemplate.xls");
String templateFilePath = URLDecoder.decode(templateFileUrl.getPath(), "UTF-8");
String outputFileDir = "MasatoExcelHorizontalOutput";
ReportProcessor reportProcessor = new ReportProcessor();
ReportBook outputBook = new ReportBook(templateFilePath, outputFileDir, ExcelExporter.FORMAT_TYPE);
ReportSheet outputSheet = new ReportSheet("myExcelSheet");
outputBook.addReportSheet(outputSheet);
reportProcessor.addReportBookExporter(new OutputStreamExporter(response));
reportProcessor.process(outputBook);
System.out.println("done!!");
}
catch(Exception e) {
System.out.println(e);
}
return;
}
}//end class
class OutputStreamExporter extends ReportBookExporter {
private HttpServletResponse response;
public OutputStreamExporter(HttpServletResponse response) {
this.response = response;
}
//ReportProcessor output()
//This method is call when ReportProcessor process() is invoked.
//The Workbook from POI API can be used to write to stream
@Override
public void output(Workbook book, BookData bookdata, ConvertConfiguration configuration) throws ExportException {
//TODO write to stream
try {
response.setContentType("application/vnd.ms-excel");
response.setHeader("Content-Disposition", "attachment; filename=masatoExample.xls");
book.write(response.getOutputStream());
response.getOutputStream().close();
System.out.println("booya!!");
}
catch(Exception e) {
System.out.println(e);
}
}
}//end class
When I try using standard servlet approach
, in my browser the popup window shows up asking me whether to open .xls file or save it.
I tried the exactly same code via JAX-RS
and the browser popup won't show up somehow. Has anyone encounter this?
JAX-RS way that won't display popup:
@Path("excellaTest")
public class ExcellaTestResource {
@Context
private UriInfo context;
@Context
private HttpServletResponse response;
@Context
private HttpServletRequest request;
public ExcellaTestResource() {
}
@Path("horizontalProcess")
@GET
//@Produces("application/vnd.ms-excel")
@Produces("application/vnd.ms-excel")
public void getProcessHorizontally() {
try {
URL templateFileUrl = this.getClass().getResource("myExcelTemplate.xls");
String templateFilePath = URLDecoder.decode(templateFileUrl.getPath(), "UTF-8");
String outputFileDir = "MasatoExcelHorizontalOutput";
ReportProcessor reportProcessor = new ReportProcessor();
ReportBook outputBook = new ReportBook(templateFilePath, outputFileDir, ExcelExporter.FORMAT_TYPE);
ReportSheet outputSheet = new ReportSheet("myExcelSheet");
outputBook.addReportSheet(outputSheet);
reportProcessor.addReportBookExporter(new OutputStreamExporter(response));
reportProcessor.process(outputBook);
System.out.println("done!!");
}
catch(Exception e) {
System.out.println(e);
}
return;
}
}//end class
class OutputStreamExporter extends ReportBookExporter {
private HttpServletResponse response;
public OutputStreamExporter(HttpServletResponse response) {
this.response = response;
}
//ReportProcessor output()
//This method is call when ReportProcessor process() is invoked.
//The Workbook from POI API can be used to write to stream
@Override
public void output(Workbook book, BookData bookdata, ConvertConfiguration configuration) throws ExportException {
//TODO write to stream
try {
response.setContentType("application/vnd.ms-excel");
response.setHeader("Content-Disposition", "attachment; filename=masatoExample.xls");
book.write(response.getOutputStream());
response.getOutputStream().close();
System.out.println("booya!!");
}
catch(Exception e) {
System.out.println(e);
}
}
}//end class
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您使用什么 JAX-RS 框架?
我的猜测是您的代码不起作用,因为您返回的是 void。您使用的框架可能会将 void 识别为 HTTP 204 No Content。 这会导致浏览器跳过实际的响应正文并忽略内容处置标头。
正如我已经在并行线程中写给您的:尝试返回 Response 对象。您可以将 OutputStream 或 byte[] 作为实体来设置内容处置标头。
What JAX-RS framework are you using?
My guess is that your code doesn't work, because you are returning void. The framework you are using probably recognizes void as HTTP 204 No Content. This causes browser to skip the actual response body and to ignore conntent-disposition header.
As I already wrote you in a parallel thread: try to returning Response object. You can put either OutputStream or byte[] as entity as set the content-disposition header.
我从未对 jax-rs 服务使用过类级别注入。我建议两种解决方案之一。
1)尝试将请求和响应作为方法参数注入。
2) 将文件输出到字节数组输出流,并从方法返回字节数组而不是 void。
I have never used class level injection for a jax-rs service. I suggest one of 2 solutions.
1) Try injecting the request and response as method arguments.
2) Output your file to a byte array output stream and return a byte array from your method instead of void.