Retrieving email attachment filename with mime4j - java

I'm trying to use mime4j to parse emails, all is working fine, however I'm not able to get the file name of the attachment. Unfortunately the BodyDescriptor doesn't include this information in the content disposition, or content type fields.
I have read that the MaximalBodyDescriptor will include the filename, however I don't know how to tell the parser to return a MaximalBodyDescriptor object.
My handler is implementing the ContentHandler interface. I can't see an alternate interface which would work.
Any advice appreciated.

Here is a helper class that we use successfully to parse e-mails with their attachments.
In this approach attach.getFileName() has the filename.
package com.bitplan.smartCRM;
import java.awt.Toolkit;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.ClipboardOwner;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.StringSelection;
import java.awt.datatransfer.Transferable;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.Enumeration;
import java.util.List;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.mail.Flags;
import javax.mail.Folder;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.Store;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import org.apache.commons.io.IOUtils;
import org.apache.james.mime4j.MimeException;
import org.apache.james.mime4j.dom.Body;
import org.apache.james.mime4j.dom.Entity;
import org.apache.james.mime4j.dom.Message;
import org.apache.james.mime4j.dom.MessageBuilder;
import org.apache.james.mime4j.dom.MessageServiceFactory;
import org.apache.james.mime4j.dom.Multipart;
import org.apache.james.mime4j.dom.SingleBody;
import org.apache.james.mime4j.dom.TextBody;
import org.apache.james.mime4j.dom.address.MailboxList;
import org.apache.james.mime4j.message.MessageImpl;
import org.apache.james.mime4j.stream.Field;
import com.bitplan.restinterface.Configuration;
/**
* EMail Helper class
*
* #author wf
* #author Denis Lunev <den#mozgoweb.com>
* #see http
* ://www.mozgoweb.com/posts/how-to-parse-mime-message-using-mime4j-library
* /
*/
public class EMailHelper implements ClipboardOwner {
public static boolean debug = true;
public static Logger LOGGER = Logger
.getLogger("com.bitplan.common.EMailHelper");
private StringBuffer txtBody;
private StringBuffer htmlBody;
private ArrayList<Entity> attachments;
/**
* get a String from an input Stream
*
* #param inputStream
* #return
* #throws IOException
*/
public String fromInputStream(InputStream inputStream) throws IOException {
String result = IOUtils.toString(inputStream);
// System.out.println(result);
return result;
}
/**
* get the full Mail from a message
*
* #param message
* #return
* #throws MessagingException
* #throws IOException
*/
public String fullMail(javax.mail.Message message) throws MessagingException,
IOException {
StringBuffer sBuf = new StringBuffer();
#SuppressWarnings("unchecked")
Enumeration<javax.mail.Header> headers = message.getAllHeaders();
while (headers.hasMoreElements()) {
javax.mail.Header header = headers.nextElement();
sBuf.append(header.getName() + ": " + header.getValue() + "\n");
}
sBuf.append(fromInputStream(message.getInputStream()));
return sBuf.toString();
}
/**
* Authentication
*/
public static class Authentication {
enum AuthenticationType {
pop3, smtp
};
String host;
String user;
String password;
AuthenticationType authenticationType;
Transport mTransport;
/**
* create an Authentication from the configuration
*
* #param configuration
* #param pAuthType
*/
public Authentication(Configuration configuration,
AuthenticationType pAuthType) {
authenticationType = pAuthType;
String prefix = pAuthType.name() + ".";
// use prefix e.g. pop3.host / smtp.host
host = (String) configuration.toMap().get(prefix + "host");
user = (String) configuration.toMap().get(prefix + "user");
password = (String) configuration.toMap().get(prefix + "password");
}
/**
* authenticate for sending / receiving e-mail
*
* #throws MessagingException
*/
public Transport authenticate() throws MessagingException {
Properties lProps = new Properties();
Session session = Session.getDefaultInstance(lProps);
switch (authenticationType) {
case pop3:
Store store = session.getStore("pop3");
store.connect(host, user, password);
store.close();
return null;
case smtp:
// http://javamail.kenai.com/nonav/javadocs/com/sun/mail/smtp/package-summary.html
mTransport = session.getTransport("smtp");
mTransport.connect(host, user, password);
return mTransport;
}
return null;
}
}
/**
* send the given e-mail
*
* #param email
* #throws MessagingException
*/
public void send(EMail email, Configuration configuration)
throws MessagingException {
Authentication lAuth = new Authentication(configuration,
Authentication.AuthenticationType.pop3);
Properties lProps = System.getProperties();
lProps.put("mail.smtp.host", lAuth.host);
// WF 2004-09-18: make sure full qualified domain name is used for localhost
// the default InetAddress.getLocalHost().getHostName() might not work ...
// lProps.put("mail.smtp.localhost",java.net.InetAddress.getLocalHost().getCanonicalHostName());
Session lSession = Session.getInstance(lProps);
MimeMessage lMsg = new MimeMessage(lSession);
lMsg.setFrom(new InternetAddress(email.getFromAdr()));
lMsg.setRecipients(javax.mail.Message.RecipientType.TO,
InternetAddress.parse(email.getToAdr()));
if (email.getCC() != null)
lMsg.setRecipients(javax.mail.Message.RecipientType.CC,
InternetAddress.parse(email.getCC()));
/*
* if (bcc()!=null) lMsg.setRecipients(Message.RecipientType.BCC,
* InternetAddress.parse(bcc())); lMsg.setHeader("X-Mailer", "JavaMail");
* lMsg.setSentDate(new Date()); lMsg.setSubject(subject());
* lMsg.setText(content()); lMsg.saveChanges(); Transport
* lTransport=lAuth.authenticate(); if (lTransport!=null)
* lTransport.sendMessage(lMsg,lMsg.getAllRecipients()); } else {
* Transport.send(lMsg); }
*/
}
/**
* retrieve pop3 mail from the given host
*
* #param pop3host
* #param user
* #param password
* #throws Exception
*/
public List<EMail> retrievePop3Mail(EMailManager eMailmanager,
Configuration configuration) throws Exception {
List<EMail> result = new ArrayList<EMail>();
Properties lProps = new Properties();
Session session = Session.getDefaultInstance(lProps);
Store store = session.getStore("pop3");
File attachmentDirectory = (File) configuration.toMap().get(
"attachmentDirectory");
// get a pop3 authentication
Authentication auth = new Authentication(configuration,
Authentication.AuthenticationType.pop3);
store.connect(auth.host, auth.user, auth.password);
Folder remoteInbox = store.getFolder("INBOX");
remoteInbox.open(Folder.READ_WRITE);
javax.mail.Message message[] = remoteInbox.getMessages();
if (message.length > 0) {
// get all messages
LOGGER.log(Level.INFO, "Getting " + message.length
+ " messages from POP3 Server '" + store.getURLName() + "'");
for (int i = 0; i < message.length; i++) {
if (!message[i].isSet(Flags.Flag.DELETED)) {
EMail email = eMailmanager.create();
String mailInput = this.fullMail(message[i]);
// System.out.print(mailInput);
ByteArrayInputStream mailStream = new ByteArrayInputStream(
mailInput.getBytes());
this.parseMessage(email, mailStream, attachmentDirectory);
result.add(email);
message[i].setFlag(Flags.Flag.DELETED, true);
}
} // for
} // if
remoteInbox.close(true);
store.close();
return result;
}
/**
* parse the Message into the given EMail
*
* #param email
* #param fileName
* #param attachmentDirectory
*
* #throws Exception
*/
public void parseMessage(EMail email, String fileName,
String attachmentDirectory) throws Exception {
parseMessage(email, new File(fileName), new File(attachmentDirectory));
}
/**
* strip the brackets
*
* #param addressList
* #return
*/
public String stripBrackets(MailboxList addressList) {
String result = null;
if (addressList != null) {
result = addressList.toString();
if (result.startsWith("[") && result.endsWith("]")) {
result = result.substring(1, result.length() - 1);
}
}
return result;
}
/**
* parse the Message from the given file into the given e-mail using the given
* attachmentDirectory
*
* #param email
* #param file
* #param attachmentDirectory
* #throws Exception
*/
public void parseMessage(EMail email, File file, File attachmentDirectory)
throws Exception {
if (!file.canRead() || (!file.isFile()))
throw new IllegalArgumentException(file.getCanonicalPath()
+ " is not a readable file");
// Get stream from file
FileInputStream fis = new FileInputStream(file);
parseMessage(email, fis, attachmentDirectory);
}
/**
* parse the Message from the given file into the given e-mail using the given
* attachmentDirectory
*
* #param email
* #param emailInputStream
* #param attachmentDirectory
* #throws Exception
*/
public void parseMessage(EMail email, InputStream eMailInputStream,
File attachmentDirectory) throws Exception {
Message mimeMsg = null;
if (!attachmentDirectory.isDirectory())
throw new IllegalArgumentException(attachmentDirectory.getCanonicalPath()
+ " is not a directory");
txtBody = new StringBuffer();
htmlBody = new StringBuffer();
attachments = new ArrayList<Entity>();
Exception ex = null;
try {
// Create message with stream from file
// If you want to parse String, you can use:
// Message mimeMsg = new Message(new
// ByteArrayInputStream(mimeSource.getBytes()));
MessageServiceFactory factory = MessageServiceFactory.newInstance();
MessageBuilder msgBuilder = factory.newMessageBuilder();
try {
mimeMsg = msgBuilder.parseMessage(eMailInputStream);
} catch (Throwable th) {
LOGGER.log(Level.SEVERE,th.getClass().getName());
LOGGER.log(Level.SEVERE,th.getMessage());
}
if (mimeMsg == null) {
LOGGER.log(Level.SEVERE, "could not read mime msg:\n",
this.fromInputStream(eMailInputStream));
return;
}
// Get some standard headers
if (mimeMsg.getTo() != null)
email.setToAdr(stripBrackets(mimeMsg.getTo().flatten()));
email.setFromAdr(stripBrackets(mimeMsg.getFrom()));
email.setSubject(mimeMsg.getSubject());
email.setSendDate(mimeMsg.getDate());
email.setEMailId(mimeMsg.getMessageId());
LOGGER.log(Level.INFO, "To: " + email.getToAdr());
LOGGER.log(Level.INFO, "From: " + email.getFromAdr());
LOGGER.log(Level.INFO, "Subject: " + mimeMsg.getSubject());
// Get custom header by name
Field priorityFld = mimeMsg.getHeader().getField("X-Priority");
// If header doesn't found it returns null
if (priorityFld != null) {
// Print header value
LOGGER.log(Level.FINEST, "Priority: " + priorityFld.getBody());
}
// If message contains many parts - parse all parts
if (mimeMsg.isMultipart()) {
Multipart multipart = (Multipart) mimeMsg.getBody();
parseBodyParts(multipart);
// fix mime4j 0.7.2 behaviour to have no separate text/plain part
if (txtBody.length() == 0) {
txtBody.append(multipart.getPreamble());
}
} else {
// If it's single part message, just get text body
String text = getTxtPart(mimeMsg);
txtBody.append(text);
}
email.setContent(txtBody.toString());
// Print text and HTML bodies
if (debug) {
LOGGER.log(Level.FINEST, "Text body: " + txtBody.toString());
LOGGER.log(Level.FINEST, "Html body: " + htmlBody.toString());
}
// loop over attachments
for (Entity attach : attachments) {
writeAttachment(attach, attachmentDirectory);
}
} catch (Exception cex) {
ex = cex;
} finally {
if (eMailInputStream != null) {
try {
eMailInputStream.close();
} catch (IOException ioex2) {
ioex2.printStackTrace();
}
}
}
if (ex != null) {
throw ex;
}
}
/**
* write the given Attachment
*
* #param attach
* #param attachmentDirectory
* #throws IOException
*/
public void writeAttachment(Entity attach, File attachmentDirectory)
throws IOException {
String attName = attach.getFilename();
// Create file with specified name
if (attName == null) {
LOGGER.log(Level.WARNING, "attachment has no file name using 'attachment"
+ attach.hashCode() + "' instead");
attName = "attachment" + attach.hashCode();
}
FileOutputStream fos = new FileOutputStream(new File(attachmentDirectory,
attName));
try {
writeBody(fos, attach.getBody());
} finally {
fos.close();
}
}
/**
* write the given body to the given fileoutput stream
*
* #param fos
* #param body
* #throws IOException
*/
public void writeBody(FileOutputStream fos, Body body) throws IOException {
if (body instanceof SingleBody) {
((SingleBody) body).writeTo(fos);
} else if (body instanceof MessageImpl) {
writeBody(fos, ((MessageImpl) body).getBody());
} else {
LOGGER.log(Level.WARNING, "can't handle body of type "
+ body.getClass().getSimpleName());
}
}
/**
* This method classifies bodyPart as text, html or attached file
*
* #param multipart
* #throws IOException
*/
private void parseBodyParts(Multipart multipart) throws IOException {
// loop over the parts
for (Entity part : multipart.getBodyParts()) {
String mimeType = part.getMimeType();
if (mimeType.equals("text/plain")) {
String txt = getTxtPart(part);
txtBody.append(txt);
} else if (mimeType.equals("text/html")) {
String html = getTxtPart(part);
htmlBody.append(html);
} else if (part.getDispositionType() != null
&& !part.getDispositionType().equals("")) {
// If DispositionType is null or empty, it means that it's multipart,
// not attached file
attachments.add(part);
}
// If current part contains other, parse it again by recursion
if (part.isMultipart()) {
parseBodyParts((Multipart) part.getBody());
}
}
}
/**
*
* #param part
* #return
* #throws IOException
*/
private String getTxtPart(Entity part) throws IOException {
// Get content from body
TextBody tb = (TextBody) part.getBody();
return this.fromInputStream(tb.getInputStream());
}
/**
* Place a String on the clipboard, and make this class the owner of the
* Clipboard's contents.
*
* #param aString
*/
public void setClipboardContents(String aString) {
StringSelection stringSelection = new StringSelection(aString);
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
clipboard.setContents(stringSelection, this);
}
/**
* get text from the clipboard
*
* #return
* #throws Exception
*/
public String getClipboardText() throws Exception {
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
String text = (String) clipboard.getData(DataFlavor.stringFlavor);
return text;
}
/**
* get Mail from clipboard
*
* #param email
* #param attachmentDirectory
* #return
* #throws Exception
*/
public boolean getMailFromClipboard(EMail email, File attachmentDirectory)
throws Exception {
String mailText = getClipboardText();
if (mailText == null)
return false;
this.parseMessage(email,
new ByteArrayInputStream(mailText.getBytes("UTF-8")),
attachmentDirectory);
return true;
}
/*
* (non-Javadoc)
*
* #see
* java.awt.datatransfer.ClipboardOwner#lostOwnership(java.awt.datatransfer
* .Clipboard, java.awt.datatransfer.Transferable)
*/
#Override
public void lostOwnership(Clipboard clipboard, Transferable contents) {
}
}

