JAXRS response with multiple file - javascript

I am able to send a single image file to ReactJS. But I have to send multiple image files to ReactJS.
JAXRS code:
#GET
#Path("/download/file1")
#Produces( MediaType.APPLICATION_OCTET_STREAM )
public Response getFile() {
String fileName = DOWNLOAD_FILE_SERVER+"BMI/testcases/Basispath_BMI_0_out.gif";
File file = new File( fileName);
System.out.println("fileName inside getFile = "+fileName);
final String filename = "testcase1.gif";
System.out.println("filename inside getFile = "+filename);
// Create the JAXRS response
// Don't forget to include the filename in 2 HTTP headers:
//
// a) The standard 'Content-Disposition' one, and
// b) The custom 'X-Suggested-Filename'
final Response.ResponseBuilder builder = Response.ok(
file, MediaType.APPLICATION_OCTET_STREAM)
.header("X-Actual-Content-Length", file.length())
.header("Content-Disposition", "attachment; filename=\"" + file.getName() + "\"");
// All Done.
return builder.build();
}
ReactJS code:
downloadImage = () => {
axios({
url: 'http://localhost:9900/EXAMPLE/rest/myresource/download/file1',
method: 'GET',
responseType: 'blob',
}).then((response) => {
const url = window.URL.createObjectURL(new Blob([response.data]));
const link = document.createElement('a');
link.href = url;
var filename = 'Image1.gif'
link.setAttribute('download', filename);
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
})
.catch((response) => { // then print response status
console.log("response = ",response);
})
}
Questions:
Is it possible to send multiple image files in the response of JAXRS?
How to receive multiple files in ReactJS GET response?
How to display received files in ReactJS?
Please provide solution to this issue.

Related

how to download a file from laravel [duplicate]

