Ajax call to download pdf file in jsp - java

I've tried to open itext created pdf file using jsp code but not opening valid pdf file.
BTW if I'll open pdf in generated path then it is valid generated pdf.
<%
//code to generate pdf on file location.
String pdfurl = filePDF.getAbsolutePath();
File pdf = null;
try {
System.out.println("pdfurl : " + pdfurl);
response.setCharacterEncoding("utf-8");
pdf = new File(pdfurl);
response.setContentType("application/pdf");
response.setHeader("Expires", "0");
response.setHeader("Cache-Control", "must-revalidate, post-check=0, pre-check=0");
response.setHeader("Content-Disposition", "inline;filename=checklist.pdf");
response.setHeader("Accept-Ranges", "bytes");
response.setContentLength((int) pdf.length());
OutputStream sos = response.getOutputStream();
FileInputStream input = new FileInputStream(pdf);
BufferedInputStream buf = new BufferedInputStream(input);
int readBytes = 0;
while ((readBytes = buf.read()) != -1) {
sos.write(readBytes);
}
System.out.println("Finished writing bytes to output stream.");
sos.flush();
sos.close();
input.close();
} catch (Exception ex) {
ex.printStackTrace();
} finally {
if (null != pdf && pdf.exists() && !pdf.isDirectory()) {
try {
pdf.delete();
System.out.println("Deleted file from " + pdfurl + " successfully");
} catch (Exception ex) {
System.out.println("Error while deleting pdf from : " + pdfurl);
}
}
}
%>
And angularJS code for ajax call:
pfqa.createDocument = function(action,data){
$("body").addClass("loading");
var deferred = $q.defer();
var paramJsonObj= {
'userId' : userId,
};
var data = angular.copy(paramJsonObj);
data = angular.toJson(data);
$http({
url : 'services/downloadPDF.jsp',
dataType: 'json',
method : 'POST',
headers : {
'Content-type' : 'application/json',
},
data: {data: paramJsonObj},
responseType : 'arraybuffer'
}).success(function(data, status, headers, config) {
var file = new Blob([ data ], {
type : 'application/json'
});
var fileURL = URL.createObjectURL(file);
var a = document.createElement('a');
a.href = fileURL;
a.target = '_blank';
a.download = 'checklist.pdf';
document.body.appendChild(a);
a.click();
}).error(function(data, status, headers, config) {
});
$("body").removeClass("loading");
}
Please guide me what I'm missing here.

What you are missing here is :
Use : application/pdf instead of application/json
$http({
url : 'services/downloadPDF.jsp',
dataType: 'json',
method : 'POST',
headers : {
'Content-type' : 'application/pdf',
},
data: {data: paramJsonObj},
responseType : 'arraybuffer'
}).success(function(data, status, headers, config) {
var file = new Blob([ data ], {
type : 'application/pdf'
});
var fileURL = URL.createObjectURL(file);
var a = document.createElement('a');
a.href = fileURL;
a.target = '_blank';
a.download = 'checklist.pdf';
document.body.appendChild(a);
a.click();
}).error(function(err) {
console.log(err);
});
That's it !!!

Related

Current request is not of type MultipartHttpServletRequest

I'm trying to send an image + object from Angular to Spring Boot but everytime I try I get this error:
Current request is not of type [org.springframework.web.multipart.MultipartHttpServletRequest]
This is my Angular code:
addPostWithIMG(image: File, postRequest: PostRequest): Subscription {
const headers = new HttpHeaders();
headers.append('Content-Type', ' multipart/form-data content');
var file: FormData = new FormData();
file.append('file', image);
file.append('postRequest', JSON.stringify(postRequest));
console.log(file)
return this.http.post<PostRequest>(`${this.baseUrl + "multi"}`, file, {headers: headers}).subscribe({
next: (data: any) => {
console.log(data)
},
error: (err: any) => {
console.error(err)
},
complete: () => {
console.log("Done")
}
});
}
This my Spring Boot side:
#PostMapping(path = "multi")
public String multi(MultipartHttpServletRequest request) throws IOException {
String postJSON = request.getParameter("postRequest");
PostRequest = new Gson().fromJson(post, PostRequest.class);
MultipartFile file = request.getFile("file");
Binary files = new Binary(file.getBytes());
File fileToSave = new File("Post/src/main/resources/" + postRequest.getPostId() + ".png");
log.info("file: {}", fileToSave.getAbsolutePath());
if (!fileToSave.exists()) {
log.info("file created: {}", fileToSave);
fileToSave.createNewFile();
} else {
log.info("file already exist: {}", fileToSave);
}
// Try-with-resource
try (OutputStream out = new FileOutputStream(fileToSave.getAbsolutePath())) {
out.write(files.getData());
out.flush();
} catch (IOException e) {
e.printStackTrace();
}
return "Image saved";
}
Can Anyone help me to find the reason of thi exception
Thank you very much
Try to don't add:
headers.append('Content-Type', ' multipart/form-data content');
The web will automatically set for you

Return pdf from controller and display on front end in spring

