作者:蜗牛 527812862
1. 首先把javacommons-fileupload-1.2.1.jar和commons-io-1.4.jar两个包通过MyEclipse导入到项目工程里。
2. 建立FileUpload.java的Servlet类。
package com.web.server.servlet;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Iterator;
import java.util.List;
import javax.servlet.ServletException;
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.FileUploadBase.SizeLimitExceededException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
public class FileUpload extends HttpServlet {
public FileUpload() {
super();
}
public void destroy() {
super.destroy(); // Just puts "destroy" string in log
}
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doPost(request, response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
final String appRealPath = this.getServletContext().getRealPath("/"); // 获取webapp的物理路径
final long MAX_SIZE = 3 * 1024 * 1024; // 设置上传文件最大为 3M
final String[] allowedExt = new String[] { "jpg", "jpeg", "gif", "txt",
"doc", "docx","pdf", "mp3", "wma", "jar" }; // 允许上传的文件格式的列表
response.setContentType("text/html");
response.setCharacterEncoding("UTF-8"); // 设置字符编码为UTF-8, 这样支持汉字显示
// 实例化一个硬盘文件工厂,用来配置上传组件ServletFileUpload
DiskFileItemFactory dfif = new DiskFileItemFactory();
dfif.setSizeThreshold(4096); // 设置上传文件时用于临时存放文件的内存大小,这里是4K.多于的部分将临时存在硬盘
dfif.setRepository(new File(appRealPath + "FilesUploadTemp//"));
// 设置存放临时文件的目录,web根目录下的ImagesUploadTemp目录
// 用以上工厂实例化上传组件
ServletFileUpload sfu = new ServletFileUpload(dfif);
sfu.setSizeMax(MAX_SIZE); // 设置最大上传尺寸
PrintWriter out = response.getWriter();
// 从request得到 所有 上传域的列表
List fileList = null;
try {
fileList = sfu.parseRequest(request);
} catch (FileUploadException e) {// 处理文件尺寸过大异常
if (e instanceof SizeLimitExceededException) {
out.println("文件尺寸超过规定大小:" + MAX_SIZE + "字节<p />");
out.println("<a href=/" " + request.getContextPath()
+ "/server_upload.jsp" + " /" target=/"_top/">返回</a>");
return;
}
e.printStackTrace();
}
// 没有文件上传
if (fileList == null || fileList.size() == 0) {
out.println("请选择上传文件<p />");
out.println("<a href=/" " + request.getContextPath()
+ "/server_upload.jsp" + " /" target=/"_top/">返回</a>");
return;
}
// 得到所有上传的文件
Iterator fileItr = fileList.iterator();
// 循环处理所有文件
while (fileItr.hasNext()) {
FileItem fileItem = null;
String path = null;
long size = 0;
// 得到当前文件
fileItem = (FileItem) fileItr.next();
// 忽略简单form字段而不是上传域的文件域(<input type="text" />等)
if (fileItem == null || fileItem.isFormField()) {
continue;
}
// 得到文件的完整路径
path = fileItem.getName();
// 得到文件的大小
size = fileItem.getSize();
if ("".equals(path) || size == 0) {
out.println("请选择上传文件<p />");
out.println("<a href=/" " + request.getContextPath()
+ "/server_upload.jsp" + " /" target=/"_top/">返回</a>");
return;
}
// 得到去除路径的文件名
String t_name = path.substring(path.lastIndexOf("//") + 1);
// 得到文件的扩展名(无扩展名时将得到全名)
String t_ext = t_name.substring(t_name.lastIndexOf(".") + 1);
// 拒绝接受规定文件格式之外的文件类型
int allowFlag = 0;
int allowedExtCount = allowedExt.length;
for (; allowFlag < allowedExtCount; allowFlag++) {
if (allowedExt[allowFlag].equals(t_ext))
break;
}
if (allowFlag == allowedExtCount) {
out.println("请上传以下类型的文件<p />");
for (allowFlag = 0; allowFlag < allowedExtCount; allowFlag++)
out.println("*." + allowedExt[allowFlag]
+ " ");
out.println("<a href=/" " + request.getContextPath()
+ "/server_upload.jsp" + " /" target=/"main/">返回</a>");
return;
}
/*
* 根据系统时间生成上传后保存的文件名
*/
//long now = System.currentTimeMillis();
// 根据系统时间生成上传后保存的文件名
//String prefix = String.valueOf(now);//转为字符串
//System.out.println("servlet"+prefix);
// 保存的最终文件完整路径,保存在web根目录下的FilesUploaded目录下
/*String u_name = appRealPath + "FilesUploaded//" + prefix + "."
+ t_ext;
*/
String u_name = appRealPath + "FilesUploaded//" + path ;
try {
// 保存文件
fileItem.write(new File(u_name));
/*out.println("文件上传成功. 已保存为: " + prefix + "." + t_ext
+ " 文件大小: " + size + "字节<p />");
*/
out.println("文件上传成功. 已保存为: " + path
+ " 文件大小: " + size + "字节<p />");
out.println("恭喜管理员资料上传成功!");
} catch (Exception e) {
e.printStackTrace();
}
}
}
public void init() throws ServletException {
}
}
3. 编写好Servlet之后对项目中的web.xml文件进行配置,映射Servlet的正确路径。
<servlet>
<servlet-name>FileUpload</servlet-name>
<servlet-class>com.web.server.servlet.FileUpload</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>FileUpload</servlet-name>
<url-pattern>/servlet/FileUpload</url-pattern>
</servlet-mapping>
4. 最后进行视图层的JSP页面的编写。如下展示上传功能模块表单部分的代码
server_upload.jsp:
<%@ page language="java" import="java.util.*" pageEncoding="GB18030"%>
<%@ page import="com.web.server.user.*"%>
<%@page import="java.io.File"%>
<!-- 此处我使用了Jakarta的commons-fileupload-1.2.1.jar和commons-io-1.4.jar上传组件并且编写了上传使用的servlet:FileUpload.java
-->
<html>
<head>
<title>上传资料</title>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<style type="text/css">
<!--
a{ text-decoration: none; color: #000000 }
a:hover{ text-decoration: underline }
body{ scrollbar-base-color: #F3F6FA; scrollbar-arrow-color: #4D76B3; font-size: 12px; background-color: #ffffff }
table{ font: 12px Verdana,Tahoma; color: #000000 }
input,select,textarea{ font: 11px Verdana,Tahoma; color: #000000; font-weight: normal; background-color: #F3F6FA }
select{ font: 11px Verdana,Tahoma; color: #000000; font-weight: normal; background-color: #F3F6FA }
.nav{ font: 12px Verdana,Tahoma; color: #000000; font-weight: bold }
.nav a{ color: #000000 }
.header{ font: 11px Verdana,Tahoma; color: #000000; font-weight: bold; background-image: url("images/green/bg01.gif") }
.header a{ color: #FFFFFF }
.category{ font: 11px Verdana,Tahoma; color: #000000; background-color: #EFEFEF }
.tableborder{ background: #4D76B3; border: 0px solid #4D76B3 }
.singleborder{ font-size: 0px; line-height: 0px; padding: 0px; background-color: #F3F6FA }
.smalltxt{ font: 11px Verdana,Tahoma }
.outertxt{ font: 12px Verdana,Tahoma; color: #000000 }
.outertxt a{ color: #000000 }
.bold{ font-weight: bold }
.altbg1{ background: #F3F6FA }
.altbg2{ background: #FFFFFF }
-->
</style>
<script language="JavaScript" src="images/common.js"></script>
<style type="text/css" id="defaultPopStyle">.cPopText { font-family: Tahoma, Verdana; background-color: #FFFFCC; border: 1px #000000 solid; font-size: 12px; padding-right: 4px; padding-left: 4px; height: 20px; padding-top: 2px; padding-bottom: 2px; visibility: hidden; filter: Alpha(Opacity=80)}
</style>
</head>
<body leftmargin="0" rightmargin="0" topmargin="0"
onkeydown="if(event.keyCode==27) return false;">
<div id="popLayer" style="position: absolute; z-index: 1000;"
class="cPopText">
</div>
<table style="table-layout: fixed;" align="center" border="0"
cellpadding="0" cellspacing="0" width="97%">
<tbody>
<tr>
<td class="nav" align="left" nowrap="nowrap" width="90%">
资料管理» 上传资料
</td>
<td align="right" width="10%">
<a href="#bottom"><br></a>
</td>
</tr>
</tbody>
</table>
<br>
<table align="center" border="0" cellpadding="0" cellspacing="0"
width="97%">
<tbody>
<tr>
<td><br></td>
</tr>
</tbody>
</table>
<input name="formhash" value="93a2a31f" type="hidden">
<table class="tableborder" align="center" cellpadding="4"
cellspacing="1" width="97%">
<tbody>
<tr class="header">
<td align="center" width="65%">
资料选择
</td>
</tr>
<tr>
<td class="altbg1" align="center" nowrap="nowrap">
<!-- 获取servlet的相对路径 -->
<form action="<%=request.getContextPath()%>/servlet/FileUpload"
method="post" enctype="multipart/form-data">
<input type="file" name="fileUpload" />
<input type="submit" value="上传" />
</form>
</td>
</tr>
</tbody>
</table><br><a name="bottom" /></body>
</html>
5. 通过如上步骤就已开发出一个基于commons-fileupload组件的具有上传功能的模块。把指定后缀的文件上传到指定的目录下。作者在对此系统的设计中把上传的文件保存在了此项目根目录的FilesUploaded文件夹下。
在进行此功能模块开发过程中,难解决的是编码问题,即如何把有中文字符文件名的文件上传到文件夹中和如何下载文件名为英文字符与中文字符混合的文件。经过对上传与下载文件的原理和对Tomcat服务器的研究,作出如下对乱码问题的解决方案:
6. <a href="<%=downloadpath+fs.getName() %>">[下载]</a>可以下载到文件名为英文字符或中文字符的文件名,但不能下载英文字符与中文字符混合的文件。
为解决如上问题,需对Tomcat的conf目录下的server.xml配置文件进行修改。
在
<Connector port="8088" protocol="HTTP/1.1" connectionTimeout="20000"
redirectPort="8443" />
中加入 URIEncoding="UTF-8",
即:
<Connector port="8088" protocol="HTTP/1.1" connectionTimeout="20000"
redirectPort="8443" URIEncoding="UTF-8" />
最后重启服务器,下载问题得到解决。
最后展示效果如图所示:
7. 管理员从后台管理处上传资料后,用户可以从前台展示页面下载所有资料。下载功能模块的开发依旧使用commons-fileupload组件。这里编写一个用户下载资料的JSP页面
resource_download.jsp
<%@ page language="java" import="java.util.*" pageEncoding="GB18030"%>
<%@ page import="com.web.server.user.*"%>
<%@page import="java.io.File"%>
<html>
<head>
<title>资料列表</title>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<style type="text/css"><!--
a { text-decoration: none; color: #000000 }
a:hover { text-decoration: underline }
body { scrollbar-base-color: #F3F6FA; scrollbar-arrow-color: #4D76B3; font-size: 12px; background-color: #ffffff }
table { font: 12px Verdana,Tahoma; color: #000000 }
input,select,textarea { font: 11px Verdana,Tahoma; color: #000000; font-weight: normal; background-color: #F3F6FA }
select { font: 11px Verdana,Tahoma; color: #000000; font-weight: normal; background-color: #F3F6FA }
.nav { font: 12px Verdana,Tahoma; color: #000000; font-weight: bold }
.nav a { color: #000000 }
.header { font: 11px Verdana,Tahoma; color: #000000; font-weight: bold; background-image: url("images/green/bg01.gif") }
.header a { color: #FFFFFF }
.category { font: 11px Verdana,Tahoma; color: #000000; background-color: #EFEFEF }
.tableborder { background: #4D76B3; border: 0px solid #4D76B3 }
.singleborder { font-size: 0px; line-height: 0px; padding: 0px; background-color: #F3F6FA }
.smalltxt { font: 11px Verdana,Tahoma }
.outertxt { font: 12px Verdana,Tahoma; color: #000000 }
.outertxt a { color: #000000 }
.bold { font-weight: bold }
.altbg1 { background: #F3F6FA }
.altbg2 { background: #FFFFFF }
--></style>
<script language="JavaScript" src="images/common.js"></script>
<style type="text/css" id="defaultPopStyle">.cPopText { font-family: Tahoma, Verdana; background-color: #FFFFCC; border: 1px #000000 solid; font-size: 12px; padding-right: 4px; padding-left: 4px; height: 20px; padding-top: 2px; padding-bottom: 2px; visibility: hidden; filter: Alpha(Opacity=80)}</style>
</head>
<body leftmargin="0" rightmargin="0" topmargin="0"
onkeydown="if(event.keyCode==27) return false;">
<div id="popLayer" style="position: absolute; z-index: 1000;"
class="cPopText"></div>
<table style="table-layout: fixed;" align="center" border="0"
cellpadding="0" cellspacing="0" width="97%">
<tbody>
<tr>
<td class="nav" align="left" nowrap="nowrap" width="90%">
<h3> <a href="welcome.jsp">网络教学平台</a> » 资料下载</h3>
</td>
<td align="right" width="10%">
<a href="#bottom"><br>
</a>
</td>
</tr>
</tbody>
</table>
<br>
<table align="center" border="0" cellpadding="0" cellspacing="0"
width="97%">
<tbody>
<tr>
<td><br></td>
</tr>
</tbody>
</table>
<input name="formhash" value="93a2a31f" type="hidden">
<table class="tableborder" align="center" cellpadding="4"
cellspacing="1" width="97%">
<tbody>
<tr class="header">
<td align="center" width="65%">
资料名
</td>
<td align="center">
操作
</td>
</tr>
<%
request.setCharacterEncoding("UTF-8");
String path ="../webapps/NetworkTeachingSystem/FilesUploaded/"; //自己去测试路径
System.out.println(path);
File f = new File(path);
File fa[] = f.listFiles();
for(int i=0;i<fa.length;i++)
{
File fs = fa[i];
if (fs.isDirectory())
{
out.println(fs.getName()+" [目录]<br />");
}else{
String downloadpath="../NetworkTeachingSystem/FilesUploaded/";
%>
<tr>
<td class="altbg1" align="center" nowrap="nowrap">
<%=fs.getName()%>
</td>
<td class="altbg1" align="right">
<% String url = request.getRequestURL() + (request.getQueryString() == null ? "" : "?" + request.getQueryString()); %>
<center> <a href="<%=downloadpath+fs.getName() %>">[下载]</a></center>
</td>
</tr>
<%
}
}
%>
</tbody>
</table><br><a name="bottom" /></body>
</html>
下载界面如图所示:
8. 最后谈谈如何进行文件的删除。
1)如何删除文件名是数字和字母组合的文件
解决方法:
<%@ page contentType="text/html;charset=UTF-8"%>
<%@ page import="java.io.*"%>
<html>
<head>
<title>资料删除</title>
<!-- 支持删除文件夹中文件名含数字字母和中文组合的文件-->
</head>
<body>
<%
request.setCharacterEncoding("UTF-8");
String path="../webapps/NetworkTeachingSystem/FilesUploaded/";
String filename=request.getParameter("filename");
File f=new File(path,filename);
if(f.exists()){//检查是否存在
f.delete();//删除文件
out.println(path +filename+" 存在,已删除。");
}else{
out.println(path + filename+"不存在!");//输出目前所在的目录路径
}
%>
附上罗列目录的代码:
<%@ page contentType="text/html;charset=gb2312"%>
<%@ page import="java.io.*"%>
<html>
<head>
<title>文件的建立、检查与删除</title>
</head>
<body>
<%
String path=request.getRealPath("");
//out.println(path);
File f=new File(path,"File.txt");
//out.println(f);
//out.println(f.exists());
if(f.exists()){//检查File.txt是否存在
f.delete();//删除File.txt文件
out.println(path + "//File.txt 存在,已删除。");
}else{
f.createNewFile();//在当前目录下建立一个名为File.txt的文件
out.println(path + "//File.txt 不存在,已建立。");//输出目前所在的目录路径
}
%>
2)如何删除文件名包含中文字符的文件
解决办法:
把编码统一换成UTF-8,解决了中文字符的问题
如图所示:
注:视图显示可能用了一些脚本,若用到了脚本则不作解释。所以读者在自己运行环境测试的时候展现的效果与截图不一样,但是核心功能肯定可以实现。