IE11 converting .xlsx files to .xls and .docx files to .doc - java

I have a java application where users can upload and download files. Recently, we found out that whenever users click on a link on IE11 to download .docx or a .xlsx file, it downloads a .doc or .xls file. In the process, it warns the users that the file format and extension do not match and the users should only open the file if they trust its source. There is no such issue on Microsoft Edge or other browsers.
Is there some setting that can be done in IE11 or can some coding (specific to IE11) be done so that so that it downloads .xlsx and .docx files as they are and doesn't give annoying warning messages to users?
try {
byte[] fileContent = getFileContent(id, fName);
if (fileContent != null) {
OutputStream out = null;
try {
System.out.println("content type: "+getContentType(fName)); //prints application/vnd.ms-excel
res.reset();
out = res.getOutputStream();
res.setContentType(getContentType(fName));
res.setHeader("Content-Disposition", "inline; filename=" + fName + "; size=" + String.valueOf(fileContent.length));
res.setContentLength(fileContent.length);
out.write(fileContent);
setDestination(req, RESPONSE_NO_REDIRECT);
} catch (Exception ex) {
ex.printStackTrace();
} finally {
flushCloseOutputStream(out);
}
} else {
setDestination(req, "/404.jsp");
}
} catch (Exception ex) {
ex.printStackTrace();
}
public byte[] getFileContent(int id, String fileName) {
byte[] bytes = null;
Transaction tx = null;
Session s = null;
try {
GenericDAO dao = HibernateDAOFactory.getInstance().getDAO(GenericClassDAO.class, Files.class);
s = SessionAndTransactionManagementService.createNewSession(dao);
tx = SessionAndTransactionManagementService.startNewTransaction(s);
Criteria cr = s.createCriteria(Files.class)
.add(Restrictions.eq("id", id))
.add(Restrictions.eq("fileName", fileName))
.setProjection(Projections.property("fileContent"));
bytes = (byte[]) cr.uniqueResult();
SessionAndTransactionManagementService.commitTransaction(s);
} catch (Exception e) {
HibernateUtil.rollback(tx);
}finally{
HibernateUtil.cleanupResources(s);
}
return bytes;
}

