Java Servlet JSP delete file using apache commons FileUpload - java

I have been searching this topic for quite a while, and haven't found anything that has been able to solve my problem.. so I turn to you!
I have a JSP where I open a file dialog box to select a file. Previously, I used this to upload the file to a specified directory (in my code). This works fine. I am now trying to use the same code to delete that same file by selecting it in the appropriate directory and passing it off to the servlet, which I included below. I am using the Apache Common FileUpload library to do this.
protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
// checks if the request actually contains upload file
if (!ServletFileUpload.isMultipartContent(request)) {
// if not, we stop here
return;
}
// configures some settings
DiskFileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload delete = new ServletFileUpload(factory);
// constructs the directory path to delete file
String deletePath = UPLOAD_DIRECTORY;
// parses the request's content to extract file data
List formItems = delete.parseRequest(request);
Iterator iter = formItems.iterator();
// iterates over form's fields
while (iter.hasNext()) {
FileItem item = (FileItem) iter.next();
// processes only fields that are not form fields
if (!item.isFormField()) {
String fileName = new File(item.getName()).getName();
String filePath = deletePath + File.separator + fileName;
File storeFile = new File(filePath);
//File storeFile = new File("C:\\temp\\discLogo.txt");
// deletes the file on disk
boolean erased = storeFile.delete();
}
}
UPLOAD_DIRECTORY is where I am storing my files from my upload JSP. The delete method works fine if I uncomment the line I commented out for storeFile with the hardcoded directory, as long as I select a DIFFERENT FILE in the directory initially. This leads me to believe the HttpServletRequest is holding the file in memory somewhere.
Is this correct? is there any way I can release it so I can delete the file I select initially? Or is there a much simpler way to do this?
Thanks!

The File#delete() will return false if the file does not exist at all (use File#exists() to test it beforehand), or if the file is locked because it is been opened by another app or even your own code!
Provided that this file is written do disk beforehand by your own code and guaranteed not opened elsewhere, then you should ensure that you're invoking OutputStream#close() in the finally block after writing the file's content. This problem suggests that you didn't. If you leave the file open after writing to it, then it cannot be deleted until you restart the server/JVM.
Apache Commons IO, which you should already have as a dependency of FileUpload, comes with handy utility methods reducing the file copy and close boilerplate.
InputStream input = item.getInputStream();
OutputStream output = new FileOutputStream(storeFile);
try {
IOUtils.copy(input, output);
} finally {
IOUtils.closeQuietly(output);
IOUtils.closeQuietly(input);
}
See also:
How I save and retrieve an image on my server in a java webapp.

What is the object of uploading the file? Are you going to check all the files by content?
I would say the simpler way would be to not upload the whole file. What you want to do is to call some code - JSP/Servlet -, pass as a parameter an ID of the file (most usually the path inside the server) and make it delete the file. If all the files uploaded are in the same folder, then the name should be enough (*).
After all, by uploading the file you are forcing you to have a copy in your PC of the file you want to delete (what if you deleted your local file? Should you not be able to delete the file in the server?)
(*) be sure to perform safety checks so nobody can pass ..\..\WEB-INF\web.xml as a parameter.

you can delete the file because the platform indepenedent solution is like this
File deleteFile = new File(<file Path> ) ;
// check if the file present or not
if( deleteFile.exists() )
deleteFile.delete() ;
Be carefule if the file path is directory then the directory must empty before deleting.
UploadFileorDelete

Looks like my issue was in my JSP. I had the following form initially:
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>File Delete</title>
</head>
<body>
<form method="post" action="DeleteServlet"
enctype="multipart/form-data">
Select file to delete: <input type="file" name="dataFile"
id="fileChooser" /><br />
<br /> <input type="submit" value="Delete" />
</form>
</body>
</html>
I changed this by deleting encytype="multipart/form-data" from the form, and was then able to use request.getParameter("dataFile") to get the file name.

Related

Need to hide the files which are being used from Assets folder