I recommand you to use Token streams.
It is quite straight forward with it.
You can locate attachment by using headers of your multipart section :
Content-Disposition:attachment; filename="toto.txt"
You must be carefull when parsing a header with it ... It can be mail headers or multipart section header....

Related

Using third party library in software ag webmethods results in InvocationTargetException

I'm using This Library in webmethods to read from a large .xlsm file, It's a wrapper around Apache POI library. I cannot use the default POI API since the file contains more than 1 million rows and it's just too big to be loaded at once.
so the problem here is that when I import the library in my test project in eclipse (not webmethods) it works perfectly without any problem but when I import it into webmethods with all the required jar files when I run, it throws an "InvocationTargetException".
Here's the class that is used for parsing from that library:
package com.monitorjbl.xlsx;
import com.monitorjbl.xlsx.exceptions.CloseException;
import com.monitorjbl.xlsx.exceptions.MissingSheetException;
import com.monitorjbl.xlsx.exceptions.OpenException;
import com.monitorjbl.xlsx.exceptions.ReadException;
import com.monitorjbl.xlsx.impl.StreamingCell;
import com.monitorjbl.xlsx.impl.StreamingRow;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.poifs.crypt.Decryptor;
import org.apache.poi.poifs.crypt.EncryptionInfo;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.ss.usermodel.BuiltinFormats;
import org.apache.poi.ss.usermodel.DataFormatter;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.util.CellReference;
import org.apache.poi.xssf.eventusermodel.XSSFReader;
import org.apache.poi.xssf.model.SharedStringsTable;
import org.apache.poi.xssf.model.StylesTable;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.apache.poi.xssf.usermodel.XSSFRichTextString;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import javax.xml.namespace.QName;
import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.events.Attribute;
import javax.xml.stream.events.Characters;
import javax.xml.stream.events.EndElement;
import javax.xml.stream.events.StartElement;
import javax.xml.stream.events.XMLEvent;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.security.GeneralSecurityException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;
import static com.monitorjbl.xlsx.XmlUtils.document;
import static com.monitorjbl.xlsx.XmlUtils.searchForNodeList;
/**
* Streaming Excel workbook implementation. Most advanced features of POI are not supported.
* Use this only if your application can handle iterating through an entire workbook, row by
* row.
*/
public class StreamingReader implements Iterable<Row>, AutoCloseable {
private static final Logger log = LoggerFactory.getLogger(StreamingReader.class);
private final SharedStringsTable sst;
private final StylesTable stylesTable;
private final XMLEventReader parser;
private final DataFormatter dataFormatter = new DataFormatter();
private int rowCacheSize;
private List<Row> rowCache = new ArrayList<>();
private Iterator<Row> rowCacheIterator;
private String lastContents;
private StreamingRow currentRow;
private StreamingCell currentCell;
private File tmp;
private StreamingReader(SharedStringsTable sst, StylesTable stylesTable, XMLEventReader parser, int rowCacheSize) {
this.sst = sst;
this.stylesTable = stylesTable;
this.parser = parser;
this.rowCacheSize = rowCacheSize;
}
/**
* Read through a number of rows equal to the rowCacheSize field or until there is no more data to read
*
* #return true if data was read
*/
private boolean getRow() {
try {
rowCache.clear();
while(rowCache.size() < rowCacheSize && parser.hasNext()) {
handleEvent(parser.nextEvent());
}
rowCacheIterator = rowCache.iterator();
return rowCacheIterator.hasNext();
} catch(XMLStreamException | SAXException e) {
log.debug("End of stream");
}
return false;
}
/**
* Handles a SAX event.
*
* #param event
* #throws SAXException
*/
private void handleEvent(XMLEvent event) throws SAXException {
if(event.getEventType() == XMLStreamConstants.CHARACTERS) {
Characters c = event.asCharacters();
lastContents += c.getData();
} else if(event.getEventType() == XMLStreamConstants.START_ELEMENT) {
StartElement startElement = event.asStartElement();
String tagLocalName = startElement.getName().getLocalPart();
if("row".equals(tagLocalName)) {
Attribute rowIndex = startElement.getAttributeByName(new QName("r"));
currentRow = new StreamingRow(Integer.parseInt(rowIndex.getValue()) - 1);
} else if("c".equals(tagLocalName)) {
Attribute ref = startElement.getAttributeByName(new QName("r"));
String[] coord = ref.getValue().split("(?<=\\D)(?=\\d)|(?<=\\d)(?=\\D)");
currentCell = new StreamingCell(CellReference.convertColStringToIndex(coord[0]), Integer.parseInt(coord[1]) - 1);
setFormatString(startElement, currentCell);
Attribute type = startElement.getAttributeByName(new QName("t"));
if(type != null) {
currentCell.setType(type.getValue());
} else {
currentCell.setType("n");
}
Attribute style = startElement.getAttributeByName(new QName("s"));
if(style != null){
String indexStr = style.getValue();
try{
int index = Integer.parseInt(indexStr);
currentCell.setCellStyle(stylesTable.getStyleAt(index));
} catch(NumberFormatException nfe) {
log.warn("Ignoring invalid style index {}", indexStr);
}
}
}
// Clear contents cache
lastContents = "";
} else if(event.getEventType() == XMLStreamConstants.END_ELEMENT) {
EndElement endElement = event.asEndElement();
String tagLocalName = endElement.getName().getLocalPart();
if("v".equals(tagLocalName)) {
currentCell.setRawContents(unformattedContents());
currentCell.setContents(formattedContents());
} else if("row".equals(tagLocalName) && currentRow != null) {
rowCache.add(currentRow);
} else if("c".equals(tagLocalName)) {
currentRow.getCellMap().put(currentCell.getColumnIndex(), currentCell);
}
}
}
/**
* Read the numeric format string out of the styles table for this cell. Stores
* the result in the Cell.
*
* #param startElement
* #param cell
*/
void setFormatString(StartElement startElement, StreamingCell cell) {
Attribute cellStyle = startElement.getAttributeByName(new QName("s"));
String cellStyleString = (cellStyle != null) ? cellStyle.getValue() : null;
XSSFCellStyle style = null;
if(cellStyleString != null) {
style = stylesTable.getStyleAt(Integer.parseInt(cellStyleString));
} else if(stylesTable.getNumCellStyles() > 0) {
style = stylesTable.getStyleAt(0);
}
if(style != null) {
cell.setNumericFormatIndex(style.getDataFormat());
String formatString = style.getDataFormatString();
if(formatString != null) {
cell.setNumericFormat(formatString);
} else {
cell.setNumericFormat(BuiltinFormats.getBuiltinFormat(cell.getNumericFormatIndex()));
}
} else {
cell.setNumericFormatIndex(null);
cell.setNumericFormat(null);
}
}
/**
* Tries to format the contents of the last contents appropriately based on
* the type of cell and the discovered numeric format.
*
* #return
*/
String formattedContents() {
switch(currentCell.getType()) {
case "s": //string stored in shared table
int idx = Integer.parseInt(lastContents);
return new XSSFRichTextString(sst.getEntryAt(idx)).toString();
case "inlineStr": //inline string (not in sst)
return new XSSFRichTextString(lastContents).toString();
case "str": //forumla type
return '"' + lastContents + '"';
case "e": //error type
return "ERROR: " + lastContents;
case "n": //numeric type
if(currentCell.getNumericFormat() != null && lastContents.length() > 0) {
return dataFormatter.formatRawCellContents(
Double.parseDouble(lastContents),
currentCell.getNumericFormatIndex(),
currentCell.getNumericFormat());
} else {
return lastContents;
}
default:
return lastContents;
}
}
/**
* Returns the contents of the cell, with no formatting applied
*
* #return
*/
String unformattedContents() {
switch(currentCell.getType()) {
case "s": //string stored in shared table
int idx = Integer.parseInt(lastContents);
return new XSSFRichTextString(sst.getEntryAt(idx)).toString();
case "inlineStr": //inline string (not in sst)
return new XSSFRichTextString(lastContents).toString();
default:
return lastContents;
}
}
/**
* Returns a new streaming iterator to loop through rows. This iterator is not
* guaranteed to have all rows in memory, and any particular iteration may
* trigger a load from disk to read in new data.
*
* #return the streaming iterator
*/
#Override
public Iterator<Row> iterator() {
return new StreamingIterator();
}
/**
* Closes the streaming resource, attempting to clean up any temporary files created.
*
* #throws com.monitorjbl.xlsx.exceptions.CloseException if there is an issue closing the stream
*/
#Override
public void close() {
try {
parser.close();
} catch(XMLStreamException e) {
throw new CloseException(e);
}
if(tmp != null) {
log.debug("Deleting tmp file [" + tmp.getAbsolutePath() + "]");
tmp.delete();
}
}
static File writeInputStreamToFile(InputStream is, int bufferSize) throws IOException {
File f = Files.createTempFile("tmp-", ".xlsx").toFile();
try(FileOutputStream fos = new FileOutputStream(f)) {
int read;
byte[] bytes = new byte[bufferSize];
while((read = is.read(bytes)) != -1) {
fos.write(bytes, 0, read);
}
is.close();
fos.close();
return f;
}
}
public static Builder builder() {
return new Builder();
}
public static class Builder {
int rowCacheSize = 10;
int bufferSize = 1024;
int sheetIndex = 0;
String sheetName;
String password;
/**
* The number of rows to keep in memory at any given point.
* <p>
* Defaults to 10
* </p>
*
* #param rowCacheSize number of rows
* #return reference to current {#code Builder}
*/
public Builder rowCacheSize(int rowCacheSize) {
this.rowCacheSize = rowCacheSize;
return this;
}
/**
* The number of bytes to read into memory from the input
* resource.
* <p>
* Defaults to 1024
* </p>
*
* #param bufferSize buffer size in bytes
* #return reference to current {#code Builder}
*/
public Builder bufferSize(int bufferSize) {
this.bufferSize = bufferSize;
return this;
}
/**
* Which sheet to open. There can only be one sheet open
* for a single instance of {#code StreamingReader}. If
* more sheets need to be read, a new instance must be
* created.
* <p>
* Defaults to 0
* </p>
*
* #param sheetIndex index of sheet
* #return reference to current {#code Builder}
*/
public Builder sheetIndex(int sheetIndex) {
this.sheetIndex = sheetIndex;
return this;
}
/**
* Which sheet to open. There can only be one sheet open
* for a single instance of {#code StreamingReader}. If
* more sheets need to be read, a new instance must be
* created.
*
* #param sheetName name of sheet
* #return reference to current {#code Builder}
*/
public Builder sheetName(String sheetName) {
this.sheetName = sheetName;
return this;
}
/**
* For password protected files specify password to open file.
* If the password is incorrect a {#code ReadException} is thrown on
* {#code read}.
* <p>NULL indicates that no password should be used, this is the
* default value.</p>
*
* #param password to use when opening file
* #return reference to current {#code Builder}
*/
public Builder password(String password) {
this.password = password;
return this;
}
/**
* Reads a given {#code InputStream} and returns a new
* instance of {#code StreamingReader}. Due to Apache POI
* limitations, a temporary file must be written in order
* to create a streaming iterator. This process will use
* the same buffer size as specified in {#link #bufferSize(int)}.
*
* #param is input stream to read in
* #return built streaming reader instance
* #throws com.monitorjbl.xlsx.exceptions.ReadException if there is an issue reading the stream
*/
public StreamingReader read(InputStream is) {
File f = null;
try {
f = writeInputStreamToFile(is, bufferSize);
log.debug("Created temp file [" + f.getAbsolutePath() + "]");
StreamingReader r = read(f);
r.tmp = f;
return r;
} catch(IOException e) {
throw new ReadException("Unable to read input stream", e);
} catch(RuntimeException e) {
f.delete();
throw e;
}
}
/**
* Reads a given {#code File} and returns a new instance
* of {#code StreamingReader}.
*
* #param f file to read in
* #return built streaming reader instance
* #throws com.monitorjbl.xlsx.exceptions.OpenException if there is an issue opening the file
* #throws com.monitorjbl.xlsx.exceptions.ReadException if there is an issue reading the file
*/
public StreamingReader read(File f) {
try {
OPCPackage pkg;
if(password != null) {
// Based on: https://poi.apache.org/encryption.html
POIFSFileSystem poifs = new POIFSFileSystem(f);
EncryptionInfo info = new EncryptionInfo(poifs);
Decryptor d = Decryptor.getInstance(info);
d.verifyPassword(password);
pkg = OPCPackage.open(d.getDataStream(poifs));
} else {
pkg = OPCPackage.open(f);
}
XSSFReader reader = new XSSFReader(pkg);
SharedStringsTable sst = reader.getSharedStringsTable();
StylesTable styles = reader.getStylesTable();
InputStream sheet = findSheet(reader);
if(sheet == null) {
throw new MissingSheetException("Unable to find sheet at index [" + sheetIndex + "]");
}
XMLEventReader parser = XMLInputFactory.newInstance().createXMLEventReader(sheet);
return new StreamingReader(sst, styles, parser, rowCacheSize);
} catch(IOException e) {
throw new OpenException("Failed to open file", e);
} catch(OpenXML4JException | XMLStreamException e) {
throw new ReadException("Unable to read workbook", e);
} catch(GeneralSecurityException e) {
throw new ReadException("Unable to read workbook - Decryption failed", e);
}
}
InputStream findSheet(XSSFReader reader) throws IOException, InvalidFormatException {
int index = sheetIndex;
if(sheetName != null) {
index = -1;
//This file is separate from the worksheet data, and should be fairly small
NodeList nl = searchForNodeList(document(reader.getWorkbookData()), "/workbook/sheets/sheet");
for(int i = 0; i < nl.getLength(); i++) {
if(Objects.equals(nl.item(i).getAttributes().getNamedItem("name").getTextContent(), sheetName)) {
index = i;
}
}
if(index < 0) {
return null;
}
}
Iterator<InputStream> iter = reader.getSheetsData();
InputStream sheet = null;
int i = 0;
while(iter.hasNext()) {
InputStream is = iter.next();
if(i++ == index) {
sheet = is;
log.debug("Found sheet at index [" + sheetIndex + "]");
break;
}
}
return sheet;
}
}
class StreamingIterator implements Iterator<Row> {
public StreamingIterator() {
if(rowCacheIterator == null) {
hasNext();
}
}
#Override
public boolean hasNext() {
return (rowCacheIterator != null && rowCacheIterator.hasNext()) || getRow();
}
#Override
public Row next() {
return rowCacheIterator.next();
}
#Override
public void remove() {
throw new RuntimeException("NotSupported");
}
}
}
and here is the code I use in my java service: (it's basically what the library provides in their page as documentation)
File is = new File("E:\\bpc\\testdata01.xlsm"));
StreamingReader reader = StreamingReader.builder()
.rowCacheSize(100)
.bufferSize(4096)
.sheetName("SOURCE_1")
.read(is);
so when the StreamingReader calls read(is) function I get the below exception thrown:
java.lang.reflect.InvocationTargetException:Could not initialize class org.apache.poi.POIXMLTypeLoader
I'm really sure why is it happening like this... is it because the builder class in the source code is static and it's being called from my static java service?
Note: Please be noted that I'm running this software AG webmethods and it's has its own way of implementing a java service so the only place that I can put my code in is like this: (you cannot debug the java service)
public final class importInputFile_SVC
{
public static final void importInputFile(IData pipeline)
throws ServiceException {
//code goes here
}
}
Any help is highly appreciated.
Not enough information for really analyzing your problem. But try putting all libraries in your package's code/jars directory and enable the package classloader in the manifest.v3 file. This will ensure that your java service uses only your specific libs and not jars on other version which may be part of your wM installation.
Edit: Enable the package classloader in the manifest.v3 file by adding the following line:
<value name='classloader'>package</value>

