I'm using the following solution to try and receive an image in a restful webservice written in java:
#POST
#Consumes(MediaType.MULTIPART_FORM_DATA)
#Produces(MediaType.TEXT_PLAIN)
public String getFile(#FormDataParam("pic") InputStream file,
#QueryParam("uid") String uid) {
try {
storeFile(file, uid);
} catch (IOException ex) {
Logger.getLogger(UploadImage.class.getName()).log(Level.SEVERE, null, ex);
return "failed";
}
return "success";
}
private void storeFile(InputStream input, String uid) throws IOException {
String absPath = PATH_TO_FILES + uid + ".jpg";
try {
OutputStream out = new FileOutputStream(new File(absPath));
int read = 0;
byte[] bytes = new byte[1024];
out = new FileOutputStream(new File(absPath));
while ((read = input.read(bytes)) != -1) {
out.write(bytes, 0, read);
}
out.flush();
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
Here is the client code (javascript):
$scope.fileSelect = function (files) {
var file = files[0];
console.log("File loaded");
console.log(files);
console.log('uid = ' + $scope.uid + ' user = ' + $scope.user);
var formData = new FormData();
formData.append('pic', file);
var requestBody = {"token": $scope.token};
var req = {
method: 'POST',
url: 'http://192.168.0.9/resources/UploadPicture?uid=' + $scope.uid,
headers: {
'Content-Type': undefined
},
data: formData
};
console.log(FormData);
$http(req).then(function(response){
console.log(response);
}, function(error){
console.log(error);
});
};
This code produces a file that isnt viewable. The files im expecting are images.
So i got 2 questions:
Whenever the webservice gets called an a response is return, it seems like the image isnt fully flushed to the harddisk. After a while i can edit it. Is there a way to respond back to the client when the image is actually flushed to the disk?
How can i get the input stream to produce a viewable image when its written to the disk?
--edit--
After some fiddling with the file, i realized if i edit the image in notepad++ and took off the beggining and ending tags for the form boundaries, the image is viewable again:
Produced File
Is there a way for the form boundaries to stop interfering with the image data?
I found a solution using apache commons fileupload:
#POST
#Consumes(MediaType.MULTIPART_FORM_DATA)
#Produces(MediaType.TEXT_PLAIN)
public String getFile(#Context HttpServletRequest request, #QueryParam("uid") String uid) {
ServletFileUpload upload = new ServletFileUpload();
try {
FileItemIterator iter = upload.getItemIterator(request);
while (iter.hasNext()) {
FileItemStream item = iter.next();
String name = item.getFieldName();
InputStream stream = item.openStream();
if (item.isFormField()) {
System.out.println("Form field " + name + " with value "
+ Streams.asString(stream) + " detected.");
} else {
System.out.println("File field " + name + " with file name "
+ item.getName() + " detected.");
// Process the input stream
storeFile(stream, uid);
}
}
return "success";
} catch (FileUploadException ex) {
Logger.getLogger(UploadImage.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Logger.getLogger(UploadImage.class.getName()).log(Level.SEVERE, null, ex);
}
return "failed.";
}
Related
I am able to create the file but not able to download it. I am trying to download the file by an ajax call. I am able to receive the file name and file content and successfully able to write the content in a file in application directory but I'm not able to download that file. My code is given bellow :-
The Ajax Code -:
downloadButton.onclick = function() {
//alert(payLoadID);
$.ajax({
type: "POST",
url: "payloadAjax",
data: { payloadData: document.getElementById("modal_paragraph").innerHTML, id: payLoadID },
success : function(data) {
alert("SUCCESS: " +data);
// modal.style.display = "none";
// $("body").css("overflow","auto");
},
error : function(e) {
alert("ERROR: "+ e);
},
done : function(e) {
alert("DONE");
}
})
}
Here is the java code -:
#RequestMapping(value = "/payloadAjax", method = RequestMethod.POST, produces = MediaType.TEXT_PLAIN_VALUE)//, produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
public #ResponseBody
void download(#RequestParam("payloadData") String payloadData, #RequestParam("id") String fileName, HttpServletRequest request, HttpServletResponse response) throws Exception {
System.out.println("id : " +fileName);
System.out.println("payloadData : " +payloadData);
/* File creation code is here. */
String FOLDER = "/downloadDir";
String FILE_NAME = fileName +".txt";
String appPath = request.getRealPath("");
System.out.println("appPath = " + appPath);
File downloadDirectory = new File(appPath + FOLDER);
if(!downloadDirectory.exists() || !downloadDirectory.isDirectory()) {
downloadDirectory.mkdir();
System.out.println("Directory Created");
} else {
System.out.println("Directory already exists.");
}
File uploadFile = new File(downloadDirectory, FILE_NAME);
if(uploadFile.exists()) {
uploadFile.delete();
System.out.println(uploadFile.getName() +" Has been deleted.");
}
try {
uploadFile.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("New File successfully created.");
try
{
PrintWriter writer = new PrintWriter(uploadFile, "UTF-8");
writer.println(payloadData);
writer.flush();
writer.close();
System.out.println("File successfully written.");
}
catch(Exception ex) {
ex.printStackTrace();
}
if (uploadFile.exists()) {
System.out.println("Upload file exists. Ready to download....");
} else {
System.out.println("Sorry File not found!!!!");
}
/*File creation code successfully completed.*/
/*File download code starts here */
/*HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.TEXT_HTML);
headers.setContentLength(uploadFile.length());
headers.setContentDispositionFormData("attachment", "Soubhab_Pathak.txt");
InputStreamResource isr = new InputStreamResource(new FileInputStream(uploadFile));
return new ResponseEntity<InputStreamResource>(isr, headers, HttpStatus.OK);*/
if(response == null) {
System.out.println("Response is null.");
} else {
System.out.println("Response is not null.");
}
System.out.println("111");
OutputStream out = response.getOutputStream();
System.out.println("112");
FileInputStream in = new FileInputStream(uploadFile);
System.out.println("113");
response.setContentType(MediaType.TEXT_PLAIN_VALUE);
response.setHeader("Content-Disposition", "attachment; filename=" + FILE_NAME);
response.setHeader("Content-Length", uploadFile.length() +"");
FileCopyUtils.copy(in, out);
System.out.println("114");
response.flushBuffer();
System.out.println("115");
/*File download code completes here.*/
}
The log is as follows
Any idea?
Finally I am able to solve the problem. This also an example of how to download a string as file in Spring MVC using ajax. Solution is as follows -:
1) one controller action to receive the string from ajax call and store that string in a file in the application server.
2) another controller action where you need to write file download code and this action will receive a GET request.
3) in the ajax call in the success part just call the second action method to download the file.
Now the code is working fine.
I am returning a temporary file from my JAX-RS REST Service like below:
#GET
#Produces(MediaType.APPLICATION_OCTET_STREAM)
public Response getFile() {
File file = ... // create a temporary file
return Response.ok(file, MediaType.APPLICATION_OCTET_STREAM)
.header("Content-Disposition", "attachment; filename=\"" + file.getName() + "\"" ) //optional
.build();
}
What is the correct way of removing this temporary file after the response has been processed? Is the JAX-RS implementation (like Jersey) supposed to do this automatically?
You can pass an instance of StreamingOutput that copies the content of the source file to the client output and eventually deletes the file.
final Path path = getTheFile().toPath();
final StreamingOutput output = o -> {
final long copied = Files.copy(path, o);
final boolean deleted = Files.deleteIfExists(path);
};
return Response.ok(output).build();
final File file = getTheFile();
return Response.ok((StreamingOutput) output -> {
final long copied = Files.copy(file.toPath(), output);
final boolean deleted = file.delete();
}).build();
The example on https://dzone.com/articles/jax-rs-streaming-response looks more helpful than the brief reply from Jin Kwon.
Here is an example:
public Response getDocumentForMachine(#PathParam("custno") String custno, #PathParam("machineno") String machineno,
#PathParam("documentno") String documentno, #QueryParam("language") #DefaultValue("de") String language)
throws Exception {
log.info(String.format("Get document. mnr=%s, docno=%s, lang=%s", machineno, documentno, language));
File file = new DocFileHelper(request).getDocumentForMachine(machineno, documentno, language);
if (file == null) {
log.error("File not found");
return Response .status(404)
.build();
}
StreamingOutput stream = new StreamingOutput() {
#Override
public void write(OutputStream out) throws IOException, WebApplicationException {
log.info("Stream file: " + file);
try (FileInputStream inp = new FileInputStream(file)) {
byte[] buff = new byte[1024];
int len = 0;
while ((len = inp.read(buff)) >= 0) {
out.write(buff, 0, len);
}
out.flush();
} catch (Exception e) {
log.log(Level.ERROR, "Stream file failed", e);
throw new IOException("Stream error: " + e.getMessage());
} finally {
log.info("Remove stream file: " + file);
file.delete();
}
}
};
return Response .ok(stream)
.build();
}
I am trying to to download the report generated in server to the local machine for that i have written a servlet and calling the servelt from my jsp. But its not ont invoking my servlet... i have added some S.O.P for testing and i am not getting those s.o.ps in log and and the screen display blank.
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try {
System.out.println("In RRR DownLoadServlet");
outs = response.getOutputStream();
String action = request.getParameter("action");
String strInfodom = "DMINFO88";
//String filename = request.getParameter("filename");
String filename = "/Report_Income Statement.xls";
if (action.equals("6")) {
Vector<String> vProperties = new Vector<String>();
vProperties.addElement("DOCUMENT_UPLOAD_SAVE");
vProperties.addElement("DOCUMENT_UPLOAD_TEMP");
// Properties prop = SMSServices.getConfiguration(vProperties);
// String strUploadSave = (String) prop.get("DOCUMENT_UPLOAD_SAVE");
// String strUploadTemp = (String) prop.get("DOCUMENT_UPLOAD_TEMP");
String completePath = RRRConstants.RRR_PATH+RRRConstants.OUTPUT;
System.out.println("Report File path :::::::::::::::: "+completePath);
if (completePath != null) {
byte arrByte[] = new byte[1024];
int readBytes = -1;
response.setContentType("application/x-download");
response.setHeader("Content-Disposition", "attachment; filename=" + completePath.substring(completePath.lastIndexOf("/") + 1));
fin = new FileInputStream(new File(completePath));
BufferedInputStream bout = new BufferedInputStream(fin);
while ((readBytes = bout.read(arrByte)) > 0) {
outs.write(arrByte, 0, readBytes);
}
outs.flush();
}
}
}
catch (Exception e) {
e.printStackTrace();
}
finally {
try {
if (outs != null)
outs.close();
if (fin != null)
fin.close();
}
catch (Exception e) {
e.printStackTrace();
}
}
}
jsp code :
<%
String infodom = request.getParameter("infodom");
String user = (String) session.getAttribute("gsUsrID");
String strURL = "";
FileHandler objFileHandler = new FileHandler(null);
WebServerInfo objWebServer = objFileHandler.getPrimaryWebServerInfo();
String protocol = objWebServer.getServletProtocol();
try
{
strURL = protocol+ "://" + getServletConfig().getServletContext().getInitParameter("FIC_WEBSERVER_IP") + ":" + getServletConfig().getServletContext().getInitParameter("FIC_WEBSERVER_PORT") + request.getContextPath() + "/RRRDownLoadServlet?infodom="+infodom+"&filename=";
}
catch(Exception e)
{
System.out.println(" [Download.jsp] Exception "+e);
}
%>
function downloareport()
{
alert("downloading");
var filename = "/Report_Income Statement.xls";
downloadExcel(filename);
}
function downloadExcel(excelFile)
{
window.location.href = "<%=strURL%>"+ excelFile+"&mode=excel";
}
The jsp code contains some javascript. Check these points:
In javascript; writing just function body doesn't automatically invoke that, one has to make call to the function somewhere.
Also tags for java-scripts seems missing.
The request from the JSP is get, not post. Use doGet(...){} instead of doPost(...){...} in servlet.
I have a little problem when I try to download a file with rest.
Here is my function :
#GET
#Produces(MediaType.APPLICATION_OCTET_STREAM)
#Path("{directory: (([^/]+[/])+)[^/]+}")
public Response getFile(#PathParam("directory") String directory)
{
Response responseFile = null;
try
{
/*String tmpFileName = "REST_FTP_TMPFile_"+ Math.random();
tmpFileName = tmpFileName.replace(".", "");
File tmpFile = new File(tmpFileName);
tmpFile.createNewFile();
//*/
String filename = directory.substring(directory.lastIndexOf("/")+1, directory.length());
File tmpFile = File.createTempFile("REST_FTP_TMPFile_", null);
directory = StringEscapeUtils.unescapeHtml4(directory);
this.client.getFile(directory, tmpFile);
System.out.println("size : " + tmpFile.length());
responseFile = Response.ok(tmpFile, MediaType.APPLICATION_OCTET_STREAM)
.header("Content-length", tmpFile.length())
.header("Content-Disposition","attachment; filename="+filename+"")
.build();
//A voir quand on peut le supprimer...
//tmpFile.delete();
}
catch (IOException ex)
{
Logger.getLogger(GetResource.class.getName()).log(Level.SEVERE, null, ex);
}
return responseFile;
}
The function getFile of client use the libapache method :
public boolean getFile(String pathname, File file) throws IOException
{
OutputStream output;
output = new FileOutputStream(file);
System.out.println("Wanted pathname : "+pathname);
boolean status = this.client.retrieveFile("/"+pathname, output);
if(status)
{
output.close();
return status;
}
else
{
output.close();
throw new IOException("Cannot retrieve the file : " + pathname);
}
}
When I try to download my web browser says that the download is canceled :
I really don't know what I did wrong and nothing on the web helped me out so far (it's been 2 hours..)
I found what the problem was, the FTP transfer is supposed to be in binary mode..
I have made ckeditor plugin to convert doc file to html, the file is uploaded via servlet witha ajax and converted to html. But I am not getting desired html response from servlet. I am getting the same jsp page in result.
Here is Servlet code.
protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
// HttpSession
response.setContentType("text/html"); // session;
if (!ServletFileUpload.isMultipartContent(request)) {
response.sendError(HttpServletResponse.SC_FORBIDDEN,
"only multipart requests are allowed");
return;
}
WebappContext webappContext = WebappContext.get(getServletContext());
ServletFileUpload fileUpload = webappContext.getFileUpload();
OfficeDocumentConverter converter = webappContext
.getDocumentConverter();
String outputExtension = FilenameUtils.getExtension(request
.getRequestURI());
FileItem uploadedFile;
try {
uploadedFile = getUploadedFile(fileUpload, request);
// FileHandler.checkForValidExtn(uploadedFile);
} catch (FileUploadException fileUploadException) {
throw new ServletException(fileUploadException);
}
if (uploadedFile == null) {
throw new NullPointerException("uploaded file is null");
}
String inputExtension = FilenameUtils.getExtension(uploadedFile
.getName());
String baseName = FilenameUtils.getBaseName(uploadedFile.getName());
// File fileFolder=new File(getServletContext().getRealPath("/")
// +"images");
// fileFolder.mkdir();
// File inputFile=new File(fileFolder+"\\"+ baseName + "." +
// inputExtension);
File inputFile = new File(getServletContext().getRealPath("/")
+ baseName + "." + inputExtension);
writeUploadedFile(uploadedFile, inputFile);
File outputFile = new File(getServletContext().getRealPath("/")
+ baseName + "." + "html");
// File outputFile=new File(fileFolder+"\\"+ baseName + "." + "html");
// outputFile.mkdirs();
System.out.println("input file path:" + inputFile.getAbsolutePath());
System.out.println("outPut file path:" + outputFile.getAbsolutePath());
try {
// DocumentFormat outputFormat = converter.getFormatRegistry()
// .getFormatByExtension(outputExtension);
long startTime = System.currentTimeMillis();
converter.convert(inputFile, outputFile);
long conversionTime = System.currentTimeMillis() - startTime;
logger.info(String.format(
"successful conversion: %s [%db] to %s in %dms",
inputExtension, inputFile.length(), outputExtension,
conversionTime));
} catch (Exception exception) {
logger.severe(String.format(
"failed conversion: %s [%db] to %s; %s; input file: %s",
inputExtension, inputFile.length(), outputExtension,
exception, inputFile.getName()));
throw new ServletException("conversion failed", exception);
} finally {
inputFile.delete();
}
PrintWriter out = response.getWriter();
out.println("<b>File Sent to server</b>");
out.close();
}
Here is code javascript code for sendi file to server.
CKEDITOR.dialog.add( 'uploadDoc', function( editor )
{ var dialougeDefination =
{ title: editor.lang.uploadDoc.labelName,
resizable: CKEDITOR.DIALOG_RESIZE_BOTH,
minWidth: 250,
minHeight: 50,
onOk: function()
{ if(document.getElementById("flFileBrowser").value == "")
{ alert("No file selected");
//return;
}
else
{
$.ajax({
beforeSend: function(){
{ $("#frmFileUpload").ajaxSubmit();
$.blockUI();
}
},
success: function(result)
{ alert(result);
$.unblockUI();
}
});
The response is actually in the responseText field, so your code should be
alert(result.responseText);