I am using an offline application which has html,css and js files in the assets folder.When i install the application on a device a can access those files from file:////storage/emulated/0/Android/data/myapp.name/files. I need a way to hide these files at it causes a security issue. I load my app from UI webview through one of the files in assets folder
I need a way to hide these files at it causes a security issue
First, they are not files. They are assets. They are stored in the APK file, not as files on the filesystem.
Second, you cannot "hide" assets. They are in your APK, and anyone can take your APK and retrieve those assets. It is unlikely that anyone will bother to do this.
You wont be able to hide assets.
As a workaround, you can do the following:
Copy the content of your HTML, CSS and JS files in a long text String.
When app is loaded for the first time, load the string content and create a Private file at runtime and save it in Internal Storage.
Files written in Internal storage by an app can not be accessed by any other apps, including a file explorer. so they are safe from misuse.
use this code to store private file in internal storage:
String filename = "yourfile.html";
String string = "Hello world!";
FileOutputStream outputStream;
try {
outputStream = openFileOutput(filename, Context.MODE_PRIVATE);
outputStream.write(string.getBytes());
outputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
To protect assets folder information If the html file is either css or js, the easiest way is to:
Write your code in the html editor first, and then enter it in a Java class as follows :
public class Content{
public static final String myContent ="<!DOCTYPE html> ... </html> "
And then call through the loadDataWithBaseURL method
webView.loadDataWithBaseURL(null,Content.myContent, "text/html" , "UTF-8" ,null);
And you can call js and css in html code :
...
<head>
<link rel="stylesheet" type="text/css"
href="file:///android_asset/css/custom.css" />
<script src="file:///android_asset/js/code.jquery.js"></script>
</head>

How to upload Multiple files using play framework?

i am using play framework 2.1.2 using java and i am creating view to upload multiple files and my code is here :
#form(action = routes.upload.up, 'enctype -> "multipart/form-data") {
<input type="file" name="picture" accept="application/pdf" multiple="multiple"><br/>
<input type="submit" value="upload">
}
i want to upload only doc and pdf file.
how to restrict form to upload only doc and pdf file ?
i can this with java but i am looking for html code.
after this i want to store multiple file to permanent storage in my computer.
and print name of file i uploaded.
my code :
public static Result up(){
MultipartFormData md=request().body().asMultipartFormData();
List<FilePart>file;
file=md.getFiles();
for(FilePart p: file){
Logger.info(p.getFilename());
}
return ok(file.get(0).getFilename());
}
it is storing file into temp directory but i want to store to permanent location not on temp directory as a file not temp file like if i upload a.docx i want to store this file into storage with a.docx name.
i don't want to store file into database.
and how to list all file that i uploaded by file name?
i found some question but i am not getting that answers because that question is for old version.
give me some idea to fix this issue.
Here is how I implemented mine. I apologize if I made any mistakes somewhere. I "refactored" it so that it doesn't look anything like my production code.
In HTML I have:
<form name="fileUploadForm" method="POST" enctype="multipart/form-data" action="#routes.Application.upload()">
File 1: <br /> <input type="file" name="filePart1" id="filePart1"><br />
File 2: <br /> <input type="file" name="filePart2" id="filePart1"><br />
</form>
In my controller I have:
public static Result upload() {
MultipartFormData body = request().body().asMultipartFormData();
FilePart filePart1 = body.getFile("filePart1");
FilePart filePart2 = body.getFile("filePart2");
File newFile1 = new File("path in computer");
File newFile2 = new File("path in computer");
File file1 = filePart1.getFile();
File file2 = filePart2.getFile();
InputStream isFile1 = new FileInputStream(file1);
InputStream isFile2 = new FileInputStream(file2);
byte[] byteFile1 = IOUtils.toByteArray(isFile1);
byte[] byteFile2 = IOUtils.toByteArray(isFile2);
FileUtils.writeByteArrayToFile(newFile1, byteFile1);
FileUtils.writeByteArrayToFile(newFile2, byteFile2);
isFile1.close();
isFile2.close();
}
Just like Kris said, you will have to get Apache's CommonIO
You can easily do this buy adding this into your Build.scala found in /PlayProject/project:
import sbt._
import Keys._
import play.Project._
import com.typesafe.config._
object ApplicationBuild extends Build {
val appDependencies = Seq(
"commons-io" % "commons-io" % "2.4" //add this here
)
}
In this implementation, you can store the files anywhere on your computer where you specified in File newFile1. But you will have to use a database if you want to list your files. But you only have to store the file path as a String (varchar) in the database. I will leave that part up to you to figure out as I don't know how you want to handle file retrieval.
You can restrict user to only upload certain type of files by using Javascript. Have Javascript do form validation by checking the file name: Here is an example:
<script>
var file1 = document.getElementById("filePart1").value;
if (file1.indexOf(".pdf") == -1) {
alert("Not a PDF file!");
else {
document.fileUploadForm.submit();
}
</script>
Hope all of that helps.
To get your file somewhere else than temp location you would need to copy it, best using something like FileUtils from apache commons (http://commons.apache.org/proper/commons-io/apidocs/org/apache/commons/io/FileUtils.html)
As for the file names you can get it from MultipartFormData
First getFiles() method
Second getFile():File method
One way could be is to use a custom body parser that can take a specified directory and save the uploaded files there. But you have to add some Scala code to the project. Here is the gist:
https://gist.github.com/nraychaudhuri/6349808

Upload PDF to database and storage system (folder) in JSP

Just like title, I want to ask, how to adding pdf files with upload form to my storage folder (e.g: uploadData) then its added to database as a file too in JSP.
If it not possible, it's ok to added to database as a text.
If it possible as a file, what type of my table for that pdf? blob? or text?
I accept blog links/other links that relevant for my problem
sorry for bad english.
Servlet 3.0 container's has standard support for multipart data. It also has the support to write to local file system. First you should be writing a HTML page which takes the file input along with other input parameters.
<form action="uploadservlet" method="post" enctype="multipart/form-data">
<input type="text" name="name" />
<input type="text" name="age" />
<input type="file" name="photo" />
<input type="submit" />
</form>
Now write a UploadServlet which uses the Servlet 3.0 Upload API. Here is the code which demonstrates the usage of API. Fist the servlet handling multipart data should define MultiPartConfig using any of the two approaches:
#MultiPartConfig annotation on Servlet Class
In web.xml, by adding entry inside definition.
Here is the UploadServlet,
#MultipartConfig
public class UploadServlet extends HttpServlet
{
protected void service(HttpServletRequest request,
HttpServletResponse responst) throws ServletException, IOException
{
Collection<Part> parts = request.getParts();
if (parts.size() != 3) {
//can write error page saying all details are not entered
}
Part filePart = httpServletRequest.getPart("photo");
InputStream imageInputStream = filePart.getInputStream();
//read imageInputStream
filePart.write("somefiepath");
//can also write the photo to local storage
//Read Name, String Type
Part namePart = request.getPart("name");
if(namePart.getSize() > 20){
//write name cannot exceed 20 chars
}
//use nameInputStream if required
InputStream nameInputStream = namePart.getInputStream();
//name , String type can also obtained using Request parameter
String nameParameter = request.getParameter("name");
//Similialrly can read age properties
Part agePart = request.getPart("age");
int ageParameter = Integer.parseInt(request.getParameter("age"));
}
}
If you are not using Sevlet 3.0 Container, you should be truing Apache Commons File Upload. Here are the links for using Apache Commons File Upload:
Using Apache Commons File Upload
Apache Commons File Upload Example
References:
File Upload Using Servlet 3.0
Servlet 3.0 javax.servlet.http.HttpServletRequest API
Servlet 3.0 javax.servlet.http.Part API
Uploading File using Servlet 3.0
The easiest way I know of to handle file uploads is by using Commons FileUpload. The documentation gives you a step by step overview of how to accept uploaded files, including how to easily copy them into a file.
Should you decide to put the PDF in a database (I wouldn't do that), BLOB is your best choice, a PDF file isn't text.
I would however advise not to cram all that logic in a JSP but in a servlet instead.

Java SE HTML POST filename issue

I'm currently writing a program using nanoHTTPD to upload files to a server. Currently I can successfully upload the file with a preassigned name. However, I would like to maintain the original name of the file being uploaded.
How it uploads now:
Original filename: foo.jpg
Uploaded filename: file123.whatever
How I want it to upload:
Original file name: foo.jpg
Uploaded filename: foo.jpg
Here is the HTML being used:
<FORM ENCTYPE="multipart/form-data" ACTION="/uploaded.html" METHOD=POST>
Upload a file: <INPUT NAME="userfile1" TYPE="file">
<INPUT TYPE="submit" VALUE="Send File">
</FORM>
Here is the vanilla nanoHTTPD code for reference: http://pastebin.com/pMNS3VKf
Note: I would prefer to use Java SE and avoid Java EE.
Any advice would be welcomed, thank you.
Edit: in short all I need to learn how to do is get the filename from the HTML POST.
I'm not certain if your NanoHTTPD is the same as mine, but with mine you can retrieve the original filename by looking at the parms Parameters object for the same key that you retrieve the file from the files Parameters object.
Enumeration<Object> keys = files.keys()
while (keys.hasMoreElements())
{
String key = keys.nextElement().toString();
String origFileName = parms.getProperty(key);
String fsFileName = files.getProperty(key);
this.renameFile(fsFileName, origFileName);
}
Once you retrieve the filename, you can use whatever method you want to rename the file. (With proper checking. It could be a huge security hole if you completely trusted their original filename.)

How to display a dynamically-generated image (barcode) on a web page?

I have a barcode that I am dynamically generating, and want to pass to a gsp that will later become a pdf. I do not need to persist the barcode for any of my own purposes, and would like to simply pass the image from the controller to the gsp.
Is there a way to render an image that is passed as a variable rather than specifying a src?
Thanks in advance.
EDIT:
Since I am generating the pdf from the gsp, I am flushing the output stream of the response then, and therefore cannot do it with the image also, or I get an error.
Furthermore, using javascript/jQuery does not work since the page is never rendered directly by the browser.
It may look like the only option I have is to persist the images temporarily somewhere, and then delete them...
I answered a similar question recently, perhaps its answer will work for you. I'll paste a portion of it here. It's basically Oded's "outside of this..." suggestion.
class BarcodeController {
def index = {
def img // byte array, set this to the binary contents of your image
response.setHeader('Content-length', img.length)
response.contentType = 'image/png' // or the appropriate image content type
response.outputStream << img
response.outputStream.flush()
}
}
You could then access your image in the src of an tag like this:
<img src="${g.link(controller: 'barcode', action: 'index')}"/>
This answer seems to fit the last comment you made on the question (about a similar solution using PHP).
You can use a data URI scheme for the src attribute.
The data URI scheme is a URI scheme that provides a way to include data in-line in web pages as if they were external resources.
Here is an example from the wikipeida article:
<img src="data:image/png;base64,
iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAABGdBTUEAALGP
C/xhBQAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9YGARc5KB0XV+IA
AAAddEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIFRoZSBHSU1Q72QlbgAAAF1J
REFUGNO9zL0NglAAxPEfdLTs4BZM4DIO4C7OwQg2JoQ9LE1exdlYvBBeZ7jq
ch9//q1uH4TLzw4d6+ErXMMcXuHWxId3KOETnnXXV6MJpcq2MLaI97CER3N0
vr4MkhoXe0rZigAAAABJRU5ErkJggg==" alt="Red dot" />
Outside of this, if you are using a server side technology, you can stream the image data from a script (with the correct mime-type) and point the src attribute to it.
Here is a related SO question for grails.
Just want to contribute to this age-old question. I got this working by adding the following lines to BuildConfig.groovy:
In the plugins section:
plugins {
// other plugins here
// ...
compile ":barcode4j:0.3"
compile ":rendering:1.0.0"
}
In the dependencies section:
dependencies {
// other dependencies here
// ...
compile 'avalon-framework:avalon-framework:4.1.5'
}
Then I added a controller based on code examples I found on the net. I needed specifically a DataMatrix generator, but adding others should be easy just adding methods to the controller. Sorry for the bad quality code (I'm a Groovy newbie):
package myproject
import org.krysalis.barcode4j.impl.datamatrix.DataMatrix
import java.awt.Dimension
class BarcodeController {
// a valid PNG image, base64 encoded
static invalidBarcodeImgBase64 = """iVBORw0KGgoAA...=="""
// Needs index.gsp for testing
def index() {
['uuid': UUID.randomUUID(), 'fecha': new Date()]
}
def dataMatrix(String value) {
if ((null == value) || (value.length() < 1) || (value.length() > 2000)) {
def img = invalidBarcodeImgBase64.decodeBase64()
response.setHeader('Content-length', new Integer(img.length).toString())
response.contentType = 'image/png'
response.outputStream << img
response.outputStream.flush()
} else {
def generator = new DataMatrix()
generator.dataMatrixBean.setMinSize(new Dimension(16, 16))
renderBarcodePng(generator, value, [antiAlias: false])
}
}
def datamatrix(String value) {
dataMatrix(value)
}
}
Finally here's index.gsp in the barcode view for testing:
<%# page contentType="text/html;charset=UTF-8" %>
<html>
<head>
<title>DataMatrix</title>
</head>
<body>
<g:img dir="barcode" file="dataMatrix?value=${uuid}"/>
<br />
<br />
<g:img dir="barcode" file="dataMatrix?value=${fecha}"/>
<br />
<br />
<g:img dir="barcode" file="dataMatrix?value=Nothing to see here"/>
</body>
</html>

Categories

Resources