本教程显示了如何实现Java Web应用程序(使用Servlet和JSP),该Java Web应用程序将文件上传到服务器并将文件保存到数据库。
该应用程序采用以下技术:
- Servlet 3.0+:从Servlet 3.0开始,我们可以编写代码来轻松处理文件上传。有关详细信息,请阅读本教程:使用servlet上载Java文件。该代码正在使用最新版本的Servlet API(Servlet 4.0或4.1)
- MySQL数据库5.5或更高版本:我们会将上传的文件存储在MySQL数据库中。有关如何在MySQL数据库中存储文件的更多详细信息,请阅读本文。
该应用程序将包含以下源文件:
- Upload.jsp:提供一种表单,该表单允许用户输入一些信息(名字和姓氏)并拾取文件(人像图片)。
- FileUploadDBServlet:从上载表单捕获输入,将上载文件保存到数据库中,并将用户转发到消息页面。
- Message.jsp:显示成功或错误消息。
现在,让我们详细研究应用程序的每个部分。
1.创建MySQL数据库表
首先,让我们在MySQL中创建一个数据库和一个表。使用MySQL命令行客户端或MySQL Workbench执行以下脚本:
CREATE TABLE `contacts` (
`contact_id` int(11) NOT NULL AUTO_INCREMENT,
`first_name` varchar(45) DEFAULT NULL,
`last_name` varchar(45) DEFAULT NULL,
`photo` mediumblob,
PRIMARY KEY (`contact_id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=latin1
该脚本将创建一个名为AppDB的数据库和一个名为contacts的表。文件将存储在mediumblob 类型的列照片中最多可以存储16 MB的二进制数据。对于较大的文件,请使用longblob(最大4 GB)。
2.编码上传表单页面
编写上传表单的代码,如下所示(Upload.jsp):
1个 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18岁 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
<%@ 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 Upload to Database Demo</ title >
</ head >
< body >
< center >
< h1 >File Upload to Database Demo</ h1 >
< form method = "post" action = "uploadServlet" enctype = "multipart/form-data" >
< table border = "0" >
< tr >
< td >First Name: </ td >
< td >< input type = "text" name = "firstName" size = "50" /></ td >
</ tr >
< tr >
< td >Last Name: </ td >
< td >< input type = "text" name = "lastName" size = "50" /></ td >
</ tr >
< tr >
< td >Portrait Photo: </ td >
< td >< input type = "file" name = "photo" size = "50" /></ td >
</ tr >
< tr >
< td colspan = "2" >
< input type = "submit" value = "Save" >
</ td >
</ tr >
</ table >
</ form >
</ center >
</ body >
</ html >
|
此页面显示两个文本字段(名字和姓氏)和一个文件字段,允许用户选择要上传的文件。此表单的action属性设置为uploadServlet,这是我们将在下一部分中创建的servlet的URL映射。
3.编码文件上传servlet
使用以下代码创建一个名为FileUploadDBServlet.java的Servlet类:
1个 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18岁 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65岁 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
package net.codejava.upload;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;
@WebServlet ( "/uploadServlet" )
@MultipartConfig (maxFileSize = 16177215 ) // upload file's size up to 16MB
public class FileUploadDBServlet extends HttpServlet {
// database connection settings
private String dbURL = "jdbc:mysql://localhost:3306/AppDB" ;
private String dbUser = "root" ;
private String dbPass = "secret" ;
protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
// gets values of text fields
String firstName = request.getParameter( "firstName" );
String lastName = request.getParameter( "lastName" );
InputStream inputStream = null ; // input stream of the upload file
// obtains the upload file part in this multipart request
Part filePart = request.getPart( "photo" );
if (filePart != null ) {
// prints out some information for debugging
System.out.println(filePart.getName());
System.out.println(filePart.getSize());
System.out.println(filePart.getContentType());
// obtains input stream of the upload file
inputStream = filePart.getInputStream();
}
Connection conn = null ; // connection to the database
String message = null ; // message will be sent back to client
try {
// connects to the database
DriverManager.registerDriver( new com.mysql.jdbc.Driver());
conn = DriverManager.getConnection(dbURL, dbUser, dbPass);
// constructs SQL statement
String sql = "INSERT INTO contacts (first_name, last_name, photo) values (?, ?, ?)" ;
PreparedStatement statement = conn.prepareStatement(sql);
statement.setString( 1 , firstName);
statement.setString( 2 , lastName);
if (inputStream != null ) {
// fetches input stream of the upload file for the blob column
statement.setBlob( 3 , inputStream);
}
// sends the statement to the database server
int row = statement.executeUpdate();
if (row > 0 ) {
message = "File uploaded and saved into database" ;
}
} catch (SQLException ex) {
message = "ERROR: " + ex.getMessage();
ex.printStackTrace();
} finally {
if (conn != null ) {
// closes the database connection
try {
conn.close();
} catch (SQLException ex) {
ex.printStackTrace();
}
}
// sets the message in request scope
request.setAttribute( "Message" , message);
// forwards to the message page
getServletContext().getRequestDispatcher( "/Message.jsp" ).forward(request, response);
}
}
}
|
在此servlet中,我们使用两个注释:
- @WebServlet:标记此servlet,以便servlet容器在启动时将其加载,并将其映射到URL模式/ uploadServlet。
- @MultipartConfig:指示此servlet将处理多部分请求。我们限制上传文件的最大大小为16 MB。
所述的doPost()方法执行的所有细节。这里有三个值得注意的地方:
- 在请求中获取上传文件的一部分:
名称“照片”是Upload.jsp页面中文件输入字段的名称。1个 Part filePart = request.getPart(
"photo"
);
- 获取上传文件的输入流:
1个 inputStream = filePart.getInputStream();
- 并将输入流传递到准备好的语句中:
1个 |
statement.setBlob( 3 , inputStream);
|
如果您想精通Java Servlet和JSP编程,建议您阅读这本出色的Head First Servlet和JSP书籍。
4.编码信息页面
使用以下代码创建一个名为Message.jsp的JSP页面:
1个 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
<%@ 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>Message</title>
</head>
<body>
<center>
<h3><%=request.getAttribute( "Message" )%></h3>
</center>
</body>
</html>
|
该页面仅在请求范围内显示变量“ Message”的值。
5.测试应用程序并验证存储在数据库中的文件
假设应用程序部署在本地主机上的端口8080的根目录/ FileUploadDatabase下,键入以下URL:
http:// localhost:8080 / FileUploadDatabase / Upload.jsp
显示以下上传表单:
键入名字,姓氏,然后选择一个图像文件。单击“保存”按钮,如果一切顺利,则会出现以下消息:
要验证文件是否已成功存储在数据库中,请在MySQL Workbench中打开一个新的SQL编辑器并执行以下查询:
1个 |
select * from contacts;
|
该查询将返回新插入的记录,右键单击列photo的BLOB单元,然后从上下文菜单中选择“在编辑器中打开值”:
出现一个对话框,我们可以在“图像”选项卡中看到图像:
如果要以编程方式检索存储在数据库中的文件,请阅读教程:如何从数据库检索文件数据。
注意:默认情况下,MySQL将查询中可发送的数据包的大小限制为仅1 MB。因此,如果尝试上传大于此限制的文件,则可能会出错。要增加此大小限制,请按照本教程中的讨论在MySQL中设置max_allowed_packet变量。