How to download a file using XMLHttpRequest - java

I am posting html content to the serverside and converting it to PDF and streaming the file back.
But am not able to download the file using:
var formData = new FormData();
formData.append("htmlContent", strHTML);
var request = new XMLHttpRequest();
request.open("POST", "RenderHtmlAsPDF.jsp");
request.send(formData);
Download works when I create a dynamic form and post the html content targeting it to an iframe. But I am limited by the amount of data I can send.

You can't download a file with AJAX. However you can "simulate" the behaviour by doing the folowing: make the ajax post request for file generation, after the file was generated on the server, generate a token or id with witch you can identify the file, send it back to the client and when you have received the response token on the client simply generate an iframe with the src pointing to a method on your back-end which receives the token and sends back the file.

Related

Getting a PDF from another API

How can I get a PDF from another API through my own API then to the front for downloading by the user.
All I get now is a blank page.
The back is in Scala and when I println the file, I get it in a String.
In the front, I get the blob and use that function to download it :
onDownload(invoice) {
var mediaType = 'application/pdf';
this.invoices.downloadInvoice(invoice.id).subscribe((file: Blob) => {
const fileName = invoice.number;
var blob = new Blob([file], { type: mediaType });
const fileUrl = URL.createObjectURL(blob);
FileSaver.default(fileUrl, fileName.toString());
}), err => {
console.error(err);
}
}
The back is using Play and the WebService to get the file from another API but I can only receive it as a string it seems. Should I try to store him on the server then serve it to the front ?
Which scala-server used? And what does the path/API return?
Should I try to store him on the server then serve it to the front
This is the sure-shot way of making it work. For eg: If using akka-server, save the incoming file in some temporary location (say /tmp), and use akka-route getFromFile to server the file to front-end. Every server will have an equivalent of this.
If we want to bypass file-saving, we need to trick/hack the client into thinking that the incoming string is actually a file. I am not sure if your server will allow this, but you can try by passing the same http-headers. For this, create a simple API to send some PDF, check all the headers received on the client side, and then make sure your hacky way sends the same http-headers.

How to send file via Ajax call to Servlet

I have an HTML form in AEM where I have to attach the files and the same files will be sent to one Rest API via Java Servlet.
I am calling the Java Servlet via Ajax and able to send other String data to Java Servlet but not able to send the file Array which contains the files attached to the HTML Form attachment option while submitting the Form. How can I get the file in Java servlet?
In JS
var myFile [] is what I am sending in a ajax call.
$.ajax({
url: /servletUrl,
type: 'post',
data: {
'myFile': myFile,
},
success: function(response){
}
});
In Java :
Enum paramObject = request.getparameter();
When I put the object in HashMap and try to get the file, its type is coming as String not Object.
I am not sure where I am setting it as String.
The servlet has to be able to process Multipart-Messages.
I do not know AEM, but in Jakarta / Java Enterprise Edition / JEE / J2EE:
you have to specifically add the #Multipart annotation to the servlet.
Now, open your browser, press F12 to go into debug details, and when you trigger the request, the Network tab will display alle the infos that are posted. Look up the name of the parameter, usually it's calles file[]
When handling the request in the servlet, you can use the HttpServletRequest's request.getParts() method to find all parameter parts.
With final Part filePart = request.getPart(pFileParamName); and final InputStream filecontent = filePart.getInputStream(); you will be able to access the data.
And this will probably be very similar in most servlet frameworks.

RESTEasy client multipart post file

I'm trying to send a file with resteasy client to an http server with some code like this:
File source = new File("test.pdf");
Client client = ClientBuilder.newClient();
MultipartFormDataOutput upload = new MultipartFormDataOutput();
upload.addFormData("source", source, MediaType.APPLICATION_OCTET_STREAM_TYPE);
Entity entity = Entity.entity(upload, MediaType.MULTIPART_FORM_DATA_TYPE)
Response response = client.target(url).request().post(entity);
What happens is that on the http server I'm not getting the usual "file" in request (with the content, the name etc..), but something like a regular POST parameter named "source" with the file content as its value.
I tried it with some different web servers, so the issue have to be in the request that RESTeasy builds.
Any help?
MultipartFormDataOutput behaves the same away as a HTML form would do. It sends key/value pairs to the server.
If you want to upload a MIME message consider using MultipartOutput.

How to stream S3 object directly from Java web server to browser

What I have tried so far is
S3Object object = s3Object.getObject(new getObjectRequest(bucketName,FileName));
InputStreamResource inputStreamResource = object.getObjectContent();
// Setting Headers.
return new ResponseEntity(inputStreamResource,headers, HttpStatus.OK);
But this code is not streaming date to browser. I has first downloaded to server and then sent back to browser but requirement is to directly stream to browser without downloading at server.
Any pseudocode or link will help.
Thanks
Instead of calling getObject(), create a signed GET request and send a 302 redirect to the client. The browser will then retrieve the object directly from Amazon. In case you aren't already using it, the jets3t library makes dealing with S3 signatures much simpler.

Jersey servlet returns zip file that contains more bytes than response sent

I'm trying to implement a simple servlet that returns a zip file that is bundled inside the application (simple resource)
So I've implemented the following method in the server side:
#GET
#Path("{path}/{zipfile}")
#Produces("application/zip")
public Response getZipFile(
#PathParam("path") String pathFolder,
#PathParam("zipfile") String zipFile) IOException {
String fullPath= String.format("/WEB-INF/repository/%s/%s",
pathFolder, zipFile);
String realPath = ServletContextHolder.INSTANCE.getServletContext()
.getRealPath(fullPath);
File file = new File(realPath );
ResponseBuilder response = Response.ok((Object) file);
return response.build();
}
When I call this method from the borwser, the zip file is downloaded and its size is the same number of bytes as the original zip in the server.
However, when I call this using a simple XMLHttpRequest from my client side code:
var oXHR = new XMLHttpRequest();
var sUrl = "http://localhost:8080/path/file.zip"
oXHR.open('GET', sUrl);
oXHR.responseType = 'application/zip';
oXHR.send();
I can see in the Network tab of the Developer tools in chrome that the content size is bigger, and I'm unable to process this zip file (for instance JSzip doesn't recognize it).
It seems like somewhere between my response and the final response from org.glassfish.jersey.servlet.ServletContainer, some extra bytes are written/ some encoding is done on the file.
Can you please assist?
Best Regards,
Maxim
When you use an ajax request, the browser expects text (by default) and will try to decode it from UTF-8 (corrupting your data).
Try with oXHR.responseType = "arraybuffer"; : that way, the browser won't change the data and give you the raw content (which will be in oXHR.response).
This solution won't work in IE 6-9 : if you need to support it, check JSZip documentation : http://stuk.github.io/jszip/documentation/howto/read_zip.html
If it's not the right solution, try downloading directly the zip file (without any js code involved) to check if the issue comes from the js side or from the java side.

Categories