I have pdf saved in blob format in my database. It's coming empty on front end.
Here is my controller call:
#RequestMapping(value = "/viewDocument", method = RequestMethod.GET, produces=MediaType.APPLICATION_PDF_VALUE)
public ResponseEntity<InputStreamResource> viewDocument()
{
HttpHeaders headers = new HttpHeaders();
ByteArrayInputStream bis = null;
try{
File uFile = null;
uFile = maintainFileService.getDocument(123456L);
bis = new ByteArrayInputStream(uFile.getFile());
headers.add("Content-Disposition", "inline; filename=pdf.pdf");
}
catch(Exception e){
logger.error("Exception while viewing the pdf.");
}
return ResponseEntity
.ok()
.headers(headers)
.contentType(MediaType.APPLICATION_PDF)
.body(new InputStreamResource(bis));
}
And here is my ajax call:
$.ajax({
type : "GET",
url: "/esubmission/recorder/search/viewDocument" ,
timeout : 100000,
success : function(result) {
window.open(result);
},
error : function(e) {
console.log("ERROR: ", e);
},
done : function(e) {
console.log("DONE");
}
});
I think I am missing something but just couldn't figure it out. TIA

BLOB to PDF download using Java and angular 5

I am trying to implement logic of download pdf from db on angular 5. I am facing issue in download file. File gets downloaded but throws error on opening -"Failed to load".
I have looked at so many blogs and question/answers but not able to find the mistake in my code.
In Database -> pdf file content saved as BLOB
Rest web service ->
In below code pdfData is the data from BLOB type column, which is byte[] in java code here
#GetMapping("downloadReport/{reportId}")
public StreamingResponseBody downloadDocument(byte[] pdfData) {
return outputStream -> {
//This way working for sample
/*try (InputStream inputStream = new ByteArrayInputStream(
Files.readAllBytes(Paths.get("D:/pdfWithoutPassword.pdf")))) {
IOUtils.copy(inputStream, outputStream);
}*/
//This way not working when data fetched from Database
try (InputStream inputStream = new ByteArrayInputStream(pdfData)) {
IOUtils.copy(inputStream, outputStream);
}
outputStream.close();
};
Angular 5 code
downloadReport(reportType: string, reportId: string) {
let fileDownloadUrl = environment.apiUrl + "/downloadReport" + "/" + reportId;
return this.httpClient
.get(fileDownloadUrl, { observe: 'response', responseType: "blob"})
.subscribe(response => this.saveFileToSystem(response.body)),
error => console.log("Error downloading the file."),
() => console.info("OK");
}
saveFileToSystem(input: any) {
const blob = new Blob([input], { type: 'application/octet-stream' });
saveAs(blob, "testingpdf1.pdf");
}
Looking for help in solving this. Thanks in advance!
Here another way I did it you you can change :
#RequestMapping(value = "/generateReport", method = RequestMethod.POST)
public ResponseEntity<byte[]> generateReport(){
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.parseMediaType("application/pdf"));
StringBuilder filename = new StringBuilder("MyPdfName").append(".pdf");
byte[] bytes = pdfGeneratorService.generatePDF();
headers.add("content-disposition", "inline;filename=" + filename.toString());
headers.setCacheControl("must-revalidate, post-check=0, pre-check=0");
ResponseEntity<byte[]> response = new ResponseEntity<byte[]>(bytes, headers, HttpStatus.OK);
return response;
}
Try this :
From your html page
YourPdf.pdf
From your js file
generatePdf() {
this.yourService.generatePdf()
.subscribe(pdf => {
let mediaType = 'application/pdf';
let blob = new
Blob([this.converterService.base64ToArrayBuffer(pdf.pdfByteArray)], { type: mediaType });
saveAs(blob, fileName);
}, err => {
console.log('Pdf generated err: ', JSON.stringify(err));
});
}
Your converter service:
import { Injectable } from "#angular/core";
#Injectable()
export class ConverterService {
base64ToArrayBuffer(base64) {
var binaryString = window.atob(base64);
var binaryLen = binaryString.length;
var bytes = new Uint8Array(binaryLen);
for (var i = 0; i < binaryLen; i++) {
var ascii = binaryString.charCodeAt(i);
bytes[i] = ascii;
}
return bytes;
}
}

Angularjs/Java - Get image from rest service method