How can I store a String with escape characters without turning the escape characters into their substitutes?

I'm writing a Java-based program that downloads a JavaScript file from GitHub, parses it into a String, and then pushes it to a MediaWiki site. The problem is that the JS file has fairly complicated regex in it, and Java is parsing it into escape characters (e.g. [^\S\r\n] getting parsed into /\s). Is there a way I can store a String without these escape characters being activated?
EDIT: The code:
package org.wikipedia.afchbuddy;
import java.io.IOException;
import static java.lang.System.*;
import java.nio.file.*;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.nio.channels.*;
import java.net.URL;
import java.io.FileOutputStream;
import javax.security.auth.login.LoginException;
/**
* This is a bot script designed to allow sysops to push releases for AFCH
* on-wiki.
*
* #author Nathan2055
*/
public class AFCHBuddy {
private static String username;
private static String password;
private static String location;
private static String buffer;
private static String error = "An error occured trying to access and write to Wikipedia. If you report this error, please provide the following debug info:";
private static String basescript = "https://raw.github.com/WPAFC/afch/develop/src/";
private static String basescript_stable = "https://raw.github.com/WPAFC/afch/master/src/";
private static String mediawikilocation = "MediaWiki:Gadget-afchelper.js";
/**
* The main bot script.
*
* #param args This program accepts three command line arguments, 0 is the
* push location (stable, beta, or testwiki), 1 is your username, and 2 is
* your password.
*/
public static void main(String[] args) {
if (args.length != 3) {
err.println("Incorrect number of arguments. Please see the README for more information.");
System.exit(1);
}
location = args[0];
username = args[1];
password = args[2];
switch (location) {
case "testwiki":
build("testwiki");
break;
case "beta":
build("beta");
break;
case "stable":
build("stable");
break;
default:
err.println("Error: Unknown build location.");
System.exit(1);
}
}
/**
* This method does the actual work of performing the edits.
*
* #param destarg The destination wiki.
*/
private static void build(String destarg) {
Wiki wiki;
try {
if ("testwiki".equals(destarg)) {
wiki = new Wiki("test.wikipedia.org");
} else {
wiki = new Wiki();
}
wiki.login(username, password);
downloadFile(basescript + "MediaWiki:Gadget-afchelper.js", "afch.js");
buffer = readFile("afch.js");
wiki.edit(mediawikilocation, buffer, "Update afch.js using AFCHBuddy");
downloadFile(basescript + "MediaWiki:Gadget-afchelper.css", "afch.css");
buffer = readFile("afch.css");
wiki.edit("MediaWiki:Gadget-afchelper.css", buffer, "Update afch.css using AFCHBuddy");
downloadFile(basescript + "core.js", "core.js");
buffer = readFile("core.js");
wiki.edit(mediawikilocation + "/core.js", buffer, "Update core.js using AFCHBuddy");
downloadFile(basescript + "redirects.js", "redirects.js");
buffer = readFile("redirects.js");
wiki.edit(mediawikilocation + "/redirects.js", buffer, "Update redirects.js using AFCHBuddy");
downloadFile(basescript + "submissions.js", "submissions.js");
buffer = readFile("submissions.js");
wiki.edit(mediawikilocation + "/submissions.js", buffer, "Update submissions.js using AFCHBuddy");
downloadFile(basescript + "ffu.js", "ffu.js");
buffer = readFile("ffu.js");
wiki.edit(mediawikilocation + "/ffu.js", buffer, "Update ffu.js using AFCHBuddy");
wiki.logout();
err.println("Files syncronized successfully.");
System.exit(0);
} catch (IOException | LoginException e) {
err.println(error);
e.printStackTrace(err);
System.exit(1);
}
}
/**
* Converts a file to a String.
*
* #param path This accepts the path of the file to be processed in String
* form.
* #return The output String.
* #throws IOException The exception if something goes wrong while reading
* the file.
*/
private static String readFile(String path) throws IOException {
byte[] encoded = Files.readAllBytes(Paths.get(path));
return Charset.defaultCharset().decode(ByteBuffer.wrap(encoded)).toString();
}
/**
* This downloads the input URL and saves it to dest.
*
* #param URL The file's location on the internet.
* #param dest The file's soon to be location on your computer.
* #throws IOException The exception if something goes wrong while
* processing.
*/
private static void downloadFile(String URL, String dest) throws IOException {
URL website = new URL(URL);
ReadableByteChannel rbc = Channels.newChannel(website.openStream());
FileOutputStream fos = new FileOutputStream(dest);
fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
}
}

