My setup is like this,
Users enters values in a JSP page. In the same page I've given an option to upload a file.
When users click on Save button at the end, it redirects to a servlet and the values including the file gets uploaded into DB (I'm using SQL Server)
If users do not upload any file and click on save, the query to update in the servlet is updating with '0x' for the File(ProgressFile in DB) column. But I don't want to update DB when there's no file selected to upload.
In My JSP, <INPUT NAME="file" TYPE="file">
In My Servlet,
InputStream inputStream = null;
Part filePart = request.getPart("file");
String File = filePart.getSubmittedFileName();
if (filePart != null) {
// obtains input stream of the upload file
inputStream = filePart.getInputStream();
}
String query = "Update helpData SET ProgressFile = ?, ProgressFileName = ? where ID='"+ID+"'";
pstmt = conn.prepareStatement(query);
pstmt.setString(2, File);
//method to insert a stream of bytes
pstmt.setBlob(1, inputStream );
int row = pstmt.executeUpdate();
if (row > 0) {
System.out.println( "File uploaded and saved into database");
}
How to not to update the DB when there is no file selected for upload?
Thanks in advance..
Related
A web app, the client side is jsp and backend is JAVA, DB is simple sqlite.
In the DB there is a table that contains "files" called Reports, and users are allowed to download each file in the DB only ONCE "Due to security requirements", and I have been trying to find a way to do that.
Is there anyway I can write a jsp code that allows the users to download the requested file once from the DB?
I don't know if it is useful but this is the JAVA piece of code that is used to download from the DB.
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();
The current problem I'm having is that whenever a user is trying to download the requested file and whether the user chose to open/save or cancel, it will be counted as a downloaded file, even with a cancel.
Any ideas? Would using cookies in JSP help to implement that? If so can someone guide me? Or how to solve the download count issue
If you have control over the database, you could possibly have another table with the user_id, file_id, download_status column. That way you could always have the records who downloaded the file.
I have written this to upload an image in the specified folder and store the path in database, but when i click on add a blank page is displayed, I have already created all the folders in webcontent.I am using tomcat server:
My upload.jsp code looks something like this:
<form action="Add" method=post enctype="multipart/form-data">
<p>Book name: <input type="text" name="bname" required/></p>
<p>Price:<input type="text" name="bprice" required/></p>
<p>Quantity:<input type="text" name="bqty" required/></p>
<p>Image: <input type="file" name="file" required/></p>
<p>Course: <select name="course">
<option>course 1</option>
<option>course 2</option> <!-- Some more options-->
<input type="submit" value="Add" name="Submit"/></p>
</form>
The Add.java servlet code is:
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter out=response.getWriter();
String bname=request.getParameter("bname");
String bprice=request.getParameter("bprice");
String bqty=request.getParameter("bqty");
String path="images";
String file=request.getParameter("file");
String course=request.getParameter("course");
if(course.equals("course 1"))
{
path="images/folder1";
}
else if(course.equals("course 2"))
{
path="images/folder2";
}
else
{
path="images";
}
MultipartRequest m=new MultipartRequest(request,path);
try
{
Class.forName("com.mysql.jdbc.Driver");
Connection con=DriverManager.getConnection("",user,pass);
PreparedStatement ps=con.prepareStatement("insert into product(bname,course,price,qty,path) values (?,?,?,?,?)");
ps.setString(1,bname);
ps.setString(2,course);
ps.setString(3,bprice);
ps.setString(4,bqty);
ps.setString(5,path+file);
ps.executeUpdate();
}
catch(Exception e)
{
e.printStackTrace();
}
out.print("<p>Product added!</p>");
RequestDispatcher rd=request.getRequestDispatcher("upload.jsp");
rd.include(request, response);
}
I get NullPointer exception.
I read somewhere that instead of using
request.getParameter()
I shoud use
m.getParameter()
I did that and it worked, But that won't solve my problem because my code determines the path based on the value of course from the form.
And also I need to get the filename of the file uploaded, right now I am doing this like this:
String file=request.getParameter("file");
I was trying some sample code and when I used m.getParameter() I managed to get values of all fields except file(I want that coz i want to store the img path in the DB).
When I don't use enctype=multipart/form-data everything works fine (I also get the filename) except the error that content is multipart(That's obvious I know).
ServletRequest#getParameter works only for application/x-www-form-urlencoded data (this encoding is used by default if you don't specify enctype attribute on your form). You can read more information about form content types here.
From the line
MultipartRequest m=new MultipartRequest(request,path);
I am assuming you are using the com.oreilly.servlet library.
In this case, using MultipartRequest#getParameter is a correct way to get the values of fields. In order to get the name of the uploaded file, you can use MultipartRequest#getFilesystemName.
my code determines the path based on the value of course from the form
I am afraid that you won't be able to do this in a clear way with com.oreilly.servlet library. What you could do is move the file by yourself like this:
m.getFile("file").renameTo(new File("newPath"));
Alternatively, you can consider using some other library for dealing with multipart data, such as Apache Commons FileUpload.
You can get both the form fields and the file using cos-multipart.jar.
The following worked for me:
public class FileUploadHandler extends HttpServlet {
private final String UPLOAD_DIRECTORY = "/home/mario/Downloads";
#Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//fix max file size 500 Mb
int maxFileSize = 500000 * 1024;
int maxMemSize = maxFileSize;
//getting form fields (both text as well as file) (enctype=multipart/form-data)
MultipartRequest mreq = new MultipartRequest(request, UPLOAD_DIRECTORY, maxFileSize);
String uname = mreq.getParameter("username"); //give 'id' in html accordingly
String dateofupload = mreq.getParameter("uploaddate");
//System.out.println(uname);
String NEW_UPLOAD_DIRECTORY = UPLOAD_DIRECTORY;
//get actual file name here //name field in html tag has to be given accordingly
String uploadedfilename = mreq.getFilesystemName("file");
//renaming & moving the file to new location
File newfileloc = new File(NEW_UPLOAD_DIRECTORY + "/" + uploadedfilename);
Boolean uploadresult = mreq.getFile("file").renameTo(newfileloc); //true if success
}
}
This initially saves the file to a location and rename/move it to new location. I could have saved it at the desired location but to do that I need file name, which comes only with the servlet request. But to access filename we need to create 'Multipart' request object. I tried to create two such things, one to access fields and the other to save file. But, cos-multipart.jar has some bugs in handling this.
You might want to consider using Apache commons FileUpload. It helps you handle these kinds of scenarios and handles most of the business logic for you.
When using Apache Commons FileUpload you can parse the request like this:
// Create a factory for disk-based file items
DiskFileItemFactory factory = new DiskFileItemFactory();
// Configure a repository (to ensure a secure temp location is used)
ServletContext servletContext = this.getServletConfig().getServletContext();
File repository = (File) servletContext.getAttribute("javax.servlet.context.tempdir");
factory.setRepository(repository);
// Create a new file upload handler
ServletFileUpload upload = new ServletFileUpload(factory);
// Parse the request
List<FileItem> items = upload.parseRequest(request);
You can parse all the individual
// Process the uploaded items
Iterator<FileItem> iter = items.iterator();
while (iter.hasNext()) {
FileItem item = iter.next();
if (item.isFormField()) {
processFormField(item);
} else {
processUploadedFile(item);
}
}
try this way:
DiskFileItemFactory factory = new DiskFileItemFactory();
factory.setSizeThreshold(MEMORY_THRESHOLD);
factory.setRepository(new File(System.getProperty("java.io.tmpdir")));
ServletFileUpload upload = new ServletFileUpload(factory);
upload.setFileSizeMax(MAX_FILE_SIZE);
upload.setSizeMax(MAX_REQUEST_SIZE); // sets maximum size of request (include file + form data)
String uploadPath = getServletContext().getRealPath("") + File.separator + UPLOAD_DIRECTORY;
File uploadDir = new File(uploadPath);
if (!uploadDir.exists()) {
uploadDir.mkdir();
}
List<FileItem> formItems = upload.parseRequest(request);
if (formItems != null && formItems.size() > 0) {
for (FileItem item : formItems) {
if (!item.isFormField()) {
//file field
} else {
other form field
}
I am trying to download video file stored as blob in Mysql. The file gets downloaded fine but it gets corrupted i guess. The formats to downloaded are ogg, webm n mp3. The problem is that wen i try to convert any video using ffmpeg, it says "invalid data found during processing".
I am using the following code
Blob image = null;
Connection con = null;
ResultSet rs = null;
try{
Class.forName("com.mysql.jdbc.Driver");
con = MySqlConnect.getDBConnection();
String sql = "select videos, filename from sun.videostore where id ='"+fileID+"'";
Statement stmt = con.createStatement();
rs = stmt.executeQuery(sql);
while (rs.next()) {
String filename = rs.getString("filename");
Blob video = rs.getBlob("videos");
File file1 = new File("C:\\DowloadFile\\" + filename);
FileOutputStream foStream = new FileOutputStream(file1);
if( video != null){
int length = (int) video.length();
InputStream is2 = video.getBinaryStream();
int b = 0;
while(b!=-1){
b=is2.read();
foStream.write(b);
}
}
}
}catch(Exception e){
System.out.println("Ecxeption in getting data from DB = "+e);
}'
No i have checked my uploaded file, it is not corrupted....I have tried a different way to upload the video into DB.
File video = new File(filename);
fis = new FileInputStream(video);
ps.setBinaryStream(2, fis, (int) video.length());//preparedStatement
If i upload the file in above way, i get a correct file on downloading.
I'm trying to generate a pdf file from data in a database using JasperReports with a java servlet. The first time I generated a pdf file successfully with data in database. Then I made some changes in my database table and recreated jrxml file and created a jasper file using that jrxml file. But now when I am trying to generate a pdf, the pdf file is always empty.
Code in my Servlet
response.setContentType("application/pdf");
try {
HttpSession hs = request.getSession();
String id = (String) hs.getAttribute("id");
Class.forName("com.mysql.jdbc.Driver");
Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/exam", "root", "pass");
Statement statement = con.createStatement();
ResultSet resultSet = statement.executeQuery
("SELECT marks, date_time FROM result where sub_id = 1 and user_id = 3");
ServletOutputStream set = response.getOutputStream();
InputStream re = getServletConfig().getServletContext().getResourceAsStream("./results.jasper");
JRResultSetDataSource resultSetDataSource = new JRResultSetDataSource(resultSet);
JasperRunManager.runReportToPdfStream(re,set, new HashMap(), resultSetDataSource);
} catch (Exception e) {
}
How could I solve this?
Change every catch to
...
} catch (Exception e) {
e.printStackTrace();
}
That will provide details of what is going wrong, and where.
I need to store and retrieve MS Word documents into MySQL 5.1 with Servlets. I've the code to upload a file, but I don't know can I feed into the table. I've used BLOB for the field I've to insert .doc files.
Here's my code snippet to upload files:
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
try {
// get access to file that is uploaded from client
Part p1 = request.getPart("file");
String type=p1.getContentType();
String name=p1.getName();
long size = p1.getSize();
InputStream is = p1.getInputStream();
//FileInputStream fis = is.
// read filename which is sent as a part
Part p2 = request.getPart("name");
Scanner s = new Scanner(p2.getInputStream());
String filename = s.nextLine(); // read filename from stream
// get filename to use on the server
String outputfile = this.getServletContext().getRealPath(filename); // get path on the server
FileOutputStream os = new FileOutputStream (outputfile);
// write bytes taken from uploaded file to target file
int ch = is.read();
while (ch != -1) {
os.write(ch);
ch = is.read();
}
os.close();
out.println("<h3>File : '" + name + "' Type : '" + type + "' "
+ "of Size : " + ((double) size/1024) + "KB uploaded successfully!</h3>");
}
catch(Exception ex) {
out.println("Exception -->" + ex.getMessage());
}
finally {
out.close();
}
}
Here, I've used Servlets 3.0 feature for uploading a file...
My table schema :
resources
- UserID [varchar(15)]
- Document [mediumblob]
Could anyone help me how can I store the document into the table and though BLOB is a type representing binary data, how can I retrieve as a Word Document (*.doc)?
I agree with Archimedix... Instead of putting them into MySQL as BLOB, you can store the file on the disk and store its path in MYSQL as TEXT field. This way your retrieval time will be low. If you are space conscious then you can zip the doc and save it on the disk and on request uncompress and send it.
UPDATE
From your code it appears that you already have the handle of the file and you are able to save it on the server.
Now to save space you can zip it using default java zip utility.
You might face a problem when two people upload two different files with the same name. To avoid scenarios like this you can either rename your archived document with an uuid (use java 6 uuid class) or you can generate SHA1 for that file and use that for name.
Now you can use the absolute path of the archived (and renamed file) for storing in the MySQL.
Instead of table schema
resources
UserID [varchar(15)]
Document [mediumblob]
You can use this
resources
UserID [varchar(15)]
Document [varchar(512)]
So for a query like this:
Select Document from table Documents WHERE UserID = 'abcd';
you will now get an absolute path for the zipped file. Uncompress this file and send it.
A partial answer on storing the Word documents in files:
You don't need any additional column to save the file name as the document's record ID can serve as the file name.
When saving a new document, do in a database transaction so that you can undo the process when something goes wrong.
In pseudo code, this would look like this:
begin transaction;
try {
save new record for document;
save Word document in predefined directory, using record's ID as the filename;
} catch (Exception e) {
rollback transaction;
throw e; // Rethrow exception
}
commit transaction;
The code above assumes that an exception is thrown when an error occurs.