I am new to Struts and working on File Upload using Struts.
Client:
It is Java Program which hits my Strut app by using apache HttpClient API and provides me
File.
Client as per need sometime gives me .wav file and sometime .zip file and sometime both.
Server:
Struts app which got the request from client app and upload the file.
Here, problem comes as I upload the file, it get uploaded using ".tmp" extension, which I want to get uploaded with the same extension what client has passed.
Or there is any other way by which we can check what is the extension of the file client has sent....?
I am stuck in this problem and not able to go ahead.
Please Find the code attached and tell me what modification I have to do:
Server Code:
MultiPartRequestWrapper multiWrapper=null;
File baseFile=null;
System.out.println("inside do post");
multiWrapper = ((MultiPartRequestWrapper)request);
Enumeration e = multiWrapper.getFileParameterNames();
while (e.hasMoreElements()) {
// get the value of this input tag
String inputValue = (String) e.nextElement();
// Get a File object for the uploaded File
File[] file = multiWrapper.getFiles(inputValue);
// If it's null the upload failed
if (file != null) {
FileInputStream fis=new FileInputStream(file[0]);
System.out.println(file[0].getAbsolutePath());
System.out.println(fis);
int ch;
while((ch=fis.read())!=-1){
System.out.print((char)ch);
}
}
}
System.out.println("III :"+multiWrapper.getParameter("method"));
Client code:
HttpClient client = new HttpClient();
MultipartPostMethod mPost = new MultipartPostMethod(url);
File zipFile = new File("D:\\a.zip");
File wavFile = new File("D:\\b.wav");
mPost.addParameter("recipientFile", zipFile);
mPost.addParameter("promptFile", wavFile);
mPost.addParameter("method", "addCampaign");
statusCode1 = client.executeMethod(mPost);
actually Client is written long back and cant be modified and I want to identify something at server side only to find the extension.
Please help, Thanks.
Struts2 File Uploader interceptor when uploading file pass the content type information to the Action class and one can easily find the file type by comparing contentType with MIME type.
If you want to can create a map with key as content type and file type as its value like
map.Add("image/bmp",".bmp", )
map.Add("image/gif",".gif", )
map.Add("image/jpeg",".jpeg", )
and can easily fetch the type based on the extension provides.Hope this will help you.
Related
I am working on asp.net MVC project.
I use ExcelDataReader component to read excel file records.
Now when I published my project to server and upload a .xlsx file with uploader I get below mentioned exception message. There are no errors with local deployment but server.
Access to the path '\Microsoft Corporation\Internet Information
Services\7.5.7600.16385' is denied.
and code where I am getting error is:
if (personsFile.FileExtension == ".xls")
{
Stream st = new MemoryStream(personsFile.FileArray);
reader = ExcelReaderFactory.CreateBinaryReader(st);
}
else if (personsFile.FileExtension == ".xlsx")
{
Stream st = new MemoryStream(personsFile.FileArray);
//exception occured on under line
reader = ExcelReaderFactory.CreateOpenXmlReader(st);
}
But when I upload a .xls file, I dont have any error.
How to resolve issue with .xlsx extenstion?
This is most likely due to ExcelDataReader 2.x extracting the xlsx archive to %TEMP% before processing it. The current pre-alpha of 3.0 no longer does this. See https://github.com/ExcelDataReader/ExcelDataReader/releases.
I am using the Export plugin in Grails for generating PDF/Excel report. I am able to generate single report on PDF/Excel button click. But, now I want to generate multiple reports on single button click. I tried for loop, method calls but no luck.
Reference links are ok. I don't expect entire code, needs reference only.
If you take a look at the source code for the ExportService in the plugin you will notice there are various export methods. Two of which support OutputStreams. Using either of these methods (depending on your requirements for the other parameters) will allow you to render a report to an output stream. Then using those output streams you can create a zip file which you can deliver to the HTTP client.
Here is a very rough example, which was written off the top of my head so it's really just an idea rather than working code:
// Assumes you have a list of maps.
// Each map will have two keys.
// outputStream and fileName
List files = []
// call the exportService and populate your list of files
// ByteArrayOutputStream outputStream = new ByteArrayOutputStream()
// exportService.export('pdf', outputStream, ...)
// files.add([outputStream: outputStream, fileName: 'whatever.pdf'])
// ByteArrayOutputStream outputStream2 = new ByteArrayOutputStream()
// exportService.export('pdf', outputStream2, ...)
// files.add([outputStream: outputStream2, fileName: 'another.pdf'])
// create a tempoary file for the zip file
File tempZipFile = File.createTempFile("temp", "zip")
ZipOutputStream out = new ZipOutputStream(new FileOutputStream(tempZipFile))
// set the compression ratio
out.setLevel(Deflater.BEST_SPEED);
// Iterate through the list of files adding them to the ZIP file
files.each { file ->
// Associate an input stream for the current file
ByteArrayInputStream input = new ByteArrayInputStream(file.outputStream.toByteArray())
// Add ZIP entry to output stream.
out.putNextEntry(new ZipEntry(file.fileName))
// Transfer bytes from the current file to the ZIP file
org.apache.commons.io.IOUtils.copy(input, out);
// Close the current entry
out.closeEntry()
// Close the current input stream
input.close()
}
// close the ZIP file
out.close()
// next you need to deliver the zip file to the HTTP client
response.setContentType("application/zip")
response.setHeader("Content-disposition", "attachment;filename=WhateverFilename.zip")
org.apache.commons.io.IOUtils.copy((new FileInputStream(tempZipFile), response.outputStream)
response.outputStream.flush()
response.outputStream.close()
That should give you an idea of how to approach this. Again, the above is just for demonstration purposes and isn't production ready code, nor have I even attempted to compile it.
I'm trying to parse text files using apache tika. I pass a file to the following code:
public String parseFile(File file) throws Exception{
Parser parser = new AutoDetectParser();
Metadata metadata = new Metadata();
ParseContext parseContext = new ParseContext();
BodyContentHandler handler = new BodyContentHandler(1000000000);
FileInputStream is = new FileInputStream(file);
parser.parse(is, handler, metadata, parseContext);
System.out.println("Content: "+ handler.toString());
return handler.toString();
}
My issue is that Tika recognises SOME files but not ALL files. I'm sorry but I'm unable to actully attach the files that do not work (corporate reasons). If I do find an acceptable example, I will share it. I wanted to know if there was something blatantly obvious which I am doing wrong. I'm not sure how the BodyContentHandler class works. In most of the tutorials I read online, the code is as follows :
ContentHandler handler = new BodyContentHandler ();
However, my eclipse refuses to accept that. And asks me to cast BodyContentHandler to ContentHandler which causes other problems.
I'm trying to support text files, pdf files, word documents, excel files. The text Files that DO NOT work have a certain property: I copy paste an email thread from outlook to notepad. Most files that do not work are of this kind.
I'm trying to save an image from an OpenLDAP server. It's in binary format and all my code appears to work, however, the image is corrupted.
I then attempted to do this in PHP and was successful, but I'd like to do it in a Grails project.
PHP Example (works)
<?php
$conn = ldap_connect('ldap.example.com') or die("Could not connect.\n");
ldap_set_option($conn, LDAP_OPT_PROTOCOL_VERSION, 3);
$dn = 'ou=People,o=Acme';
$ldap_rs = ldap_bind($conn) or die("Can't bind to LDAP");
$res = ldap_search($conn,$dn,"someID=123456789");
$info = ldap_get_entries($conn, $res);
$entry = ldap_first_entry($conn, $res);
$jpeg_data = ldap_get_values_len( $conn, $entry, "someimage-jpeg");
$jpeg_filename = '/tmp/' . basename( tempnam ('.', 'djp') );
$outjpeg = fopen($jpeg_filename, "wb");
fwrite($outjpeg, $jpeg_data[0]);
fclose ($outjpeg);
copy ($jpeg_filename, '/some/dir/test.jpg');
unlink($jpeg_filename);
?>
Groovy Example (does not work)
def ldap = org.apache.directory.groovyldap.LDAP.newInstance('ldap://ldap.example.com/ou=People,o=Acme')
ldap.eachEntry (filter: 'someID=123456789') { entry ->
new File('/Some/dir/123456789.jpg').withOutputStream {
it.write entry.get('someimage-jpeg').getBytes() // File is created, but image is corrupted (size also doesn't match the PHP version)
}
}
How would I tell the Apache LDAP library that "image-jpeg" is actually binary and not a String? Is there a better simple library available to read binary data from an LDAP server? From looking at the Apache mailing list, someone else had a similar issue, but I couldn't find a resolution in the thread.
Technology Stack
Grails 2.2.1
Apache LDAP API 1.0.0 M16
Have you checked whether the image attribute value is base-64 encoded?
I found the answer. The Apache Groovy LDAP library uses JNDI under the hood. When using JNDI certain entries are automatically read as binary, but if your LDAP server uses a custom name, the library will not know that it's binary.
For those people that come across this problem using Grails, here's the steps to set a specific entry to binary format.
Create a new properties file call "jndi.properties" and add it to your grails-app/conf directory (all property files in this folder are automatically included in the classpath)
Add a line in the properties file with the name of the image variable:
java.naming.ldap.attributes.binary=some_custom_image
Save the file and run the Grails application
Here is some sample code to save a binary entry to a file.
def ldap = LDAP.newInstance('ldap://some.server.com/ou=People,o=Acme')
ldap.eachEntry (filter: 'id=1234567') { entry ->
new File('/var/dir/something.jpg').withOutputStream {
it.write entry.image
}
}
ASP.NET has four different types of file results:
FileContentResult: Sends the contents of a binary file to the response.
FilePathResult: Sends the contents of a file to the response
FileResult: Returns binary output to write to the response
FileStreamResult: Sends binary content to the response by using a Stream instance
Those descriptions are take from MSDN and with the exception of the FileStreamResult the first three sound identical. So what is the difference between them?
FileResult is an abstract base class for all the others.
FileContentResult - you use it when you have a byte array you would like to return as a file
FilePathResult - when you have a file on disk and would like to return its content (you give a path)
FileStreamResult - you have a stream open, you want to return its content as a file
However, you'll rarely have to use these classes - you can just use one of Controller.File overloads and let ASP.NET MVC do the magic for you.
Great question...and deserves more details. I find myself here as a result of an interesting situation. We were delivering some pdf attachments via the MVC3/C# environment. Our code got released and we started getting some responses from our clients that the downloads were behaving strangely when they were using Chrome and the file type was being converted over to 'pdf-, attachment.pdf-, attachment'. Yup...you got it...the whole thing. So, one could rewrite it to just be 'pdf' and the file would still save intact, but what a mess!
So, to describe the initial situation, we were setting the 'Content-Disposition' header then returning a FileContentResult...
var cd = new System.Net.Mime.ContentDisposition
{
FileName = result.Attachment.FileName,
Inline = false
};
Response.AppendHeader("Content-Disposition", cd.ToString());
return File(result.Attachment.Data, MimeExtensionHelper.GetMimeType(result.Attachment.FileName), result.Attachment.FileName);
Seemed good. Worked fine in IE. So I did some research and tried implementing FileStreamResult instead (keeping the Content-Disposition setter):
MemoryStream dataStream = new MemoryStream();
dataStream.Write(result.Attachment.Data, 0, result.Attachment.Data.Length);
dataStream.Position = 0;
return new FileStreamResult(dataStream, MimeExtensionHelper.GetMimeType(result.Attachment.FileName));
It fixed the issue in Chrome! Hmmm...but why in the heck should I have to take my perfectly good byte array and stream it and then return it via this to get the file name to work right?
Then came the Fiddler.
With FileContentResult, I got 2 Content-Dispositions in the header.
With FileStreamResult, I got 1.
FileContentResult appends a Content-Disposition header when providing the File Name and Chrome considers multiples of this header as an error.
Odd reaction...but definitely one that's good to know.