FTP Upload in JAVA

I want to use FTP to upload a file with a Java application, but it's not working.
The problem is that if I do the FTPUploader class in my main class, it works perfectly, but if I do like it's in here, it doesn't work. Can you guys help me out?
My code is:
Main Thread:
package restrictedareamanager;
import java.io.File;
import java.io.IOException;
public class RestrictedAreaManager {
File path = new File ("C:\\Área Restrita");
File lista[] = path.listFiles();
public void processa () throws IOException {
String titulo, subtitulo, nomeArq, aux;
for (File s : this.lista) {
aux = s.getName();
//String work
titulo = aux.substring (0, aux.indexOf ("-"));
aux = aux.substring (aux.indexOf ("-")+1);
subtitulo = aux.substring (0, aux.indexOf ("-"));
aux = aux.substring (aux.indexOf ("-")+1);
nomeArq = aux.substring (0);
//Create new file to be copied
final File dest = new File (path + "\\" + nomeArq);
//Copy File
FileCopier copiador = new FileCopier();
copiador.copiaArquivo(s, dest);
//Send file via FTP
FTPUploader ftp = new FTPUploader("**********", "********", "*********", titulo, subtitulo, dest);
ftp.execute();
}
}
public static void main(String[] args) throws IOException {
RestrictedAreaManager ram = new RestrictedAreaManager();
ram.processa();
}
}
FTPUploader class:
package restrictedareamanager;
import java.awt.HeadlessException;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import javax.swing.JOptionPane;
import javax.swing.SwingWorker;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPReply;
public class FTPUploader extends SwingWorker <Object,Object> {
private String servidor;
private String usuario;
private String senha;
private String titulo;
private String subtitulo;
private File dest;
public FTPUploader (String servidor, String usuario, String senha, String titulo, String subtitulo, File dest) {
this.servidor = servidor;
this.usuario = usuario;
this.senha = senha;
this.titulo = titulo;
this.subtitulo = subtitulo;
this.dest = dest;
}
#Override
protected Object doInBackground() throws Exception {
FTPClient ftp = new FTPClient ();
try {
ftp.connect("servidor");
//verifica se conectou com sucesso!
if( FTPReply.isPositiveCompletion( ftp.getReplyCode() ) ) {
ftp.login ("usuario", "senha");
} else {
//erro ao se conectar
ftp.disconnect();
JOptionPane.showMessageDialog(null, "Ocorreu um erro ao se conectar com o servidor FTP", "Erro", JOptionPane.ERROR_MESSAGE);
System.exit(1);
}
ftp.setFileType(FTPClient.BINARY_FILE_TYPE);
ftp.changeWorkingDirectory("/download");
ftp.changeWorkingDirectory(this.titulo);
ftp.changeWorkingDirectory (this.subtitulo);
ftp.storeFile (dest.getName(), new FileInputStream (dest.getPath().toString()));
System.out.println ("Done");
ftp.logout();
ftp.disconnect();
} catch( IOException | HeadlessException e ) {
JOptionPane.showMessageDialog(null, "Ocorreu um erro ao enviar o arquivo.", "Erro", JOptionPane.ERROR_MESSAGE);
System.exit(1);
}
return null;
}
}
You may want to check into JSch library - it handles all the ugliness of FTP and sFTP connection in java.
http://www.jcraft.com/jsch/
Here's a sample implementation (from live production code):
package com.somecompany.productfeed;
import net.snakedoc.jutils.ConfigException;
import org.apache.log4j.Logger;
import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.SftpException;
public class SFTP {
// setup logger
private static final Logger LOG = Logger.getLogger(SFTP.class.getName());
private JSch jsch;
private ChannelSftp sftpChannel;
private Session session;
private String username;
private String password;
private String host;
private int port;
// singleton
private volatile static SFTP instance = null;
/**
* Private constructor used in Singleton pattern.
* All variables populated via properties file upon
* object instantiation. Since we only need FTP to one server,
* object variables are immutable after instantiation.
*
* #throws ConfigException
* #throws NumberFormatException
*/
private SFTP() throws ConfigException, NumberFormatException {
this.jsch = new JSch();
this.username = Config.getInstance().getConfig("SFTP_USER");
this.password = Config.getInstance().getConfig("SFTP_PASS");
this.host = Config.getInstance().getConfig("SFTP_HOST");
this.port = Integer.parseInt(Config.getInstance().getConfig("SFTP_PORT"));
}
/**
* Create or Return SFTP Object using Singleton pattern.
*
* #return Singleton of SFTP Object.
* #throws NumberFormatException
* #throws ConfigException
*/
public static SFTP getInstance() throws NumberFormatException, ConfigException {
if (SFTP.instance == null) {
synchronized (SFTP.class) {
if (SFTP.instance == null) {
SFTP.instance = new SFTP();
}
}
}
return SFTP.instance;
}
/**
* If connection is not already open/connected, open connection.
*
* #throws JSchException
*/
public void openConnection() throws JSchException {
LOG.info("Opening SFTP Connection");
if (null == getSession() || ! getSession().isConnected()) {
setSession(jsch.getSession(this.username, this.host, this.port));
getSession().setConfig("StrictHostKeyChecking", "no");
getSession().setPassword(this.password);
getSession().connect();
Channel channel = getSession().openChannel("sftp");
channel.connect();
setSftpChannel((ChannelSftp) channel);
} else {
LOG.info("SFTP Connection already open");
}
LOG.debug("Success");
}
/**
* Closes connection.
*/
public void closeConnection() {
LOG.info("Closing SFTP connection");
getSftpChannel().exit();
getSession().disconnect();
LOG.debug("SFTP Connection closed");
}
/**
* Checks if SFTP Connection is open.
*
* #return TRUE if connection is open, FALSE if connection is closed
*/
public boolean isOpen() {
if (getSession().isConnected()) {
return true;
} else {
return false;
}
}
/**
* Gets SFTP Channel
*
* #return SFTP Channel (<code>ChannelSftp</code>)
*/
private ChannelSftp getSftpChannel() {
return this.sftpChannel;
}
/**
* Returns current <code>Session</code>
*
* #return <code>Session</code>
*/
private Session getSession() {
return this.session;
}
/**
* Sets SFTP Channel (<code>ChannelSftp</code>)
*
* #param sftpChannel Channel to set this object's <code>ChannelSftp</code>
*/
private void setSftpChannel(ChannelSftp sftpChannel) {
this.sftpChannel = sftpChannel;
}
/**
* Sets current <code>Session</code>
*
* #param session Sets this object's <code>Session</code>
*/
private void setSession(Session session) {
this.session = session;
}
/**
* Pushes local file to remote location
*
* #param local String representation of filepath + filename (ex: /some_local_directory/somefile.txt)
* #param remote String representation of filepath + filename (ex: /some_remote_directory/somefile.txt)
* #throws SftpException
*/
public void push(String local, String remote) throws SftpException {
LOG.info("Sending file: " + local + " to remote: " + remote);
getSftpChannel().put(local, remote);
LOG.debug("Success");
}
/**
* Gets remote file to local location
*
* #param remote String representation of filepath + filename (ex: /some_remote_directory/somefile.txt)
* #param local String representation of filepath + filename (ex: /some_local_directory/somefile.txt)
* #throws SftpException
*/
public void get(String remote, String local) throws SftpException {
LOG.info("Retrieving file: " + remote + " saving to: " + local);
getSftpChannel().get(remote, local);
LOG.debug("Success");
}
}