I'm using vuejs 2 + axios.
I need to send a get request, pass some params to server, and get a PDF as a response. Server uses Laravel.
So
axios.get(`order-results/${id}/export-pdf`, { params: { ... }})
makes successful request but it does not start force downloading, even though server returns correct headers.
I think this is a typical situation when you need to, say, form a PDF report and pass some filters to server. So how could it be accomplished?
Update
So actually I found a solution. However the same approach didn't work with axios, don't know why, that's why I used raw XHR object. So the solution is to create a blob object and user createUrlObject function. Sample example:
let xhr = new XMLHttpRequest()
xhr.open('POST', Vue.config.baseUrl + `order-results/${id}/export-pdf`, true)
xhr.setRequestHeader("Authorization", 'Bearer ' + this.token())
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded")
xhr.responseType = 'arraybuffer'
xhr.onload = function(e) {
if (this.status === 200) {
let blob = new Blob([this.response], { type:"application/pdf" })
let link = document.createElement('a')
link.href = window.URL.createObjectURL(blob)
link.download = 'Results.pdf'
link.click()
}
}
Important: you should have array buffer as response type
However, the same code written in axios returns PDF which is empty:
axios.post(`order-results/${id}/export-pdf`, {
data,
responseType: 'arraybuffer'
}).then((response) => {
console.log(response)
let blob = new Blob([response.data], { type: 'application/pdf' } ),
url = window.URL.createObjectURL(blob)
window.open(url); // Mostly the same, I was just experimenting with different approaches, tried link.click, iframe and other solutions
})
You're getting empty PDF 'cause no data is passed to the server. You can try passing data using data object like this
axios
.post(`order-results/${id}/export-pdf`, {
data: {
firstName: 'Fred'
},
responseType: 'arraybuffer'
})
.then(response => {
console.log(response)
let blob = new Blob([response.data], { type: 'application/pdf' }),
url = window.URL.createObjectURL(blob)
window.open(url) // Mostly the same, I was just experimenting with different approaches, tried link.click, iframe and other solutions
})
By the way I gotta thank you so much for showing me the hint in order to download pdf from response. Thank ya :)
var dates = {
fromDate: 20/5/2017,
toDate: 25/5/2017
}
The way in which I have used is,
axios({
method: 'post',
url: '/reports/interval-dates',
responseType: 'arraybuffer',
data: dates
}).then(function(response) {
let blob = new Blob([response.data], { type: 'application/pdf' })
let link = document.createElement('a')
link.href = window.URL.createObjectURL(blob)
link.download = 'Report.pdf'
link.click()
})
Try this:
It works perfectly for me with compatibility for Internet Explorer 11 (createObjectURL doesn't work on Explorer 11)
axios({
url: 'http://vvv.dev',
method: 'GET',
responseType: 'blob', // important
}).then((response) => {
if (!window.navigator.msSaveOrOpenBlob){
// BLOB NAVIGATOR
const url = window.URL.createObjectURL(new Blob([response.data]));
const link = document.createElement('a');
link.href = url;
link.setAttribute('download', 'download.pdf');
document.body.appendChild(link);
link.click();
}else{
// BLOB FOR EXPLORER 11
const url = window.navigator.msSaveOrOpenBlob(new Blob([response.data]),"download.pdf");
}
});
https://gist.github.com/javilobo8/097c30a233786be52070986d8cdb1743
I tried some of the above suggested approaches but in my case the browser was sending me the popup block warning.
The code described below worked for me:
axios.get(url, {responseType: 'arraybuffer'})
.then(function (response) {
var headers = response.headers();
var blob = new Blob([response.data],{type:headers['content-type']});
var link = document.createElement('a');
link.href = window.URL.createObjectURL(blob);
link.download = "Your_file_name";
link.click();
});
I don't think its possible to do this in axios or even AJAX. The file will be kept in memory, i.e. you cannot save file to disk. This is because JavaScript cannot interact with disk. That would be a serious security issue and it is blocked in all major browsers.
You can construct your URL in front-end and download it in the following way:
var url = 'http://example.com/order-results/' + id + '/export-pdf?' + '..params..'
window.open(url, '_blank');
Hope this helps!
this code works for me :
let xhr = new XMLHttpRequest()
xhr.open('POST', Vue.config.baseUrl + `order-results/${id}/export-pdf`, true)
xhr.setRequestHeader("Authorization", 'Bearer ' + this.token())
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded")
xhr.responseType = 'arraybuffer'
xhr.send()
xhr.onload = function(e) {
if (this.status === 200) {
let blob = new Blob([this.response], { type:"application/pdf" })
let link = document.createElement('a')
link.href = window.URL.createObjectURL(blob)
link.download = 'Results.pdf'
link.click()
}
}
I had similar issues- I ended up creating link and downloading from there.
I put more details of how in the answer on another stackoverflow question.

CSV file from server URL not downloading

I'm messing with a piece of code to download a CSV from server. this is what I'm trying:
downloadCSVTemp(){
let name = 'report.csv';
const response = api.getReportCSV()
.then((res)=>{
const blob = new Blob([res], { type: "data:text/csv;charset=utf-8," });
const blobURL = window.URL.createObjectURL(blob);
const anchor = document.createElement("a");
anchor.download = name;
anchor.href = blobURL;
anchor.dataset.downloadurl = ["text/csv", anchor.download, anchor.href].join(
":"
);
anchor.click();
});
}
getReportCSV(){
return axios.get("/export/assessments/");
}
I intend to download a csv file from server url by an axios call, But this code is downloading an csv file which can't be opend by the browser & full of garbage data. What's the problem here ?
The res argument contains Axios response object. When creating the blob, you should use res.data:
new Blob([res.data], { type: "data:text/csv;charset=utf-8," });

change file name in angular when download that by "Blob"

i want to download file from server in angular :
this code from service:
DownloadVerifyFile(requestId, fileId): any {
return this.httpClient
.get(this.appConfig.apiEndpoint + '/VerifyRequest/File/' + requestId + '/' + fileId,
{ responseType: 'blob' });
}
and this code for download that file in brwoser:
DownloadFile(fileId): void {
this.requestService.DownloadVerifyFile(this.id,fileId).subscribe(response => {
const a = document.createElement('a')
const objectUrl = URL.createObjectURL(response)
a.href = objectUrl
a.download = response;
a.click();
URL.revokeObjectURL(objectUrl);
});
}
but i have a problem with that , when i downlaod file , file name is this [object Blob] but i want to download by orginal name for example if file is file1.jpg , when downloaded file name must be fil1.jpg not [object Blob] . how can i solve this problem ???
Because you have named the file by response(It is an object). You were almost achieved. Just a little change as following:
a.download = response;
to
a.download = 'fil1.jpg';
Then you will get the correct file name.

How to trigger a browser download from a browser FETCH?

I'm working on a project with Vue.js and Typescript for front-end and Java Spring as backend.
My java controller retrieves a given report from the db and then copies it into the HTML response.
I want the CSV to be downloaded by the browser therefore I added Content-disposition header in the response.
#GetMapping('/download')
public void downloadCSV(HttpServletRequest response){
Report r = reportService.findById(85);
response.addHeader("Content-Disposition", "attachment; filename=myCSV.csv");
response.setContentType("text/csv");
try {
InputStream stream = new ByteArrayInputStream(r.getDocument());
IOUtils.copy(stream, response.getOutputStream());
response.flushBuffer();
} catch(Exception e) {...}
}
I have 2 buttons: one simple hyperlink tag with href linking to download(), and a b-button (from bootstrap-vue) that once cliccked triggers download2().
<a :href="download" role="button"> Download CSV </a>
<b-button #click="event => download2()">
Download CSV v2
</b-button>
get download(): string {
return 'http://localhost:8080/download';
}
async download2() {
const rHeaders = new Headers();
rHeaders.append('Accept', 'text/csv');
const configInit = RequestInit = {
method: 'GET',
headers: rHeaders
};
try {
const res = await fetch('http://localhost:8080/download', configInit);
return res.text();
} catch (e) {...}
}
Now, If I click on the first button "Download csv", the csv is correctly downloaded by the browser. The javascript console prints the following:
Resource interpreted as Document but transferred with MIME type text/csv
and there is nothing in the response body.
Instead, if I click the 2nd button "Download csv v2", the download does not start but I have the csv in the response body.
Here, the differences in the request headers between the two.
*Header* *Download csv* *Download csv v2*
Sec-Fetch-Dest document empty
Sec-Fetch-Mode navigate cors
Sec-Fetch-User ?1 -
Upgrade-Insecure-Requests 1 -
the other headers are the same. It is not possible to change these headers, even if I set them in the javascript method; they remain still the same.
What's the problem?
Thank you.
I found a solution by "mimicking" the behavior of a <a> element:
This way, it works properly:
async download2() {
const configInit: RequestInit = {
method: 'GET'
};
try {
await fetch('http://localhost:8080/download', configInit)
.then(response => response.blob())
.then(blob => {
const url = window.URL.createObjectURL(blob);
const a = document.createElement('a');
a.style.display = 'none';
a.href = url;
a.download = 'report.csv';
document.body.appendChild(a);
a.click();
window.URL.revokeObjectURL(url);
})
} catch (e) {...}

Typescript download PDF file have empty contant

I have a script to download different type files from server side. The code works for text/xml but when the downloaded pdf file is empty.
let response = this.http.get(this.Url , new Headers({responseType: 'blob'}))
.subscribe(doc => {
if (doc) {
let contentType = doc.headers.get("Content-Type");
let name = doc.headers.get("Content-Disposition").split("=")[1];
let blob = new Blob([doc.text()], {type: contentType});
let a = window.document.createElement("a");
a.href = window.URL.createObjectURL(blob);
a.download = name;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
}
},
error => this.msgService.showError(this.msgs, error));
My server
#GET
#Consumes(MediaType.APPLICATION_JSON)
#Path("-----")
public Response getDocument(#PathParam("documentId") Long documentId) throws Exception {
Document document = ---------------;
return ResponseHelper.createOkResponse(
output -> IOUtils.write(document.documentContent(), output),
document.documentName(),
document.documentType()
);
}
I can see the doc.text() is returning some byte[]. Also tried {responseType: 'arraybuffer'}. can anyone advise how can i display for pdf ?
Thanks

Categories