使用Javascript从Window.open中的控制器捕获异常

时间:2017-10-05 07:37:25

标签: javascript java ajax

我有一个控制器,用于刷新字节,这将在客户端生成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;

生成pdf方法

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();
    }
}

Javascript代码

try {
    window.open("http://localhost:8080/INQ/CBU/5559901410151HELMPFN");

} catch (e) {
    console.log(e);
}

2 个答案:

答案 0 :(得分:0)

我不认为您可以使用window.open()执行此操作。

我的建议是以下载PDF的方式使用servlet API,或者在出现错误的情况下向用户显示错误页面。

我有一些测试代码,用于确切地写出PDF或者错误页面被发送给用户,并显示错误消息。

线索是捕获异常,在这种情况下,使用不同的编码将错误消息发送给用户。

servlet代码

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,如果出现错误,则会显示默认错误页面:

enter image description here

答案 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中使用。