I'm trying to implement the Basic example for the GwtUpload library, as found here.
In my server code, I get the following error:
Exception java.lang.ClassCastException: org.apache.commons.fileupload.disk.DiskFileItem cannot be cast to org.apache.commons.fileupload.FileItem
I can't figure out why this is happening. DiskFileItem is a subclass of FileItem and should work. I've stepped through in the debugger and confirmed that the two classes are what they appear to be, yet the assignment fails.
Even more strangely, when I attempt to call the FileItem methods in the watch window, I have no problems, but if I attempt to access them in the code, I get the error.
Here is my Servlet code:
public class GwtUploadServlet extends UploadAction
{
private static final long serialVersionUID = 1L;
/**
* Maintain a list with received files and their content types.
*/
Hashtable<String, String> receivedContentTypes = new Hashtable<String, String>();
/**
* Maintain a list with received files.
*/
Hashtable<String, File> receivedFiles = new Hashtable<String, File>();
/**
* Override executeAction to save the received files in a custom place and
* delete this items from session.
*/
#Override
public String executeAction(HttpServletRequest request,
List<FileItem> sessionFiles) throws UploadActionException
{
String response = "";
int cont = 0;
for ( int i = 0 ; i < sessionFiles.size(); i++ )
{
if (false == sessionFiles.get(i).isFormField())
{
cont++;
try
{
// / Create a temporary file placed in the default system
// temp folder
File file = File.createTempFile("upload-", ".bin");
sessionFiles.get(i).write(file);
// / Save a list with the received files
receivedFiles.put(sessionFiles.get(i).getFieldName(), file);
receivedContentTypes.put(sessionFiles.get(i).getFieldName(),
sessionFiles.get(i).getContentType());
// / Send a customized message to the client.
response += "File saved as " + file.getAbsolutePath();
}
catch (Exception e)
{
throw new UploadActionException(e);
}
}
}
// / Remove files from session because we have a copy of them
removeSessionFileItems(request);
// / Send your customized message to the client.
return response;
}
/**
* Get the content of an uploaded file.
*/
#Override
public void getUploadedFile(HttpServletRequest request,
HttpServletResponse response) throws IOException
{
String fieldName = request.getParameter(PARAM_SHOW);
File f = receivedFiles.get(fieldName);
if (f != null)
{
response.setContentType(receivedContentTypes.get(fieldName));
FileInputStream is = new FileInputStream(f);
copyFromInputStreamToOutputStream(is, response.getOutputStream());
}
else
{
renderXmlResponse(request, response, ERROR_ITEM_NOT_FOUND);
}
}
/**
* Remove a file when the user sends a delete request.
*/
#Override
public void removeItem(HttpServletRequest request, String fieldName)
throws UploadActionException
{
File file = receivedFiles.get(fieldName);
receivedFiles.remove(fieldName);
receivedContentTypes.remove(fieldName);
if (file != null)
{
file.delete();
}
}
}
Make sure you don't have multiple versions of commons-fileupload on the classpath.
Related
I'm working on a web app (Java/JSP) and part of it, is to allow users to download the requested file only "Once". The problem that when they hit "Download" button, they will be asked to save/open or cancel the file and whatever they respond the file will be marked as downloaded and the user won't be able to download it again.
I'm trying to figure out a way to not count the file as downloaded when the user respond with "Cancel" and to check if really the user downloaded the file completely.
Here is the Java Part:
#WebServlet("/download")
public class download extends HttpServlet {
private static final long serialVersionUID = 1L;
private static final int DEFAULT_BUFFER_SIZE = 10240;
/**
* #see HttpServlet#HttpServlet()
*/
public download() {
super();
// TODO Auto-generated constructor stub
}
/**
* #see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
* response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
try {
Class.forName("org.sqlite.JDBC");
Connection c = DriverManager.getConnection("jdbc:sqlite:C:\\sqlite\\mascapp.db");
c.setAutoCommit(false);
Cookie[] cookies = request.getCookies();
if(request.getSession().getAttribute("aeid") == null || request.getSession().getAttribute("uid") == null)
{
response.sendRedirect("/index.jsp");
}
int ae_num = Integer.parseInt(request.getSession().getAttribute("aeid").toString());
String sql = "SELECT file, filename FROM reports INNER JOIN download USING(tipid) WHERE reports.tipid = ?"+
"AND download.ts_" + ae_num+ " = 0;";
PreparedStatement stmt = c.prepareStatement(sql);
String tipNum = request.getParameter("tipid");
if (tipNum != null) {
stmt.setString(1, tipNum);
//stmt.setString(2, tipNum);
ResultSet res = stmt.executeQuery();
BufferedInputStream fileBlob = null;
String filename = "";
while (res.next()) {
fileBlob = new BufferedInputStream(res.getBinaryStream("file"), DEFAULT_BUFFER_SIZE);
filename = res.getString("filename");
}
if (fileBlob != null) {
System.out.println(filename);
response.setContentType("APPLICATION/OCTET-STREAM");
response.setHeader("Content-Disposition", "attachment; filename=\"" + filename + "\"");
BufferedOutputStream output = new BufferedOutputStream(response.getOutputStream(),
DEFAULT_BUFFER_SIZE);
byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
int length;
while ((length = fileBlob.read(buffer)) > 0) {
output.write(buffer, 0, length);
}
output.close();
fileBlob.close();
Date now = new Date();
sql = "UPDATE download SET ts_" + ae_num + " = " + now.getTime() + " WHERE tipid = ?;";
System.out.println(sql);
stmt = c.prepareStatement(sql);
stmt.setString(1, tipNum);
stmt.executeUpdate();
stmt.close();
c.commit();
c.close();
}
else
{
c.close();
response.sendRedirect("/MASC/formdownloaded.jsp");
}
}
else
{
response.getWriter().append("<html><body><h1>Error: no param</h1></body></html>");
c.close();
}
} catch (SQLException | ClassNotFoundException e) {
e.printStackTrace();
}
}
/**
* #see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
* response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
Any solution or suggestion?! Thank you in advance.
Check this page: http://johnculviner.com/jquery-file-download-plugin-for-ajax-like-feature-rich-file-downloads/ (this link doesn't work sometimes, if you have some problems with it here is a link to github: https://github.com/johnculviner/jquery.fileDownload ).
It looks like the best you can do here is to make sure that download was started by checking on client side special cookie sent back from server with downloading file stream. For that you have to add Cookie into servlet response like in this thread:
Set cookie only after file download complete.
So at the end of doGet method in your servlet you should have something like:
Cookie fileDwnld = new Cookie("fileDownload", "true");
fileDwnld.setPath("/");
response.addCookie(fileDwnld);
And here is client side code:
<script src="http://code.jquery.com/jquery-2.1.4.min.js"></script>
<script src="jquery.fileDownload.js"></script>
<script>
$(document).ready(function() {
$("#btnSubmit").click(function(){
$.fileDownload('path/to/servlet')
.done(function () { alert('File download a success!'); })
.fail(function () { alert('File download failed!'); });
});
});
The answer is don't do that. Those dialogs are there for good reasons, some of them involving security.
What you want to do instead depends on why you only want the user to download the file once. Downloads can fail for all sorts of reasons, so what are you going to do if the user loses their connection in the middle of the download?
I don't have a proper answer, but I do know that the "attachment;" in the header forces the browser to "download" the file, compared to "open it", if you understand what I mean. Try removing that header and see if you get the desired effect.
I hava a java swing application and would like to use auto update using AppLoader.java class that i found online at
**https://reportmill.wordpress.com/2014/12/04/automatically-update-your-javapackager-applications/
**
has anybody had any experience with this class. i can not seem to implement this class with my application and am getting errors:
java.io.FileNotFoundException: C:\Users\home\Documents\NetBeansProjects\test_update\build\classes (Access is denied)
and
java.lang.RuntimeException: Main Jar not found!
yep, the code seems not working. I did some modification for the code to make it work. please do as follows:
download the file through http://reportmill.com/snap1/SnapCode1.jar.pack.gz
copy this file to C:\Users\home\Documents\NetBeansProjects\test_update\build\classes
copy and paste the code below and give it a run
import java.io.;
import java.lang.reflect.Method;
import java.net.;
import java.text.;
import java.util.jar.;
import javax.swing.*;
import java.util.zip .GZIPInputStream;
/**
* This app
*/
public class AppLoader {
// Constants
static final String AppDirName = "SnapCode";
static final String JarName = "SnapCode1.jar";
static final String JarURL = "http://reportmill.com/snap1/SnapCode1.jar.pack.gz";
static final String MainClass = "snap.app.App";
/**
* Main method - reinvokes main1() on Swing thread in exception handler.
*/
public static void main(final String args[]) {
// Invoke real main with exception handler
try {
main1(args);
} catch (Throwable e) {
JOptionPane.showMessageDialog(null, e.toString());
e.printStackTrace();
}
}
/**
* Main method: - Gets main Jar file from default, if missing - Updates main
* Jar file from local update file, if previously loaded - Load main Jar
* into URLClassLoader, load main class and invoke main method - Check for
* update from remove site in background
*/
public static void main1(final String args[]) throws Exception {
// Make sure default jar is in place
try {
copyDefaultMainJar();
} catch (Exception e) {
JOptionPane.showMessageDialog(null, e.toString());
e.printStackTrace();
}
// If Update Jar exists, copy it into place
File jar = getAppFile(JarName);
File updateJar = getAppFile(JarName + ".update");
if (updateJar.exists()) {
copyFile(updateJar, jar);
jar.setLastModified(updateJar.lastModified());
updateJar.delete();
}
// If jar doesn't exist complain bitterly
if (!jar.exists() || !jar.canRead())
throw new RuntimeException("Main Jar not found!");
// Check for updates in background thread
if (args.length == 0 || !args[0].equals("-snap"))
new Thread(new Runnable() {
public void run() {
checkForUpdatesSilent();
}
}).start();
// Create URLClassLoader for main jar file, get App class and invoke
// main
// URLClassLoader ucl = new URLClassLoader(
// new URL[] { jar.toURI().toURL() });
// Class cls = ucl.loadClass(MainClass); // ucl.close();
// Method meth = cls.getMethod("main", new Class[] { String[].class });
// meth.invoke(null, new Object[] { args });
// if (cls == Object.class)
// ((Closeable) ucl).close(); // Getting rid of warning message for ucl
}
/**
* Copies the default main jar into place for initial run.
*/
private static void copyDefaultMainJar() throws IOException, ParseException {
// Get main jar from app package and get location of working jar file
URL url = AppLoader.class.getProtectionDomain().getCodeSource()
.getLocation();
String path0 = url.getPath();
path0 = URLDecoder.decode(path0, "UTF-8");
path0 = path0 + "SnapCode1.jar.pack.gz" ;
File jar0 = getAppFile(JarName);
File jar1 = new File(path0);
// If app package main jar is newer, copy it into place and set time
if (jar0.exists() && jar0.lastModified() >= jar1.lastModified())
return;
copyFile(jar1, jar0);
}
/**
* Check for updates.
*/
private static void checkForUpdatesSilent() {
try {
checkForUpdates();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* Check for updates.
*/
private static void checkForUpdates() throws IOException,
MalformedURLException {
// Get URL connection and lastModified time
File jarFile = getAppFile(JarName);
URL url = new URL(JarURL);
URLConnection connection = url.openConnection();
long mod0 = jarFile.lastModified(), mod1 = connection.getLastModified();
if (mod0 >= mod1) {
System.out.println("No update available at " + JarURL + '(' + mod0
+ '>' + mod1 + ')');
return;
}
// Get update file and write to JarName.update
System.out.println("Loading update from " + JarURL);
byte bytes[] = getBytes(connection);
System.out.println("Update loaded");
File updatePacked = getAppFile(JarName + ".pack.gz"), updateFile = getAppFile(JarName
+ ".update");
writeBytes(updatePacked, bytes);
System.out.println("Update saved: " + updatePacked);
unpack(updatePacked, updateFile);
System.out.println("Update unpacked: " + updateFile);
updateFile.setLastModified(mod1);
updatePacked.delete();
// Let the user know
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JOptionPane
.showMessageDialog(null,
"A new update is available. Restart application to apply");
}
});
}
/**
* Returns the Main jar file.
*/
private static File getAppFile(String aName) {
return new File(getAppDir(), aName);
}
/**
* Returns the Main jar file.
*/
private static File getAppDir() {
return getAppDataDir(AppDirName, true);
}
/**
*
* Utility Methods for AppLoader.
*
*/
/**
* Copies a file from one location to another.
*/
public static File copyFile(File aSource, File aDest) throws IOException {
// Get input stream, output file and output stream
FileInputStream fis = new FileInputStream(aSource);
File out = aDest.isDirectory() ? new File(aDest, aSource.getName())
: aDest;
FileOutputStream fos = new FileOutputStream(out);
// Iterate over read/write until all bytes written
byte[] buf = new byte[8192];
for (int i = fis.read(buf); i != -1; i = fis.read(buf))
fos.write(buf, 0, i);
// Close in/out streams and return out file
fis.close();
fos.close();
return out;
}
/**
* Writes the given bytes (within the specified range) to the given file.
*/
public static void writeBytes(File aFile, byte theBytes[])
throws IOException {
if (theBytes == null) {
aFile.delete();
return;
}
FileOutputStream fileStream = new FileOutputStream(aFile);
fileStream.write(theBytes);
fileStream.close();
}
/**
* Unpacks the given file into the destination file.
*/
public static File unpack(File aFile, File aDestFile) throws IOException {
// Get dest file - if already unpacked, return
File destFile = getUnpackDestination(aFile, aDestFile);
if (destFile.exists() && destFile.lastModified() > aFile.lastModified())
return destFile;
// Create streams: FileInputStream -> GZIPInputStream -> JarOutputStream
// -> FileOutputStream
FileInputStream fileInput = new FileInputStream(aFile);
GZIPInputStream gzipInput = new GZIPInputStream(fileInput);
FileOutputStream fileOut = new FileOutputStream(destFile);
JarOutputStream jarOut = new JarOutputStream(fileOut);
// Unpack file
Pack200.newUnpacker().unpack(gzipInput, jarOut);
// Close streams
fileInput.close();
gzipInput.close();
jarOut.close();
fileOut.close();
// Return destination file
return destFile;
}
/**
* Returns the file that given packed file would be saved to using the
* unpack method.
*/
public static File getUnpackDestination(File aFile, File aDestFile) {
// Get dest file - if null, create from packed file minus .pack.gz
File destFile = aDestFile;
if (destFile == null)
destFile = new File(aFile.getPath().replace(".pack.gz", ""));
// If dest file is directory, change to file inside with packed file
// minus .pack.gz
else if (destFile.isDirectory())
destFile = new File(destFile, aFile.getName().replace(".pack.gz",
""));
// Return destination file
return destFile;
}
/**
* Returns the AppData or Application Support directory file.
*/
public static File getAppDataDir(String aName, boolean doCreate) {
// Get user home + AppDataDir (platform specific) + name (if provided)
String dir = System.getProperty("user.home");
if (isWindows)
dir += File.separator + "AppData" + File.separator + "Local";
else if (isMac)
dir += File.separator + "Library" + File.separator
+ "Application Support";
if (aName != null)
dir += File.separator + aName;
// Create file, actual directory (if requested) and return
File dfile = new File(dir);
if (doCreate && aName != null)
dfile.mkdirs();
return dfile;
}
/**
* Returns bytes for connection.
*/
public static byte[] getBytes(URLConnection aConnection) throws IOException {
InputStream stream = aConnection.getInputStream(); // Get stream for
// connection
byte bytes[] = getBytes(stream); // Get bytes for stream
stream.close(); // Close stream
return bytes; // Return bytes
}
/**
* Returns bytes for an input stream.
*/
public static byte[] getBytes(InputStream aStream) throws IOException {
ByteArrayOutputStream bs = new ByteArrayOutputStream();
byte chunk[] = new byte[8192];
for (int len = aStream.read(chunk, 0, 8192); len > 0; len = aStream
.read(chunk, 0, 8192))
bs.write(chunk, 0, len);
return bs.toByteArray();
}
// Whether Windows/Mac
static boolean isWindows = (System.getProperty("os.name")
.indexOf("Windows") >= 0);
static boolean isMac = (System.getProperty("os.name").indexOf("Mac OS X") >= 0);
}
Your problem is that in your copyFile method FileInputStream takes a wrong File object
I want to upload a file to an existing Google Drive folder.
I am using this how to upload an image from my android app to a specific folder on google drive to get the folder name but not sure how to implement it (smokybob's answer)
//Search by name and type folder
String qStr = "mimeType = 'application/vnd.google-apps.folder' and title = 'myFolder'";
//Get the list of Folders
FileList fList=service.files().list().setQ(qStr).execute();
//Check that the result is one folder
File folder;
if (fList.getItems().lenght==0){
folder=fList.getItems()[0];
}
//Create the insert request is as in the sample
File file = service.files().insert(body, mediaContent);
//set the parent
file.setParents(Arrays.asList(newParentReference().setId(folder.getFolderId())));
//execute the request
file.execute();
I am getting cannot resolve symbol errors for FileList, body, mediacontent.
I am getting cannot resolve method for .files, getitems(), setparents, newparentsreference, and execute.
Class:GetFile.java https://github.com/googledrive/android-demos/blob/master/src/com/google/android/gms/drive/sample/demo/CreateFileActivity.java
public class GetFile extends UploadDrive {
private static final String TAG = "CreateFileActivity";
#Override
public void onConnected(Bundle connectionHint) {
super.onConnected(connectionHint);
// create new contents resource
Drive.DriveApi.newDriveContents(getGoogleApiClient())
.setResultCallback(driveContentsCallback);
}
final private ResultCallback<DriveContentsResult> driveContentsCallback = new
ResultCallback<DriveContentsResult>() {
#Override
public void onResult(DriveContentsResult result) {
if (!result.getStatus().isSuccess()) {
showMessage("Error while trying to create new file contents");
return;
}
final DriveContents driveContents = result.getDriveContents();
// Perform I/O off the UI thread.
new Thread() {
#Override
public void run() {
// write content to DriveContents
OutputStream outputStream = driveContents.getOutputStream();
Writer writer = new OutputStreamWriter(outputStream);
try {
writer.write(MainActivity.driveText); //what is the problem?
writer.close();
} catch (IOException e) {
Log.e(TAG, e.getMessage());
}
MetadataChangeSet changeSet = new MetadataChangeSet.Builder()
.setTitle("New file")
.setMimeType("text/plain")
.setStarred(true).build();
// create a file on root folder
Drive.DriveApi.getRootFolder(getGoogleApiClient())
.createFile(getGoogleApiClient(), changeSet, driveContents)
.setResultCallback(fileCallback);
}
}.start();
}
};
final private ResultCallback<DriveFileResult> fileCallback = new
ResultCallback<DriveFileResult>() {
#Override
public void onResult(DriveFileResult result) {
if (!result.getStatus().isSuccess()) {
showMessage("Error while trying to create the file");
return;
}
showMessage("Created a file with content: " + result.getDriveFile().getDriveId());
}
};
}
When a folder is created under GDAA, it produces a DriveId.
/**************************************************************************
* create file/folder in GOODrive
* #param prnId parent's ID, (null or "root") for root
* #param titl file name
* #param mime file mime type
* #param file file (with content) to create (optional, if null, create folder)
* #return file id / null on fail
*/
static String create(String prnId, String titl, String mime, java.io.File file) {
DriveId dId = null;
if (mGAC != null && mGAC.isConnected() && titl != null) try {
DriveFolder pFldr = (prnId == null || prnId.equalsIgnoreCase("root")) ?
Drive.DriveApi.getRootFolder(mGAC):
Drive.DriveApi.getFolder(mGAC, DriveId.decodeFromString(prnId));
if (pFldr == null) return null; //----------------->>>
MetadataChangeSet meta;
if (file != null) { // create file
if (mime != null) { // file must have mime
DriveContentsResult r1 = Drive.DriveApi.newDriveContents(mGAC).await();
if (r1 == null || !r1.getStatus().isSuccess()) return null; //-------->>>
meta = new MetadataChangeSet.Builder().setTitle(titl).setMimeType(mime).build();
DriveFileResult r2 = pFldr.createFile(mGAC, meta, r1.getDriveContents()).await();
DriveFile dFil = r2 != null && r2.getStatus().isSuccess() ? r2.getDriveFile() : null;
if (dFil == null) return null; //---------->>>
r1 = dFil.open(mGAC, DriveFile.MODE_WRITE_ONLY, null).await();
if ((r1 != null) && (r1.getStatus().isSuccess())) try {
Status stts = file2Cont(r1.getDriveContents(), file).commit(mGAC, meta).await();
if ((stts != null) && stts.isSuccess()) {
MetadataResult r3 = dFil.getMetadata(mGAC).await();
if (r3 != null && r3.getStatus().isSuccess()) {
dId = r3.getMetadata().getDriveId();
}
}
} catch (Exception e) {
UT.le(e);
}
}
} else {
meta = new MetadataChangeSet.Builder().setTitle(titl).setMimeType(UT.MIME_FLDR).build();
DriveFolderResult r1 = pFldr.createFolder(mGAC, meta).await();
DriveFolder dFld = (r1 != null) && r1.getStatus().isSuccess() ? r1.getDriveFolder() : null;
if (dFld != null) {
MetadataResult r2 = dFld.getMetadata(mGAC).await();
if ((r2 != null) && r2.getStatus().isSuccess()) {
dId = r2.getMetadata().getDriveId();
}
}
}
} catch (Exception e) { UT.le(e); }
return dId == null ? null : dId.encodeToString();
}
(must be run on non-UI thread)
This ID is used in subsequent calls as a "parent ID". If you have questions about unresolved methods, please refer to this GitHub project. BTW (as I mentioned before), it does everything you're trying to accomplish (creates folders, creates text files, reads contents back, deletes files/folders, ...)
Good Luck
I'm using jsp and a servlet to do this.
I have a contact form that send a email with some data (name, subject, question,contact email etc) and a file.
when I submit the form, and get the servlet response only the first thing is returned.
String file= fileUpload(request); //upload the client's file and return the absolute path of the file in the server
//testing the rest of parameters
out.println("REQUEST LIST"
"\n" request.getParameter("name")
"\n" request.getParameter("mail")
"\n" request.getParameter("subject")
"\n" request.getParameter("ask")
"\n");
In this order the file is uploaded succesfully, but the other parameters (name, mail etc) are null.
In the order below, the parameters are ok, they return the data correctly. But the file is not uploaded.
//testing the rest of parameters
out.println("REQUEST LIST"
"\n" request.getParameter("name")
"\n" request.getParameter("mail")
"\n" request.getParameter("subject")
"\n" request.getParameter("ask")
"\n");
String file= fileUpload(request); //upload the client's file and return the absolute path of the file in the server
How can I have both?
Thanks!
You should extract the request parameters using the same API (e.g. Apache Commons FileUpload) as you've extracted the uploaded file. This is usually not interchangeable with calling getParameter() as the request body can be parsed only once (the enduser ain't going to send the same request twice, one to be parsed by the file upload parsing API and other to be parsed by getParameter()).
See also:
How to upload files to server using JSP/Servlet?
Look if the following code helps you. This is just an example. You may have to tweak it
Create a class called FileUploader which returns ServletFileUpload object
public class FileUploader
{
private static ServletFileUpload uploader;
private FileUploader()
{
}
public static synchronized ServletFileUpload getservletFileUploader(String tempDir, int maxSizeInMB)
{
if(uploader == null)
{
DiskFileItemFactory factory = new DiskFileItemFactory();
factory.setSizeThreshold(1024 * 1024);
factory.setRepository(new File(tempDir));
uploader = new ServletFileUpload(factory);
uploader.setFileSizeMax(maxSizeInMB * 1024 * 1024);
}
return uploader;
}
}
Now you can process a request and read all the data
protected MultiPartFormData handleMultiPartRequest(HttpServletRequest request)
throws FileSizeLimitExceededException
{
if(!isMultipartRequest(request))
return null;
ServletFileUpload upload = FileUploader.getservletFileUploader(tempDir, 50);
MultiPartFormData data = new MultiPartFormData();
try
{
List<FileItem> items = upload.parseRequest(request);
for (FileItem item : items)
{
if(item.isFormField())
{
data.getParameters().put(item.getFieldName(), item.getString());
}
else
{
String filename = item.getName();
//Internet explorer and firefox will send the file name differently
//Internet explorer will send the entire path to the file name including
//the backslash characters etc ... we should strip it down
//THIS IS HACKY
if(filename.indexOf("\\") != -1)
{
int index = filename.lastIndexOf("\\");
filename = filename.substring(index + 1);
}
if(filename == null || filename.equals(""))
{
//do nothing
}
else
{
File uploadFile = new File(uploadDir + File.separator + randomFileName);
item.write(uploadFile);
data.addFile(item.getFieldname(), item.getString());
}
}
}
}
catch(FileSizeLimitExceededException e)
{
throw e;
}
catch(Exception e)
{
e.printStackTrace();
}
return data;
}
After parsing the request I am storing it in some object called MultipartFormData which can be used to get request parameters
public class MultiPartFormData {
private Hashtable<String, String> parameters;
private Hashtable<String, String> uploadedFiles;
public MultiPartFormData()
{
this.parameters = new Hashtable<String, String>();
this.uploadedFiles = new Hashtable<String, String>();
}
public Hashtable<String, String> getParameters() {
return parameters;
}
public void setParameters(Hashtable<String, String> parameters) {
this.parameters = parameters;
}
public void getParameter(String paramName) {
if(this.parameters.contains(paramName))
return tyhis.parameters.get(paramName);
return null;
}
public void addFile(String key, String filename) {
uploadedFile.put(key, filename);
}
public void getFilename(String key) {
uploadedFile.get(key);
}
}
I'm trying to post 2 fields, id and data, to a servlet using HttpClient.
The problem is that if the length of the data field is less than 1MB or so, the servlet will get what I posted. But if the length of the data field is larger than 1MB or so, the servlet will receive null for all fields. What am I missing here? Thanks.
Here's the sample data that I post to the servlet:
id=12312123123123
data=the content of a file that is base-64 encoded
Here's the method that I use to post data to the servlet.
private byte[] post(String aUrl,
Map<String,String> aParams,
String aCharsetEnc,
int aMaxWaitMs) throws Exception
{
PostMethod post = null;
try
{
HttpClient client = new HttpClient();
post = new PostMethod(aUrl);
post.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=" + aCharsetEnc);
for (String key : aParams.keySet())
{
post.addParameter(key, aParams.get(key));
}
final int code = client.executeMethod(post);
if (code == HttpStatus.SC_NO_CONTENT || code == HttpStatus.SC_NOT_FOUND)
{
return null;
}
else if (code != HttpStatus.SC_OK)
{
throw new HttpException("Error code " + code + " encountered.");
}
InputStream stream = post.getResponseBodyAsStream();
if (stream != null)
{
return BlobHelper.readBytes(stream);
}
return null;
}
finally
{
if (post != null)
{
post.releaseConnection();
}
}
}
Here's the method of the servlet.
public void doPost(HttpServletRequest aReq, HttpServletResponse aResp)
throws ServletException, IOException
{
setNoCache(aResp);
aResp.setContentType("text/plain");
try
{
final String id = aReq.getParameter(PARAM_ID);
final String dataStr = aReq.getParameter(PARAM_DATA);
if (log().isDebugEnabled())
{
log().debug("id=" + id);
log().debug("data=" + dataStr);
}
}
catch (Exception e)
{
}
}
Usually servlet containers have a maximum post size parameter.
For Tomcat you can follow the steps documented here(they should be similar for other appservers) -
Is there a max size for POST parameter content?