Downloading a pdf with jquery using jax-rs - java

I'll try to download a pdf file using jquery and jax-rs. the pdf file will be created dynamically.
For testing purposes, I've just set a local pdf file. I need to parse some parameters for generating the pdf later. I'll post these params to the server and the server sends back a pdf file. Now what can I do on JS side to finally see the donwload-window?
Java-Side:
#Path("/chatexport/")
public class ChatExportController {
private static final String FILE_PATH = "c:\\own\\test.pdf";
#POST
#Path("/")
#Consumes(MediaType.APPLICATION_JSON)
#Produces("application/pdf")
public Response getFile(List<ChatMessage> chatMessageList) {
File file = new File(FILE_PATH);
ResponseBuilder response = Response.ok((Object) file);
response.header("Content-Disposition",
"attachment; filename=new-android-book.pdf");
return response.build();
}
Javascript-Side:
$.ajax({
type: "POST",
url: EXPORT_URL,
contentType: "application/json",
data: JSON.stringify([{authorId:"1",timestamp:123,content:"Test123"}]),
dataType: "application/pdf",
success: function (json, status) {
if (status != "success") {
console.log("Error loading data");
return;
}
console.log("Data loaded!");
},
error: function (result, status, err) {
console.log("Error loading data", err);
return;
}
});
The err Object in the error callback that is thrown says this:
No conversion from text to application/pdf

For a similar problem, I used this technique: Create an invisible iframe within the page when clicked on the download button (or when the download event is triggered), and set the source of the iframe as the PDF URL. You should also keep the Content-Disposition header for this technique. The file is automatically downloaded.

Related

How to pass csv file to sever path from ajax post to spring mvc controller?

I am trying to download csv file and wanted to upload that same csv file into my server location path using Spring MVC and through Ajax Post request on executing my application.
From the below code, I can able to download my csv file on running my application, but it is not uploading into my server location path at the same time or simultaneously on executing of the application, I am not sure why it is not uploading. Please help me to upload my file at my given path. Thanks !
js:
function download_csv(csv, filename) {
//filename = test.csv
//csv = "testname,testid
hello,10"
var csvFile;
var downloadLink;
// CSV FILE
csvFile = new Blob([csv], {type: "text/csv"}); //[object Blob]
// Download link
downloadLink = document.createElement("a");
// File name
downloadLink.download = filename;
var formData = new FormData(csvFile);
console.log(formData);//FormData {}
$.ajax({
url: "/uploadFile",
type: "POST",
//data: filename,
// data: new FormData(csvFile),
data: formData,
// enctype: 'multipart/form-data',
processData: false,
contentType: false,
cache: false,
success: function (data) {
// Handle upload success
$("#upload-file-message").text("File succesfully uploaded");
},
error: function (errordata) {
console.log("error: "+errordata);//[object Object]
console.log("error data: "+JSON.stringify(errordata));
}
});//$.ajax()
// We have to create a link to the file
downloadLink.href = window.URL.createObjectURL(csvFile);
// Make sure that the link is not displayed
downloadLink.style.display = "none";
// Add the link to your DOM
document.body.appendChild(downloadLink);
// Lanzamos
downloadLink.click();
}
controller:
#Controller
public class MainController {
#RequestMapping(value = "/uploadFile", method = RequestMethod.POST)
#ResponseBody
public ResponseEntity<?> uploadFile(
#RequestParam("filename") MultipartFile uploadfile) {
try {
// Get the filename and build the local file path
String filename = uploadfile.getOriginalFilename();
String directory = env.getProperty("paths.uploadedFiles");
String filepath = Paths.get(directory, filename).toString();
// Save the file locally
BufferedOutputStream stream =
new BufferedOutputStream(new FileOutputStream(new File(filepath)));
stream.write(uploadfile.getBytes());
stream.close();
}
catch (Exception e) {
System.out.println(e.getMessage());
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
}
return new ResponseEntity<>(HttpStatus.OK);
}
}
application.resources:
paths.uploadedFiles = /resources/test/
POST http://localhost:8000/uploadFile 400 (Bad Request)
error data: {"readyState":4,"responseText":"{\"timestamp\":1511523835282,\"status\":400,\"error\":\"Bad Request\",\"exception\":\"org.springframework.web.bind.MissingServletRequestParameterException\",\"message\":\"Required MultipartFile parameter 'filename' is not present\",\"path\":\"/uploadFile\"}","responseJSON":{"timestamp":1511523835282,"status":400,"error":"Bad Request","exception":"org.springframework.web.bind.MissingServletRequestParameterException","message":"Required MultipartFile parameter 'filename' is not present","path":"/uploadFile"},"status":400,"statusText":"Bad Request"}

Cannot upload file using Angular and Spring Boot

I'm trying to upload a file with AngularJS and Spring Boot controller. I have 2 problems:
1) When I use an HTML form 'submit' I get exceeded size even though I have set the max size of file to 128M. The code looks like this:
public class AppConfig {
#Bean
public MultipartConfigElement multipartConfigElement() {
factory.setMaxFileSize("128MB");
factory.setMaxRequestSize("128MB");
return factory.createMultipartConfig();
}
}
It seems that Spring ignores these settings.
2) When I'm trying to upload a file, I get the error:
org.springframework.web.multipart.MultipartException: The current request is not a multipart request
The Angular controller looks like this:
$scope.uploadFile=function(){
var formData=new FormData();
formData.append("file",file.files[0]);
$http.post('/content-files/upload /', file.files[0], {
transformRequest: function(data, headersGetterFunction) {
return data; // do nothing! FormData is very good!
},
headers: {'Content-Type': undefined }
})
.success(function(){
console.log('Post Succeded !');
})
.error(function(){
console.log('Post Failed .');
});
}
and the Spring controller looks like this:
#RequestMapping(value = "/content-files/upload/", method = RequestMethod.POST )
public #ResponseBody String handleFileUpload( #RequestParam("file") MultipartFile file) {
System.out.println("BrandController.uploadMultipart()");
String name=file.getName();
if (!file.isEmpty()) {
try {
byte[] bytes = file.getBytes();
BufferedOutputStream stream =
new BufferedOutputStream(new FileOutputStream(new File(name)));
stream.write(bytes);
stream.close();
return "You successfully uploaded " + name + "!";
} catch (Exception e) {
return "You failed to upload " + name + " => " + e.getMessage();
}
} else {
return "You failed to upload " + name + " because the file was empty.";
}
}
I tried changing the JS controller to:
$http.post('/content-files/upload /', file.files[0], {
headers: { 'Content-Type': undefined },
transformRequest: angular.identity
})
but I get the same error as above. When I try changing the JS controller to:
headers: { 'Content-Type': 'multipart/form-data' },
transformRequest: angular.identity
I get the error the request was rejected because no multipart boundary was found.
It seems that I have tried all combinations with the parameters, and still nothing worked. What do I need to do to get this file upload to work?
Try with this:
var formData = new FormData();
formData.append('file',file.files[0]);
$http.post('/content-files/upload /', formData, {
headers: { 'Content-Type': undefined },
transformRequest: angular.identity
})
Based on the MultipartAutoConfiguration code, the way to increase the size limit on uploads (by default max is 1 MB) with Spring Boot is the following properties:
multipart.maxFileSize=129Mb
multipart.maxRequestSize=129Mb
Regarding jquery multipart uploads, the way you are doing it does not appear correct, there are other good references that you can check for, I have seen plenty within Stackoverflow itself.

