admin管理员组文章数量:1405114
I have a spring boot API that creates a pdf report and download it, if I call the API directly in the browser, the pdf is created and downloaded directly, but when I call that GET API from Angular 6 I get the following error:
The Spring boot (java) code:
@RequestMapping(value = "/app_report/en", method = RequestMethod.GET)
@ResponseBody
public void getEnRpt(HttpServletResponse response, @RequestParam("appNum") String appNum) throws JRException, IOException, SQLException {
JasperReport jasperReport = JasperCompileManagerpileReport("./src/main/resources/jasperReports/App_created_en.jrxml");
Connection connection = dataSource.getConnection();
Map<String, Object> params = new HashMap<>();
params.put("P_APP_NO", appNum);
JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, params, connection);
response.setContentType("application/x-pdf");
response.setHeader("Content-disposition", "inline; filename=App_report_en.pdf");
final OutputStream outStream = response.getOutputStream();
JasperExportManager.exportReportToPdfStream(jasperPrint, outStream);
}
The Angular code that calls the API:( I tried multiple ways, two are shown here):
this.http.get(this.api_url + reportUrl, {
responseType: 'blob'
}, ).subscribe((response: File) => {
console.log('report is downloaded');
});
this.http.get(this.api_url + reportUrl).subscribe(
(response) => {
console.log('report is downloaded');
});
The console error that I get after the Angular calls the API:
error:
SyntaxError: Unexpected token % in JSON at position 0 at JSON.parse (<anonymous>) at XMLHttpRequest.onLoad
message: "Http failure during parsing for https://localhost:7001/reports/app_report/en?appNum=xxxxxxx"
name: "HttpErrorResponse"
ok: false
status: 200
statusText: "OK"
url: "https://localhost:7001/reports/app_report/en?appNum=xxxxxx"
I only need to call the API like the call that happens in the browser so that the pdf is downloaded right away
The response headers are as follows:
Content-disposition
inline; filename=App_report_en.pdf
Content-Type
application/x-pdf
Why Angular is not downloading the file like what happens in the browser if I call that API? (especially since the request is successful)
I have a spring boot API that creates a pdf report and download it, if I call the API directly in the browser, the pdf is created and downloaded directly, but when I call that GET API from Angular 6 I get the following error:
The Spring boot (java) code:
@RequestMapping(value = "/app_report/en", method = RequestMethod.GET)
@ResponseBody
public void getEnRpt(HttpServletResponse response, @RequestParam("appNum") String appNum) throws JRException, IOException, SQLException {
JasperReport jasperReport = JasperCompileManager.pileReport("./src/main/resources/jasperReports/App_created_en.jrxml");
Connection connection = dataSource.getConnection();
Map<String, Object> params = new HashMap<>();
params.put("P_APP_NO", appNum);
JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, params, connection);
response.setContentType("application/x-pdf");
response.setHeader("Content-disposition", "inline; filename=App_report_en.pdf");
final OutputStream outStream = response.getOutputStream();
JasperExportManager.exportReportToPdfStream(jasperPrint, outStream);
}
The Angular code that calls the API:( I tried multiple ways, two are shown here):
this.http.get(this.api_url + reportUrl, {
responseType: 'blob'
}, ).subscribe((response: File) => {
console.log('report is downloaded');
});
this.http.get(this.api_url + reportUrl).subscribe(
(response) => {
console.log('report is downloaded');
});
The console error that I get after the Angular calls the API:
error:
SyntaxError: Unexpected token % in JSON at position 0 at JSON.parse (<anonymous>) at XMLHttpRequest.onLoad
message: "Http failure during parsing for https://localhost:7001/reports/app_report/en?appNum=xxxxxxx"
name: "HttpErrorResponse"
ok: false
status: 200
statusText: "OK"
url: "https://localhost:7001/reports/app_report/en?appNum=xxxxxx"
I only need to call the API like the call that happens in the browser so that the pdf is downloaded right away
The response headers are as follows:
Content-disposition
inline; filename=App_report_en.pdf
Content-Type
application/x-pdf
Why Angular is not downloading the file like what happens in the browser if I call that API? (especially since the request is successful)
Share Improve this question edited Aug 1, 2018 at 12:10 Ahmed Elkoussy asked Jul 31, 2018 at 9:26 Ahmed ElkoussyAhmed Elkoussy 8,59812 gold badges67 silver badges92 bronze badges 3-
It's missing your angular code. Most likely, you need to change
responseType
to 'blob' in the request's options – David Commented Jul 31, 2018 at 9:49 - sorry I forgot to put the angular code, basically I am calling the api with the httpClient.get method and subscribe to it logging the response, I tried using the type as blob but I got no errors without saving the file, I will add the code asap but I can't now – Ahmed Elkoussy Commented Jul 31, 2018 at 12:09
- @David I have added the Angular code, unfortunately even having the responseType as 'blob' didn't help, it only helped avoid the json parsing error but the file was not downloaded, note that calling the api in browser can download automatically the file – Ahmed Elkoussy Commented Aug 1, 2018 at 12:40
2 Answers
Reset to default 8To avoid the JSON parsing issue, you need to tell the http client that the response will be a blob, using responseType: 'blob'
in requests options.
Then, to actually have the navigator open the file, you can follow the instructions from this blog
const fileName = "report.pdf";
this.http.get(this.api_url + reportUrl, { responseType: 'blob'})
.subscribe((blob: Blob) => {
console.log('report is downloaded');
if (navigator.msSaveBlob)
{
// IE 10+
navigator.msSaveBlob(blob, filename);
}
else
{
let link = document.createElement("a");
if (link.download !== undefined)
{
let url = URL.createObjectURL(blob);
link.setAttribute("href", url);
link.setAttribute("download", fileName);
link.style.visibility = 'hidden';
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
}
else
{
//html5 download not supported
}
}
});
This should work for IE 10+ and other modern browsers, apart from iOs (see CanIuse)
Spring Boot + Jaspersoft + Angular
In ponent.ts
reportGenerate() {
this.reportService.generateReport(this.form.value).subscribe(response => {
let url = window.URL.createObjectURL(response.data);
let a = document.createElement('a');
document.body.appendChild(a);
a.setAttribute('style', 'display: none');
a.setAttribute('target', 'blank');
a.href = url;
a.download = response.filename;
a.click();
window.URL.revokeObjectURL(url);
a.remove();
}, error => {
console.log(error);
});
}
In service.ts
public generateReport(data: Data) {
return this.httpService.getReport(url, data)
.pipe(map((response) => {
return {
filename: 'report.pdf',
data: new Blob([response], { type: 'application/pdf' })
};
}));
}
call rest api
getReport(url: any, data: any): Observable<any> {
const headers = new HttpHeaders({
'Authorization': 'Bearer ' + this.tokenStoreService.getToken()
})
return this.http.post(this.URL + url, data, { headers, responseType: 'arraybuffer' as 'json'});
}
Spring Boot
public JasperReport getJasperReport(String reportJrxml) throws Exception {
Resource resource = new ClassPathResource(reportJrxml);
InputStream inputStream = resource.getInputStream();
JasperDesign jasperDesign = JRXmlLoader.load(inputStream);
return JasperCompileManager.pileReport(jasperDesign);
}
本文标签:
版权声明:本文标题:javascript - Calling Spring boot api that downloads a pdf from Angular 6 is giving error can't parse response - Stack Ov 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744292309a2599173.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论