IE11 was setting content type for all excel files as 'application/vnd.ms-excel' (don't know why). That makes it show warnings and download xlsx files as xls.
I changed my code to set contentType manually to 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' when the filename contains .xlsx and this solved my problem.

Related

In email attachment any type of document file is sent with File extension instead of coreect extension

I am fetching S3 objects and then sending the object in email as an attachment. I am saving the contents in a temporary file. For images the code is working fine but in case of documents (pdf, docx, csv) files the attachments are sent without extension so they are not accessible.
try {
fullObject = s3Client.getObject(new GetObjectRequest(bucketName, key));
System.out.println("fullObject: " + fullObject);
ObjectMetadata metadata = fullObject.getObjectMetadata();
System.out.println(" meta data type: " + metadata.getContentType());
InputStream inputStream = fullObject.getObjectContent();
String extension = fullObject.getKey();
int index = extension.lastIndexOf('.');
if(index > 0) {
extension = extension.substring(index + 1);
System.out.println("File extension is " + extension);
}
File file = File.createTempFile(key, "."+ extension );
System.out.println("file: "+ file);
try (OutputStream outputStream = new FileOutputStream(file)) {
IOUtils.copy(inputStream, outputStream);
} catch (Exception e) {
System.out.println("error in copying data from one file to another");
}
dataSource = new FileDataSource(file);
System.out.println("added datasource in the list");
attachmentsList.add(dataSource);
}
Upon going through this code, I got to know that the issue was not in this code but when I was setting the name of the File. I was setting filename without any extension, for example I set Filename as "temporary" this caused the documents to be saved with tmp extension. All I had to do was add the extension of the object with its name ("temporary.docx"), this solved the issue and attachments were sent properly and were accessible.

After File compression I lost the Filename extension

I am trying to compress my file using the ZipOutPutStream. I tried below code and got the compressed folder with the file. But when I am extracting the folder using 7Zip, the fileName extension is missing.
Also I am unable to extract the folder by normal Extract option provided in Windows.
Below is the code I tried Using Java -8
public void compress(String compressed , String raw) {
Path pCompressed = null;
try {
pCompressed = Files.createFile(Paths.get(compressed));
try (ZipOutputStream zos = new ZipOutputStream(Files.newOutputStream(pCompressed))) {
Path pRaw = Paths.get(raw);
Files.walk(pRaw).filter(path -> !Files.isDirectory(path)).forEach(path -> {
ZipEntry zipEntry = new ZipEntry(pRaw.relativize(path).toString());
try {
zos.putNextEntry(zipEntry);
Files.copy(path, zos);
zos.closeEntry();
} catch (IOException e) {
logger.error("Exception while copying file to compressed Directory: "+e);
}
});
}
catch(IOException ioe) {
logger.error("Exception while compressing the output file: "+ioe);
}
}
catch (IOException e1) {
logger.error("Exception While Path initialization for compressing the file");
}
}
Expecting : After Extraction someFolder/MyFile.csv
I've just tried this code and when I provided it with compressed = "out.zip" and raw = "testdir", it worked fine for me. It produced a zip file containing the contents of testdir. I was then able to extract this with 7Zip and the built in Windows extraction and the files were all present and correct.
My guess is that you have not specified the .zip extension for the output file or that Windows is hiding the extension in the folder view. (I think it does this by default.)

Reading XLSB file with Apache POI

I am reading xlsb file with below code, but its printing as text, I want to get headers, data values for each cell to set to java objects. Which classes should I use. Thanks in advance.
File file = null;
OPCPackage pkg = null;
XSSFEventBasedExcelExtractor ext = null;
try {
file = Paths.get("C:/Users/U574564/Ref/source/Q4_GL_Assignment v1.xlsb").toFile();
pkg = OPCPackage.open(file,PackageAccess.READ);
ZipSecureFile.setMaxTextSize(110485766);
ext = new XSSFBEventBasedExcelExtractor(pkg);
System.out.println(ext.getText());
} catch(Exception ex) {
System.out.println(ex.getMessage());
}

The inline attachment i save to disk is corrupted

I have a piece of code that read my inbox email. the code identify 2 kind of attachments:
1) The attached files, which are downloaded and saved to a database. This works just fine.
2) The inline attachment (I'm using an image as the attachment in my tests). The code detects this kind of attachment, but when I save them to disk the file seems to be corrupted. I checked the file properties generated and noticed that it had no basic info (pixels, height, width) with it. I think the file is not saved properly when downloaded to disk (I have tried PNG and JPG). I think the file needs to be saved with a kind of mimetype properties so i can open it properly. Any tips please? Thanks in advance.!
Here is a snip of my code:
public void procesMultiPart(Multipart content) throws SQLException {
try {
for (int i = 0; i < content.getCount(); i++) {
BodyPart bodyPart = content.getBodyPart(i);
Object o;
String downloadDirectory = "D:/Attachment/";
o = bodyPart.getContent();
if (o instanceof String) {
System.out.println("procesMultiPart es plainText");
} else if (null != bodyPart.getDisposition() && bodyPart.getDisposition().equalsIgnoreCase(Part.ATTACHMENT)) {
System.out.println("IS ATTACHMENT...");
// i save the attachment to database and is OK..
} else if (bodyPart.getDisposition() == null){
System.out.println("IS AN INLINE ATTACHMENT...");
String fileNameinline = "inline" + i + ".png";
InputStream inStream = bodyPart.getInputStream();
FileOutputStream outStream = new FileOutputStream(new File(downloadDirectory + fileNameinline), true);
byte[] tempBuffer = new byte[4096];// 4 KB
int numRead;
while ((numRead = inStream.read(tempBuffer)) != -1) {
outStream.write(tempBuffer);
}
inStream.close();
outStream.close();
}
}
} catch (IOException e) {
e.printStackTrace();
} catch (MessagingException e) {
e.printStackTrace();
}
}
The file is corrupted because you are writing it to the disc incorrectly:
outStream.write(tempBuffer);
You should only write as many bytes as you read:
outStream.write(tempBuffer, 0, numRead);
Thanks to everyone for help and tips. I solved the problem. This is how i did it: I notice that when read the email body (where supposes there was just the pasted image) , there was more that just the image, there was a kind of HTML too, so in other words, the body part has multiparts (2 parts in my case), so i have to process each part until find the image, so i can save it.
hope this help someone else.
regards.

Displaying Pdf Document by Servlet

I am trying to show pdf document in a iframe. I have set the source of the iframe to a servlet and passing some parameter to the servlet.
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try {
String docName = request.getParameter("docName");
String id = request.getParameter("id");
if (StringUtils.isNotBlank(id) && StringUtils.isNotBlank(docName)) {
DocumentService service = DamServiceProvider.PROVIDER.getDocumentService();
FileInBean fileInBean = new FileInBean();
fileInBean.setDocName(docName);
fileInBean.setId(Integer.valueOf(id));
FileDataBean fileDataBean = service.getFileDataBean(fileInBean);
if (fileDataBean.getStatusCode() == 0) {
Map<String, String> headerFieldMap = fileDataBean.getHeaderFieldMap();
String contentType = headerFieldMap.get("Content-type");
String contentLength = headerFieldMap.get("Content-Length");
String contentDisposition = headerFieldMap.get("Content-Disposition");
byte[] stream = fileDataBean.getStream();
ByteArrayInputStream inputStream = new ByteArrayInputStream(stream);
OutputStream outputStream = response.getOutputStream();
response.reset();
response.setBufferSize(4096);
response.setContentLength(Integer.valueOf(contentLength));
response.setContentType(contentType);
response.setHeader("Content-Disposition", contentDisposition);
System.out.println(contentDisposition);
IOUtils.copy(inputStream, outputStream);
outputStream.close();
inputStream.close();
}
}
} catch (Exception ex) {
Log.error(this, ex.getMessage());
}
}
Now in my page I have a master–detail interface. The master part contains a carousel of series of pdf file items. On clicking the item I am refreshing the detail view which contains the iframe.
I can see the servlet get called. Most of the times the iframe is displaying the pdf document. But sometimes it is showing weird xml structure which contains xml tags and some unreadable output. Please see the attach image:
This is not happening for a particular file. If a file shows this output, sometime later if click the item it shows the valid pdf and if an item shows a valid pdf sometime later it shows this kind of output if I click on it. When the iframe shows this type of output my browser displays an information that this pdf document might be corrupted.
I have checked the repository where the files are and I have found no issues there. All of them are valid pdf and I can download and open them by pdf reader.
I am unable to find the cause of this issue. Any pointer would be very helpful.
Update - 1
I have checked the output. It ends with %%EOF and has %PDF in the beginning.
Update - 2
I have checked in Chrome's Network Console the GET is returning mainly three types of content-type: application/pdf, text/plain, application/octet-stream.
application/pdf: it is showing the pdf.
text/plain it is showing the content that I mentioned above.
application/octet-stream didn't arise in Firefox but in Chrome and in that case it is opening the download file window.
I have placed a log in the servlet to see the content-type that returned from service. For all the cases it is application/pdf.
I think it maybe a problem with the content-Type, you can confirm if this is the espected in your browser with the developer tools (in the network console for Chrome).
try something like this.
File pdfFile = new File(this.pdfStoreLocation + pdfFileName);
response.setContentType("application/pdf");
response.setHeader("Content-Disposition", "attachment; filename=" + pdfFileName);
response.setContentLength((int) pdfFile.length());
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(pdfFile));
BufferedOutputStream bos = new BufferedOutputStream(response.getOutputStream());
// byte array declared
byte[] buf = new byte[2048];
boolean eof = false;
while (!eof) {
int length = bis.read(buf);
if (length == -1) {
eof = true;
}else {
bos.write(buf, 0, length);
}
}
try {
bis.close();
}catch (IOException ex) {
LOGGER.error("Exception in closing buffered input stream on pdf file->" + this.pdfStoreLocation + pdfFileName);
}
try {
bos.flush();
}catch (IOException ex) {
LOGGER.error("Exception in fliushing buffered output stream on pdf file->"
+ this.pdfStoreLocation + pdfFileName);
}
bos.close();

Categories

Resources