Retrieve pdf file stream from server

By following this link PLUNKER . I want to show pdf file in new window, but I want to read the pdf file from server
My service code
#RequestMapping(value = "/retrievePDFFile", method = RequestMethod.GET)
public #ResponseBody
InputStream retrievePDFFile() throws FileNotFoundException
{
InputStream inputStream = new FileInputStream("/resources/AngularJS 2013.pdf");
return inputStream;
}
My angular controller
$http({
method : "GET",
url : "/service/retrievePDFFile"
}).success(function(data) {
console.log(data);
}).error(function(data, status) {
console.log(data);
});
I got the pdf input stream from server like this..
How to read this, and open as a PDF file in new tab or window..
Thanks
After lot of searching I achieved the goal by little bit change in my controller code
$http.get('/retrievePDFFiles', {responseType: 'arraybuffer'})
.success(function (data) {
var file = new Blob([data], {type: 'application/pdf'});
var fileURL = URL.createObjectURL(file);
window.open(fileURL);
});

AJAX: Send file to Servlet and open response in new window

in my application, users can edit an ODF file via WebODF (http://webodf.org/). On save, i want to send the edited file to a servlet, have it convert to PDF via ODFDOM (http://code.google.com/p/xdocreport/wiki/ODFDOMConverterPDFViaIText) and open in a new window.
Currently i am trying to do this via AJAX. Everything works fine up to the point where i try to open the received PDF file.
My Javascript:
function showPDF(pServletUrl)
{
var successCallback = function(pData)
{
var mimetype = "application/vnd.oasis.opendocument.text";
var blob = new Blob([pData.buffer], {type: mimetype});
var formData = new FormData();
formData.append("file", blob, "test.odt");
jQuery.ajax({
type: "POST",
url: pServletUrl,
async: false,
data: formData,
processData: false,
contentType: false,
success: function(pSuccessData)
{
window.open(pSuccessData);
},
error: function(pErrorData)
{
console.log(pErrorData);
}
});
}
var errorCallback = function(data)
{
console.log(error);
}
_canvas.odfContainer().createByteArray(successCallback, errorCallback);
}
My servlet:
public void handleRequest(HttpServletRequest pRequest, HttpServletResponse pResponse) throws ServletException, IOException
{
BufferedInputStream tBufferedInput = null;
BufferedOutputStream tBufferedOutput = null;
try
{
List<FileItem> tItems = new ServletFileUpload(new DiskFileItemFactory()).parseRequest(pRequest);
for (FileItem tItem : tItems)
{
if (!tItem.isFormField())
{
String tFieldname = tItem.getFieldName();
String tFilename = FilenameUtils.getName(tItem.getName());
InputStream tFilecontent = tItem.getInputStream();
if("file".equals(tFieldname))
{
tBufferedInput = new BufferedInputStream(tFilecontent);
pResponse.reset();
pResponse.setHeader("Content-Type", "application/pdf");
pResponse.setHeader("Content-Disposition", "inline; filename=\"" + "test.pdf" + "\"");
tBufferedOutput = new BufferedOutputStream(pResponse.getOutputStream(), 10240);
this.getOdtAsPdf(tBufferedInput, tBufferedOutput);
tBufferedOutput.flush();
}
}
}
}
catch(Exception e)
{
e.printStackTrace();
}
finally
{
try
{
tBufferedInput.close();
tBufferedOutput.close();
}
catch(Exception e)
{
}
}
}
private void getOdtAsPdf(InputStream pInputStream, OutputStream pOutputStream) throws Exception
{
OdfDocument tOdfDocument = OdfDocument.loadDocument(pInputStream);
PdfOptions tPdfOptions = PdfOptions.create();
PdfConverter.getInstance().convert(tOdfDocument, pOutputStream, tPdfOptions);
}
It seems like Javascript wants to parse the recieved PDF file as a URL and (obviously) fails doing so. Is there a way to just open the file in a new window or do i have to find another way to do this?
You can't open the file using Ajax. This is a security restriction fo javascript. You have a few workarounds:
use a plugin which gives a Ajax type experience but opens a file in a new window.more details here
have a form which is submitted to a new window. <form target=_blank /> this will cause a new window to open thus not changing the contents of your current page.
Another option (not so neat) is to store the file in session and in the response of your AJAX, pass the id. Then using Javascript make a call using window.open('downloadurl?id') which will send the response of your PDF file.
You can make use an embed tag to display your blob after you make an ajax call.
Use createObjectUrl method to get url from blob and then display your pdf.

File Upload using ajax and jquery in spring

var urlUpload = "${root}manager/uploadFile.html";
var params = $('#topicForm').serialize();
$.ajax({
type: 'POST',
url: urlUpload,
data: params,
contentType: 'multipart/form-data',
processData: false,
success: function(data) {
alert("success");
}
});
#RequestMapping(value="/manager/uploadFile.html", method = RequestMethod.POST)
public String uploadFile(#ModelAttribute("topicForm") TopicForm topicForm,
#RequestParam("topicDoc") MultipartFile multipartFile ModelMap model) { ... }
I am getting the below exception
org.springframework.web.multipart.MultipartException: Could not parse
multipart servlet request; nested exception is
org.apache.commons.fileupload.FileUploadException: the request was
rejected because no multipart boundary was found.
The plugin is working fine thank you.
var urlUpload = "${root}manager/uploadFile.html?categoryId="+$("#category").val()+"&topicName="+$("#topicName").val();
$.ajaxFileUpload({
url:urlUpload,
secureuri:false,
fileElementId:'fileupload',
dataType: 'html',
success: function (data, status) {
alert("success");
}
});
The plugin is working fine, now i need to send few form fields to the controller along with the input file. in the above ajax call i appended the values to url. Is there any other solution for this?
The problem is that you're attempting to upload a URL-encoded serialization of the form, while claiming that it's multipart (see documentation of JQuery's serialize() function).
You need to use a plugin that will create the proper request. Here's one that I've used.
Alternatively, you can use HTML5 to upload files. I haven't done this.

Categories

Resources