My java web application has a rest service method and return a inputstream image.
#GET
#Path("/image/{id}")
#Produces("image/png")
public Response buscarFoto(#PathParam("id") Long id,
#Context HttpHeaders header,
#Context HttpServletResponse response) {
byte[] bytes = null;
bytes = yakifreeService.getImageStream(id);
ByteArrayInputStream in = new ByteArrayInputStream(bytes);
response.setContentType("images/png");
response.setHeader("Content-Type", "image/png");
response.setHeader("Content-Disposition", "inline; filename=\"" + "image.png" + "\"");
try {
OutputStream out = response.getOutputStream();
IOUtils.copy(in, out);
IOUtils.closeQuietly(in);
IOUtils.closeQuietly(out);
} catch (IOException ex) {
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(ex.getMessage()).type(MediaType.TEXT_HTML).build();
}
return Response.ok().build();
}
The Angularjs client gets the inputstream image as following
Image.getImage({ id: $scope.model.image.id }).$promise.then(function (result){
if (result) {
$scope.model.image.dataURL = 'data:image/png;base64,' + result;
}
});
function(yakifree) {
return yakifree.factory("Image", ["$resource", "$rootScope",
function($resource, $rootScope) {
var Image = $resource($rootScope.contextApp + '/rest/image/:id', { }, {
getImage: { method:'GET', params: {}, isArray: false }
});
return Image;
}]);
});
And HTML shows
<img data-ng-src="{{model.image.dataURL}}" width="120" height="120">
The problem is the HTML does not show image. The result variable in javasript has the value:
Resource {0: "�", 1: "P", 2: "N", 3: "G", 4: "
", 5: "↵", 6: "", 7: "↵", 8: "
Can someone help me ? Thanks!
For me, the next approach works correctly
$resource(endpoint + 'images/:id', null, {
getImage: {
method: 'GET',
responseType: 'arraybuffer',
transformResponse: function(data) { return { data : data }}
}
})
...
const response = await resource.getImage({id}).$promise;
const binary = btoa(String.fromCharCode.apply(null, new Uint8Array(response.data)));
const img = 'data:image/png;base64,'+ binary;
...
<img src={img}/>

Files not getting Downloaded in Spring

There is a page where i have files list. On cliking on any of the .txt it must get downloaded and a notification should be displayed as the notification we get in download anything on GoogleChrome.
This is my Js which is called after cliking on .txt files
Here i am doing is, i am getting the filename and the filepath of the selected file. And then using ajax sending those filename and filepath to the spring servlet.
if (options.downloadable) {
$(easyTree).find('.easy-tree-toolbar').append('<div class="fileDownload"><button class="btn btn-default btn-sm btn-primary"><span class="glyphicon glyphicon-circle-arrow-down"></span></button></div>');
$(easyTree).find('.easy-tree-toolbar .fileDownload > button').attr('title', options.i18n.downloadTip).click(function() {
var selected = getSelectedItems();
var fileName = $(selected).find(' > span > a').text();
alert("fileName**" + fileName);
var hrefValue = $(selected).find(' > span > a').attr('href');
alert("hrefValue**" + hrefValue);
if (selected.length <= 0) {
$(easyTree).prepend(warningAlert);
$(easyTree).find('.alert .alert-content').html(options.i18n.downloadNull);
} else {
$.ajax({
url: "/ComplianceApplication/downloadFileFromDirectory",
type: "GET",
data: {
hrefValue: hrefValue,
fileName: fileName
},
success: function(data) {
//$(selected).remove();
//window.location.reload();
},
error: function(e) {
}
});
}
});
}
This is my springController. Here I am getting all the data properly but the problem is file is not getting downloaded and am not even getting any error so that I can come to know what mistake I am doing.
#RequestMapping(value="/downloadFileFromDirectory",method = RequestMethod.GET)
public #ResponseBody void downloadFileFromDirectory(#PathVariable("fileName") String fileName,#RequestParam(value = "hrefValue") String hrefValue,HttpServletRequest request, HttpServletResponse response,Model model){
System.out.println("hrefValue***"+hrefValue);
String filePath = hrefValue;
ServletContext context = request.getSession().getServletContext();
File downloadFile = new File(filePath);
FileInputStream inputStream = null;
OutputStream outStream = null;
try {
inputStream = new FileInputStream(downloadFile);
response.setContentLength((int) downloadFile.length());
response.setContentType(context.getMimeType(downloadFile.getName()));
// response header
String headerKey = "Content-Disposition";
String headerValue = String.format("attachment; filename=\"%s\"", downloadFile.getName());
//String headerValue = String.format("attachment; filename=\"%s\"", downloadFile.getName());
response.setHeader(headerKey, headerValue);
// Write response
outStream = response.getOutputStream();
IOUtils.copy(inputStream, outStream);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (null != inputStream)
inputStream.close();
if (null != outStream)
outStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Any suggestions ???
I usually use this kind of code with no problem:
public ResponseEntity<InputStreamResource> downloadFile(#PathVariable("idForm") String idForm)
{
try
{
File parent = new File(csvFilesPath);
File file = new File(parent, idForm+".csv");
HttpHeaders respHeaders = new HttpHeaders();
MediaType mediaType = new MediaType("text","csv");
respHeaders.setContentType(mediaType);
respHeaders.setContentLength(file.length());
respHeaders.setContentDispositionFormData("attachment", "file.csv");
InputStreamResource isr = new InputStreamResource(new FileInputStream(file));
return new ResponseEntity<InputStreamResource>(isr, respHeaders, HttpStatus.OK);
}
catch (Exception e)
{
String message = "Errore nel download del file "+idForm+".csv; "+e.getMessage();
logger.error(message, e);
return new ResponseEntity<InputStreamResource>(HttpStatus.INTERNAL_SERVER_ERROR);
}
}
The problem it's in you ajax code, so you can use JQuery File Download.
It's as simple as
$.fileDownload('/url/to/download.pdf');
Here you can see a tutorial
http://johnculviner.com/jquery-file-download-plugin-for-ajax-like-feature-rich-file-downloads/

Categories

Resources