Receving data form using HttpURLConnection.getOutputStream,chinese encoding wrong(The same code,why the result is not the same?)

everybody:
I try to make a httpRequest for getting data,there's something wrong while response contain chinese characters.I got a String with HttpURLConnection.getInputStream()(see /test code./),I have wrote a main method on my local environment to test this code.And it works well!But when I startup my project,using this code for requesting data,the problem came out...(from the system.out below we can see the chinese characters are wrong )I don't understand why it cant be translate into write encoding.
And when I copy (/test code./) to static main method and run it,it seems no any problem,right?The same code,why the result is not the same?
my computer environment : win7,project and tomcat all use utf-8,request and response encoding both utf-8,too.
Here's my code:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.Map;
import java.util.Vector;
public class HttpRequestUtil {
private String defaultContentEncoding;
public HttpRequestUtil() {
this.defaultContentEncoding = Charset.defaultCharset().name();
}
public HttpRequestUtil(String encoding) {
this.defaultContentEncoding = encoding;
}
/**
* 发送GET请求
*
* #param urlString
* URL地址
* #return 响应对象
* #throws IOException
*/
public HttpResponsUtil sendGet(String urlString) throws IOException {
return this.send(urlString, "GET", null, null);
}
/**
* 发送GET请求
*
* #param urlString
* URL地址
* #param params
* 参数集合
* #return 响应对象
* #throws IOException
*/
public HttpResponsUtil sendGet(String urlString, Map<String, String> params)
throws IOException {
return this.send(urlString, "GET", params, null);
}
/**
* 发送GET请求
*
* #param urlString
* URL地址
* #param params
* 参数集合
* #param propertys
* 请求属性
* #return 响应对象
* #throws IOException
*/
public HttpResponsUtil sendGet(String urlString, Map<String, String> params,
Map<String, String> propertys) throws IOException {
return this.send(urlString, "GET", params, propertys);
}
/**
* 发送POST请求
*
* #param urlString
* URL地址
* #return 响应对象
* #throws IOException
*/
public HttpResponsUtil sendPost(String urlString) throws IOException {
return this.send(urlString, "POST", null, null);
}
/**
* 发送POST请求
*
* #param urlString
* URL地址
* #param params
* 参数集合
* #return 响应对象
* #throws IOException
*/
public HttpResponsUtil sendPost(String urlString, Map<String, String> params)
throws IOException {
return this.send(urlString, "POST", params, null);
}
/**
* 发送POST请求
*
* #param urlString
* URL地址
* #param params
* 参数集合
* #param propertys
* 请求属性
* #return 响应对象
* #throws IOException
*/
public HttpResponsUtil sendPost(String urlString, Map<String, String> params,
Map<String, String> propertys) throws IOException {
return this.send(urlString, "POST", params, propertys);
}
/**
* 发送HTTP请求
*
* #param urlString
* #return 响映对象
* #throws IOException
*/
private HttpResponsUtil send(String urlString, String method,
Map<String, String> parameters, Map<String, String> propertys)
throws IOException {
HttpURLConnection urlConnection = null;
if (method.equalsIgnoreCase("GET") && parameters != null) {
StringBuffer param = new StringBuffer();
int i = 0;
for (String key : parameters.keySet()) {
if (i == 0)
param.append("?");
else
param.append("&");
param.append(key).append("=").append(parameters.get(key));
i++;
}
urlString += param;
}
URL url = new URL(urlString);
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod(method);
urlConnection.setDoOutput(true);
urlConnection.setDoInput(true);
urlConnection.setUseCaches(false);
if (propertys != null)
for (String key : propertys.keySet()) {
urlConnection.addRequestProperty(key, propertys.get(key));
}
if (method.equalsIgnoreCase("POST") && parameters != null) {
StringBuffer param = new StringBuffer();
for (String key : parameters.keySet()) {
param.append("&");
param.append(key).append("=").append(parameters.get(key));
}
urlConnection.getOutputStream().write(param.toString().getBytes());
urlConnection.getOutputStream().flush();
urlConnection.getOutputStream().close();
}
return this.makeContent(urlString, urlConnection);
}
/**
* 得到响应对象
*
* #param urlConnection
* #return 响应对象
* #throws IOException
*/
private HttpResponsUtil makeContent(String urlString,
HttpURLConnection urlConnection) throws IOException {
HttpResponsUtil httpResponser = new HttpResponsUtil();
try {
InputStream in = urlConnection.getInputStream();
//这里如果不指定InputStreamReader的编码,当中文字符超过两个时就会出现乱码(utf8情况下)
BufferedReader bufferedReader = new BufferedReader(
new InputStreamReader(in, this.defaultContentEncoding));
httpResponser.contentCollection = new Vector<String>();
StringBuffer temp = new StringBuffer();
String line = bufferedReader.readLine();
while (line != null) {
httpResponser.contentCollection.add(line);
temp.append(line); //.append("\r\n")
line = bufferedReader.readLine();
}
bufferedReader.close();
String ecod = urlConnection.getContentEncoding();
if (ecod == null){
ecod = this.defaultContentEncoding;
httpResponser.content = temp.toString();
/*test code.*/
System.out.println("ecod is" + ecod);
//ecod isUTF-8
System.out.println("temp = " + temp.toString());
//temp = {"tags":[{"r_id":3553740735078269,"tag":"再测试"},{"r_id":3555331928010955,"tag":"再测试"},{"r_id":3555332033148401,"tag":"再测试,测试好多个字符串"}],"rids":"3555332033148401,3555331928010955,3553740735078269,3553509628288136,3552801450193593,3550638895838037,3550607615227068,3550334377352366,3550333965816322,3550315184067715,3550136490112256,3550098295918936,3550094449884887,3550094122996559,3550092986220398,3550090717120421,3550090532251655,3550089362475695,3549897523877864,3549756045751486,3549719639064459,3549564726035910,3549379539997223,3549377979585685,3549373109656624","idArr":["3555332033148401","3555331928010955","3553740735078269","3553509628288136","3552801450193593","3550638895838037","3550607615227068","3550334377352366","3550333965816322","3550315184067715","3550136490112256","3550098295918936","3550094449884887","3550094122996559","3550092986220398","3550090717120421","3550090532251655","3550089362475695","3549897523877864","3549756045751486","3549719639064459","3549564726035910","3549379539997223","3549377979585685","3549373109656624"],"uId":1916364215,"type":3}
System.out.println("temp after encode: "+new String(temp.toString().getBytes(), ecod));
//temp after encode: {"tags":[{"r_id":3553740735078269,"tag":"?????"},{"r_id":3555331928010955,"tag":"?????"},{"r_id":3555332033148401,"tag":"?????,??????????"}],"rids":"3555332033148401,3555331928010955,3553740735078269,3553509628288136,3552801450193593,3550638895838037,3550607615227068,3550334377352366,3550333965816322,3550315184067715,3550136490112256,3550098295918936,3550094449884887,3550094122996559,3550092986220398,3550090717120421,3550090532251655,3550089362475695,3549897523877864,3549756045751486,3549719639064459,3549564726035910,3549379539997223,3549377979585685,3549373109656624","idArr":["3555332033148401","3555331928010955","3553740735078269","3553509628288136","3552801450193593","3550638895838037","3550607615227068","3550334377352366","3550333965816322","3550315184067715","3550136490112256","3550098295918936","3550094449884887","3550094122996559","3550092986220398","3550090717120421","3550090532251655","3550089362475695","3549897523877864","3549756045751486","3549719639064459","3549564726035910","3549379539997223","3549377979585685","3549373109656624"],"uId":1916364215,"type":3}
String str = "{\"tags\":[{\"r_id\":3553740735078269,\"tag\":\"再测试\"},{\"r_id\":3555331928010955,\"tag\":\"再测试\"},{\"r_id\":3555332033148401,\"tag\":\"再测试,测试好多个字符串\"}],\"rids\":\"3555332033148401,3555331928010955,3553740735078269,3553509628288136,3552801450193593,3550638895838037,3550607615227068,3550334377352366,3550333965816322,3550315184067715,3550136490112256,3550098295918936,3550094449884887,3550094122996559,3550092986220398,3550090717120421,3550090532251655,3550089362475695,3549897523877864,3549756045751486,3549719639064459,3549564726035910,3549379539997223,3549377979585685,3549373109656624\",\"idArr\":[\"3555332033148401\",\"3555331928010955\",\"3553740735078269\",\"3553509628288136\",\"3552801450193593\",\"3550638895838037\",\"3550607615227068\",\"3550334377352366\",\"3550333965816322\",\"3550315184067715\",\"3550136490112256\",\"3550098295918936\",\"3550094449884887\",\"3550094122996559\",\"3550092986220398\",\"3550090717120421\",\"3550090532251655\",\"3550089362475695\",\"3549897523877864\",\"3549756045751486\",\"3549719639064459\",\"3549564726035910\",\"3549379539997223\",\"3549377979585685\",\"3549373109656624\"],\"uId\":1916364215,\"type\":3}";
System.out.println("compare two string:" + temp.toString().equals(str));
//compare two string:true
StringBuffer sb = new StringBuffer();
sb.append(str);
String s = new String(sb.toString().getBytes(), "UTF-8");
System.out.println("s test:" + s);
//s test:{"tags":[{"r_id":3553740735078269,"tag":"?????"},{"r_id":3555331928010955,"tag":"?????"},{"r_id":3555332033148401,"tag":"?????,??????????"}],"rids":"3555332033148401,3555331928010955,3553740735078269,3553509628288136,3552801450193593,3550638895838037,3550607615227068,3550334377352366,3550333965816322,3550315184067715,3550136490112256,3550098295918936,3550094449884887,3550094122996559,3550092986220398,3550090717120421,3550090532251655,3550089362475695,3549897523877864,3549756045751486,3549719639064459,3549564726035910,3549379539997223,3549377979585685,3549373109656624","idArr":["3555332033148401","3555331928010955","3553740735078269","3553509628288136","3552801450193593","3550638895838037","3550607615227068","3550334377352366","3550333965816322","3550315184067715","3550136490112256","3550098295918936","3550094449884887","3550094122996559","3550092986220398","3550090717120421","3550090532251655","3550089362475695","3549897523877864","3549756045751486","3549719639064459","3549564726035910","3549379539997223","3549377979585685","3549373109656624"],"uId":1916364215,"type":3}
/*test code.*/
} else{
httpResponser.content = new String(temp.toString().getBytes(), ecod);
}
httpResponser.urlString = urlString;
httpResponser.defaultPort = urlConnection.getURL().getDefaultPort();
httpResponser.file = urlConnection.getURL().getFile();
httpResponser.host = urlConnection.getURL().getHost();
httpResponser.path = urlConnection.getURL().getPath();
httpResponser.port = urlConnection.getURL().getPort();
httpResponser.protocol = urlConnection.getURL().getProtocol();
httpResponser.query = urlConnection.getURL().getQuery();
httpResponser.ref = urlConnection.getURL().getRef();
httpResponser.userInfo = urlConnection.getURL().getUserInfo();
httpResponser.contentEncoding = ecod;
httpResponser.code = urlConnection.getResponseCode();
httpResponser.message = urlConnection.getResponseMessage();
httpResponser.contentType = urlConnection.getContentType();
httpResponser.method = urlConnection.getRequestMethod();
httpResponser.connectTimeout = urlConnection.getConnectTimeout();
httpResponser.readTimeout = urlConnection.getReadTimeout();
return httpResponser;
} catch (IOException e) {
throw e;
} finally {
if (urlConnection != null)
urlConnection.disconnect();
}
}
/**
* 默认的响应字符集
*/
public String getDefaultContentEncoding() {
return this.defaultContentEncoding;
}
/**
* 设置默认的响应字符集
*/
public void setDefaultContentEncoding(String defaultContentEncoding) {
this.defaultContentEncoding = defaultContentEncoding;
}
public static void main(String[] args) throws Exception {
String str = "{\"tags\":[{\"r_id\":3553740735078269,\"tag\":\"再测试\"},{\"r_id\":3555331928010955,\"tag\":\"再测试\"},{\"r_id\":3555332033148401,\"tag\":\"再测试,测试好多个字符串\"}],\"rids\":\"3555332033148401,3555331928010955,3553740735078269,3553509628288136,3552801450193593,3550638895838037,3550607615227068,3550334377352366,3550333965816322,3550315184067715,3550136490112256,3550098295918936,3550094449884887,3550094122996559,3550092986220398,3550090717120421,3550090532251655,3550089362475695,3549897523877864,3549756045751486,3549719639064459,3549564726035910,3549379539997223,3549377979585685,3549373109656624\",\"idArr\":[\"3555332033148401\",\"3555331928010955\",\"3553740735078269\",\"3553509628288136\",\"3552801450193593\",\"3550638895838037\",\"3550607615227068\",\"3550334377352366\",\"3550333965816322\",\"3550315184067715\",\"3550136490112256\",\"3550098295918936\",\"3550094449884887\",\"3550094122996559\",\"3550092986220398\",\"3550090717120421\",\"3550090532251655\",\"3550089362475695\",\"3549897523877864\",\"3549756045751486\",\"3549719639064459\",\"3549564726035910\",\"3549379539997223\",\"3549377979585685\",\"3549373109656624\"],\"uId\":1916364215,\"type\":3}";
StringBuffer sb = new StringBuffer();
sb.append(str);
String s = new String(sb.toString().getBytes(), "UTF-8");
System.out.println("s test:" + s);
//s test:{"tags":[{"r_id":3553740735078269,"tag":"再测试"},{"r_id":3555331928010955,"tag":"再测试"},{"r_id":3555332033148401,"tag":"再测试,测试好多个字符串"}],"rids":"3555332033148401,3555331928010955,3553740735078269,3553509628288136,3552801450193593,3550638895838037,3550607615227068,3550334377352366,3550333965816322,3550315184067715,3550136490112256,3550098295918936,3550094449884887,3550094122996559,3550092986220398,3550090717120421,3550090532251655,3550089362475695,3549897523877864,3549756045751486,3549719639064459,3549564726035910,3549379539997223,3549377979585685,3549373109656624","idArr":["3555332033148401","3555331928010955","3553740735078269","3553509628288136","3552801450193593","3550638895838037","3550607615227068","3550334377352366","3550333965816322","3550315184067715","3550136490112256","3550098295918936","3550094449884887","3550094122996559","3550092986220398","3550090717120421","3550090532251655","3550089362475695","3549897523877864","3549756045751486","3549719639064459","3549564726035910","3549379539997223","3549377979585685","3549373109656624"],"uId":1916364215,"type":3}
}
}
I have find out the solution,use the code below:
httpResponser.content = new String(temp.toString().getBytes(this.defaultContentEncoding), ecod);

