我有一个控制器,用于刷新字节,这将在客户端生成PDF。但是,如果发生异常,我想抓住它并向用户显示一些适当的消息。
我尝试了Ajax,但Ajax仅使用JSON,String或XML进行消息交换格式。我该如何处理这个条件?
我必须在成功案例中生成pdf或捕获异常。这是我的控制器和javascript代码
try {
MyUtil.generatePdf(response, documentBytes, "DU"); // --> This method will flush the bytes
} catch (Exception e) {
result.setStatus("EXCEPTION OCCURED.");
}
return result;
public static void GeneratePdf(HttpServletResponse response, byte[] documentBytes,
String fileName) {
response.setHeader("Content-Disposition", "inline;filename=" + fileName + ".pdf");
response.setContentType("application/pdf");
response.setHeader("Expires", "0");
response.setHeader("Cache-Control", "must-revalidate, postcheck=0, pre-check=0");
response.setHeader("Pragma", "public");
response.setContentLength(documentBytes.length);
ServletOutputStream out = null;
try {
out = response.getOutputStream();
out.write(documentBytes);
out.flush();
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
try {
window.open("http://localhost:8080/INQ/CBU/5559901410151HELMPFN");
} catch (e) {
console.log(e);
}
答案 0 :(得分:0)
我不认为您可以使用window.open()
执行此操作。
我的建议是以下载PDF的方式使用servlet API,或者在出现错误的情况下向用户显示错误页面。
我有一些测试代码,用于确切地写出PDF或者错误页面被发送给用户,并显示错误消息。
线索是捕获异常,在这种情况下,使用不同的编码将错误消息发送给用户。
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/download")
public class PDFServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try {
String fileName = "asset_report1.pdf"; // Dummy file
// This throws sometimes an exception.
byte[] documentBytes = MyUtil.generatePdf(fileName);
response.setHeader("Content-Disposition", "inline;filename=" + fileName);
response.setContentType("application/pdf");
expireCache(response);
response.setHeader("Pragma", "public");
response.setContentLength(documentBytes.length);
ServletOutputStream out = response.getOutputStream();
out.write(documentBytes);
out.flush();
} catch (IOException e) {
expireCache(response);
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
"The PDF file could not be retrieved.");
}
}
private void expireCache(HttpServletResponse response) {
response.setHeader("Expires", "0");
response.setHeader("Cache-Control", "must-revalidate, postcheck=0, pre-check=0");
}
}
这很好用。要么下载PDF,要么得到错误页面。您将需要最终处理错误页面以使其看起来漂亮,但默认错误页面是一个开始。
有时您会看到PDF,如果出现错误,则会显示默认错误页面:
答案 1 :(得分:0)
在您的情况下,最好将pdf响应作为arraybuffer放置在有角度的一侧,并将其存储为blob,然后下载。您可以将其发布到服务器。并在您的角度代码中添加一个错误块。
服务器端代码。
List<PhysicalCountEntityTo> salaryList = exportNonDashBoardReportManager.fetchSalaryDetails(payloadBean);
HashMap<String, Object> parametersPDF = new HashMap<String, Object>();
JasperPrint jasperPrint = null;
JRBeanCollectionDataSource beanCollectionDataSource = null;
beanCollectionDataSource = new JRBeanCollectionDataSource(salaryList);
String reportPath = httpServletRequest.getServletContext().getRealPath("//WEB-INF//JasperReports//Salary.jasper");
jasperPrint = JasperFillManager.fillReport(reportPath, parametersPDF, beanCollectionDataSource);
httpServletResponse.addHeader("Content-disposition","attachment; filename=Salary.pdf");
ServletOutputStream servletOutputStream = httpServletResponse.getOutputStream();
JasperExportManager.exportReportToPdfStream(jasperPrint, servletOutputStream);
Angular Side Code-您可以在使用javascript时在ajax请求下使用此代码
exportPDF(event){
this.showPageSpinner=true;
this.httpRestClient.fetchPDF("download_salary_report", this.payloadBean).subscribe(
response => {
var blob = new Blob([response], {type: 'application/pdf'});
var ua = window.navigator.userAgent;
var msie = ua.indexOf('MSIE');
var trident = ua.indexOf('Trident/');
var edge = ua.indexOf('Edge/');
if(msie > 0 || trident > 0 || edge > 0){
window.navigator.msSaveOrOpenBlob(blob,'Salary.pdf');
}
else if(navigator.userAgent.toLowerCase().indexOf('firefox') > -1){
var link = document.createElement('a');
link.href = URL.createObjectURL(blob);
link.download = "Salary.pdf";
document.body.appendChild(link);
link.click();
window.setTimeout(function() {
URL.revokeObjectURL(link.href);
document.body.removeChild(link);
}, 0);
}
else{
var link=document.createElement('a');
link.href=window.URL.createObjectURL(blob);
link.download="Salary.pdf";
link.click();
}
this.showPageSpinner=false;
},
error=>{
// show your message here
});
}
重要-在请求标头中,将响应类型作为'json'添加到'arraybuffer'中,否则将不起作用
fetchPDF(url: string,data): Observable<any> {
this.getCredentials();
const authHeaders = this.createBasicAuthorizationHeader(this.credentials);
return this.http.post(this.getApiUrl(url),data,{headers: authHeaders,'responseType' : 'arraybuffer' as 'json'})
}
它可以在IE,Mozilla和Crome中使用。