使用JSP和Servlet技术实现
整个内容包括:
两个jsp,一个是上传表单、一个是下载列表
两个servlet,一个用于接收表单信息,写入本地系统和数据库、一个用于用于处理jsp的下载请求
三个外部包,一个是commons-fileupload-1.3.2.rar(核心包)commons-io-2.5.jar(依赖包)Mysql驱动包
数据库
数据库的目的不是保存文件内容,而是将文件的文件名,文件类型,以及文件的路径(绝对路径)保存到数据库中:
- file_info 的表结构:
- file_info 的表结构(有待改善):
根据自己的项目需求,适当修改数据库的表结构。
在给出重要的步骤之前,把一些这个项目中用到的工具(封装好的类和方法)先提前说一下,有:
Files类:定义类文件的属性和set()、set()方法。
DatabaseConnection类:数据库的连接、关闭、释放资源。
Files.java
package vo;
public class Files {
String file_name;
String file_type;
String file_path;
public String getFile_name() {
return file_name;
}
public void setFile_name(String file_name) {
this.file_name = file_name;
}
public String getFile_type() {
return file_type;
}
public void setFile_type(String file_type) {
this.file_type = file_type;
}
public String getFile_path() {
return file_path;
}
public void setFile_path(String file_path) {
this.file_path = file_path;
}
}
DatabaseConnection.java(根据自己的实际情况配置参数):
package dbc;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class DatabaseConnection {
private static final String DBDRIVER = "com.mysql.jdbc.Driver" ;
private static final String DBURL = "jdbc:mysql://localhost:3306/MyClass" ;
private static final String DBUSER = "root" ;
private static final String PASSWORD = "4321";
private Connection conn = null;
public Connection DatabaseConnection(){
try {
Class.forName(DBDRIVER) ;
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
try {
this.conn = DriverManager.getConnection(DBURL,DBUSER,PASSWORD) ;
} catch (SQLException e) {
e.printStackTrace();
}
return this.conn ;
}
public Connection getConnection(){
return this.conn ;
}
/*
* 数据库的关闭
* */
public void close(){
if(this.conn != null){
try {
this.conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
文件上传表单(upload.jsp)
如果表单有文件类型的数据,那么表单必须使用复杂表单,enctype=“multipart/form-data”,并且
method=“post”
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@page import="java.sql.Connection"%>
<%@page import="java.sql.DriverManager"%>
<%@page import="java.sql.PreparedStatement"%>
<%@page import="java.sql.ResultSet"%>
<%@page import="java.util.List"%>
<%@page import="java.util.ArrayList"%>
<%@page import="dbc.DatabaseConnection"%>
<%@page import="vo.Files"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>上传文件</title>
<script type="text/javascript">
</script>
</head>
<body>
<form action="/myClass/RegistServlet" method="post" enctype="multipart/form-data">
<!-- <label>类别</label><input type="text" name="username"><br>-->
<label>类别</label><select name="username">
<%
//从数据库中遍历分别的分类,作为下拉框的可选项
Connection conn;
PreparedStatement pstmt ;
ResultSet rs;
DatabaseConnection databaseConnection=new DatabaseConnection();
conn=databaseConnection.DatabaseConnection();
String sql = "select * from filetype";
pstmt = conn.prepareStatement(sql);
rs=pstmt.executeQuery();
List<String>list=new ArrayList<String>();
while(rs.next()){
list.add(rs.getString(1));
}
for(int i=0;i<list.size();i++){
String type = list.get(i);
%>
<option value="<%=type%>"><%=type%></option>
<%}%>
</option></select>
<br/>
<label>文件</label><input type="file" name="pic"><br/>
<input type="submit">
</form>
</body>
</html>
接收表单内容(RegistServlet.java)
fileupload的核心类:DiskFileItemFactory、ServletFileUpload、FileItem
1.创建工厂类 DiskFileItemFactory 对象: DiskFileItemFactory factory = new DiskFileItemFactory();
2.使用工厂创建解析器对象: ServletFileUpload sfu = new ServletFileUpload(factory);
3.使用解析器来解析request对象List fiList = sfu.parseRequest(request);
FileItem 的方法
1.String getname(); 获取原始文件名
2.String getString();获得文本域项的内容
3.String getFieldName(); 获得文本域的名字 例如: 返回的是 username
4.String getContentType();获得上传文件的类型 例如:text/plain
5.long getSize(); 获取上传文件的大小,以字节为单位
6.boolean isFormField();判断当前表单字段是否为普通文本字段,如果返回true,说明该字段是普通文本字段
7.InputStream getInputStream(); 获取上传文件对应的输入流
8.void write(file); 把上传的文件保存到写到指定文件中
9. File file=new File(uploadPath,origFileName); 创建文件对象
package servlet;
import java.io.File;
import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Date;
import java.util.List;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
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 org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import dbc.DatabaseConnection;
@WebServlet("/RegistServlet")
public class RegistServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
private Connection conn ; //需要利用COnnection对象操作
private PreparedStatement pstmt ;
private ResultSet rs;
List<FileItem> fiList;
String content;
String origFileName;
String filedName;
String uploadpath;
String inputValue;
ServletContext contx;
public RegistServlet() {
super();
}
public void init(ServletConfig cfig){
contx=cfig.getServletContext();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doPost(request, response);
}
@SuppressWarnings("unchecked")
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 能控制文件名的乱码,但是不能控制普通文本的中文乱码
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
// 创建接收文件的工厂类
DiskFileItemFactory factory = new DiskFileItemFactory();
// 创建文件解析对象
ServletFileUpload sfu = new ServletFileUpload(factory);
try {
// 解析request,获得表单的每一项,包含普通文本域
fiList = sfu.parseRequest(request);
// 遍历每一个文本项
for (FileItem fi : fiList) {
//手动转换编码
content = fi.getString();
content = new String(content.getBytes("ISO-8859-1"), "UTF-8");
System.out.println("content:"+origFileName);
// 获得原始文件名
origFileName = fi.getName();
System.out.println("origFileName:"+origFileName);
// 获得文本域的名字
filedName = fi.getFieldName();
System.out.println("filedName:"+filedName);
// 获得文件的大小
long size = fi.getSize();
// 是否是普通文本
boolean isFieldForm = fi.isFormField();
// 生成文件名,
if (!isFieldForm) {
if (filedName != null && !"".equals(filedName)) {
// 指定要上传的目录
uploadpath = request.getSession().getServletContext().getRealPath("/upload");
// 创建文件对象
File file = new File(uploadpath, origFileName);
System.out.println(uploadpath);
// 把文件写入硬盘
fi.write(file);
}
}else {
String inputName=fi.getFieldName();
System.out.println("普通文件getFieldName"+inputValue);
inputValue=new String(fi.getString().getBytes("ISO-8859-1"), "UTF-8");
System.out.println("普通文件filedName"+inputValue);
}
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//将文件信息保存在数据库
DatabaseConnection databaseconnection=new DatabaseConnection();
conn=databaseconnection.DatabaseConnection();
String sql = "insert into file_info values(?,?,?)" ;
try {
this.pstmt =this.conn.prepareStatement(sql);
this.pstmt.setObject(1, origFileName );
this.pstmt.setObject(2, inputValue);
this.pstmt.setObject(3, uploadpath);
// 回写结果
if(this.pstmt.executeUpdate()>0) {
contx.log("FileName:---"+origFileName+"--- FileType:---"+inputValue+"--- FilePath:---"+uploadpath);
response.getWriter().print("文件上传成功");
}
databaseconnection.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
到这里文件的上传部分就已经完成了,万事开头难,剩下的下载部分就相对容易一些了,对于下载部分可以有很多种实现方法,但有的方法的兼容性比较差,比如a标签,设置好download属性也可以实现下载文件的功能,但是在某些浏览器不支持,所以这里就没有用这种方法。
接收表单内容(download.jsp)
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@page import="java.sql.Connection"%>
<%@page import="java.sql.DriverManager"%>
<%@page import="java.sql.PreparedStatement"%>
<%@page import="java.sql.ResultSet"%>
<%@page import="java.util.List"%>
<%@page import="java.util.ArrayList"%>
<%@page import="dbc.DatabaseConnection"%>
<%@page import="vo.Files"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>下载列表</title>
</head>
<body>
<%
Connection conn;
PreparedStatement pstmt ;
ResultSet rs;
DatabaseConnection databaseConnection=new DatabaseConnection();
conn=databaseConnection.DatabaseConnection();
String sql = "select * from file_info";
pstmt = conn.prepareStatement(sql);
rs=pstmt.executeQuery();
List<Files>list=new ArrayList<Files>();
while(rs.next()){
Files fi=new Files();
fi.setFile_name(rs.getString(1));
fi.setFile_type(rs.getString(2));
fi.setFile_path(rs.getString(3));
list.add(fi);
}
%>
<center>
<table aligin="center" width="450" border="1">
<tr>
<td align="center" colspan="5">
<h3>所有文件信息</h3>
</td>
</tr>
<tr align="center">
<td><b>文件名称</b></td>
<td><b>文件类别</b></td>
<td><b>文件操作</b></td>
</tr>
<%
if(list==null||list.size()<1){
out.print("没有数据!");
}else{
for(Files fi:list){
%>
<tr align="center">
<td><%=fi.getFile_name() %></td>
<td><%=fi.getFile_type() %></td>
<td><a href="DownServlet?fileName=<%=fi.getFile_name()%>">
<img src="icon_down.png" alt="download" height="20" width="20"/>
</a></td>
</tr>
<%
}
}
%>
</table>
</center>
<br/>
</body>
</html>
实现下载功能(DownServlet.java)
1.IOUtils.copy(new FileInputStream(file), response.getOutputStream()); 将输入流转换为输出流
2.解决预览的问题,要给response头信息
response.addHeader(“content-disposition”, “attachment;filename=”+new String(fileName.getBytes(“gb2312”),“ISO8859-1”));(具体代码如下)
package servlet;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.tomcat.util.http.fileupload.IOUtils;
@WebServlet("/DownServlet")
public class DownServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
ServletContext contx;
public DownServlet() {
super();
}
public void init(ServletConfig cfig){
contx=cfig.getServletContext();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获得下载的文件名字
String fileName=request.getParameter("fileName");
contx.log("Original_FileName:---"+fileName);
//解决get方式中文乱码
fileName=new String(fileName.getBytes("ISO-8859-1"), "UTF-8");
contx.log("After_FileName:---"+fileName);
//获取文件的绝对路径
String realPath=request.getSession().getServletContext().getRealPath("/upload");
System.out.println(realPath);
//创建文件对象
File file=new File(realPath,fileName);
if(!file.exists()) {
String result="文件不存在";
System.out.println("111"+result);
result=new String(result.getBytes("ISO-8859-1"), "UTF-8");
System.out.println("222"+result);
response.getWriter().write(result);
return;
}
System.out.println(fileName);
//让浏览器弹出下载的对话框,并且将文件名展示在对话框上
response.addHeader("content-disposition", "attachment;filename="+new String(fileName.getBytes("gb2312"),"ISO8859-1"));
System.out.println(fileName);
IOUtils.copy(new FileInputStream(file), response.getOutputStream());
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
到这里整个文件的上传下载就结束了,先看下整个项目的架构,然后整体看下效果。大家根据自己的项目需要,丰富下前端界面吧。