How to send PDF file from backend Java code?

I have a JSP file, there backend helper class to it. From the back end helper I need to send PDF file to the JSP as an attachment. How can I achieve that?
I would suggest you to use Apache Commons File Upload component. That's probably the best way rather than reinventing the wheel. ;)
Since you haven't told us if you're using any MVC framework or just plain Servlet, I'll go for the basics.
If you want to upload a file, Apache Commons File Upload is the best library that will translate your multipart/form-data encoded HttpServletRequest message and provide you with files uploaded (in InputStream format, mostly preferred).
It's up to you, the developer, to write the data back to a persistent storage of your choice.
The reverse, it's to take the file, get the appropriate MIME-Type, Content-Length (file size), and file data (InputStream, if possible) and render it back to the HttpServletResponse).
This code (fully functional and written by me) does put the file as attachment/inline.
import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.Closeable;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;
/**
* #author Buhake Sindi (The Elite Gentleman)
* #since 01 September 2011
*/
public class FileServletRenderer implements ServletRenderer {
private static final int DEFAULT_BUFFER_SIZE = 10240; // 10KB
private static final String OCTECT_STREAM_MIME_TYPE = "application/octect-stream";
private String contentType = OCTECT_STREAM_MIME_TYPE;
private long contentLength;
private String contentDisposition = "inline";
private String fileName;
private InputStream inputStream;
/**
* #return the contentType
*/
public String getContentType() {
return contentType;
}
/**
* #param contentType
* the contentType to set
*/
public void setContentType(String contentType) {
this.contentType = contentType;
}
/**
* #return the contentLength
*/
public long getContentLength() {
return contentLength;
}
/**
* #param contentLength
* the contentLength to set
*/
public void setContentLength(long contentLength) {
this.contentLength = contentLength;
}
/**
* #return the contentDisposition
*/
public String getContentDisposition() {
return contentDisposition;
}
/**
* #param contentDisposition
* the contentDisposition to set
*/
public void setContentDisposition(String contentDisposition) {
this.contentDisposition = contentDisposition;
}
/**
* #return the fileName
*/
public String getFileName() {
return fileName;
}
/**
* #param fileName
* the fileName to set
*/
public void setFileName(String fileName) {
this.fileName = fileName;
}
/**
* #return the inputStream
*/
public InputStream getInputStream() {
return inputStream;
}
/**
* #param inputStream
* the inputStream to set
*/
public void setInputStream(InputStream inputStream) {
this.inputStream = inputStream;
}
public void setFile(File file) throws IOException {
if (file == null) {
throw new IOException("file is null.");
}
setInputStream(new BufferedInputStream(new FileInputStream(file)));
setContentLength(file.length());
}
/*
* (non-Javadoc)
*
* #see org.bfs.bayweb.util.renderer.ServletViewRenderer#render(javax.servlet.
* ServletRequest, javax.servlet.ServletResponse)
*/
public void render(ServletRequest request, ServletResponse response) throws IOException {
// TODO Auto-generated method stub
BufferedOutputStream bos = new BufferedOutputStream(response.getOutputStream());
try {
byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
int inputStreamLength = 0;
int length = 0;
if (contentType == null) {
contentType = request.getServletContext().getMimeType(getFileName());
}
//We couldn't determine Content-Type
if (contentType == null) {
contentType = OCTECT_STREAM_MIME_TYPE;
}
while ((length = getInputStream().read(buffer)) > 0) {
inputStreamLength += length;
bos.write(buffer, 0, length);
}
if (inputStreamLength != getContentLength()) {
setContentLength(inputStreamLength);
}
if (response instanceof HttpServletResponse) {
HttpServletResponse httpResponse = (HttpServletResponse) response;
httpResponse.reset();
httpResponse.setHeader("Content-Type", getContentType());
httpResponse.setHeader("Content-Length", String.valueOf(getContentLength()));
httpResponse.setHeader("Content-Disposition", "\"" + getContentDisposition() + "\""
+ ((getFileName() != null && !getFileName().isEmpty()) ? "; filename=\"" + getFileName() + "\"" : ""));
httpResponse.setHeader("Content-Type", getContentType());
}
// finally
bos.flush();
// clear
} finally {
// TODO Auto-generated catch block
close(bos);
close(getInputStream());
}
}
private void close(Closeable resource) throws IOException {
if (resource != null) {
resource.close();
}
}
}
The most important method is render(HttpServletRequest, HttpServletResponse).

Categories