您的位置:首页 > 运维架构 > Apache

web项目利用apache的DiskFileItemFactory和ServletFileUpload上传图片

2018-02-02 19:22 483 查看
最近在做java的web项目时,遇到图片上传此功能,我是利用apache提供的第三方jar来实现的

一:首先需要引用以下两个jar包



二:
<form>
表单要设置属性
enctype="multipart/form-data"

<form name="itemForm" target="_self" id="itemForm" method="post" action="servlet/item/FileUploadServlet" enctype="multipart/form-data">
<input type="hidden" name="itemNo" value="<%=item.getItemNo() %>">
<div align="center">
<table width="95%" border="0" cellpadding="0" cellspacing="0">
<tr>
<td height="26"><div align="right">物料名称:&bsp;   </div></td>
<td><%=item.getItemName() %></td>
</tr>
<tr>
<td height="74"><div align="right">图片: </div></td>
<td><img src="upload/<%=item.getFileName() %>" width="85" height="49">  </td>
</tr>
<tr>
<td width="22%" height="29"><div align="right"><font color="#FF0000">*</font>选择图片: </div>
</td>
<td width="78%"><input name="fileName" type="file" class="text1" size="40" maxlength="40"></td>
</tr>
</table>
<div align="center">
<input name="btn_upload" class="button1" type="submit"
id="btn_upload" value="上传">
    
<input name="btnBack" class="button1" type="button" id="btnBack"
value="返回" onClick="history.go(-1)">
</div>
</div>
</form>


为什么上传文件的表单需要设置enctype=”multipart/form-data”

注意:使用
enctype="multipart/form-data"
时,表单必须是post提交方式

当点击上传按钮时,表单就会将文件内容也提交到HTML请求中了

三:servlet设置

package com.bjpowernode.drp.basedata.web;

import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Iterator;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

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.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

import com.bjpowernode.drp.basedata.manager.ItemManager;
import com.bjpowernode.drp.basedata.manager.ItemManagerImpl;
import com.bjpowernode.drp.util.ApplicationException;

public class FileUploadServlet extends AbstractItemServlet {
//文件下载存放路径
private File uploadPath;
//临时文件存放路径
private File tempPath;

public void doPost(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
//1.apache的核心API:DiskFileItemFactory
DiskFileItemFactory factory = new DiskFileItemFactory();
//1.1设置内存缓冲区大小
factory.setSizeThreshold(4096);
//1.2指定临时文件目录
factory.setRepository(tempPath);
//2.apache的核心API:ServletFileUpload ,负责处理上传的文件数据
ServletFileUpload upload = new ServletFileUpload(factory);
//2.1设置文件上传总量(所有上传文件)的最大值
upload.setSizeMax(1000000 * 20);
//2.2设置编码格式
upload.setHeaderEncoding("UTF-8");
try {
//2.3.解析request对象,获取传过来的数据
List fileItems = upload.parseRequest(req);
String itemNo = "";
for (Iterator iter = fileItems.iterator(); iter.hasNext();) {
//3.apache的核心API:FileItem
FileItem item = (FileItem) iter.next();
//3.1是普通的表单输入域
if(item.isFormField()) {
//
if ("itemNo".equals(item.getFieldName())) {
//3.2用于将FileItem对象中保存的数据流内容以一个字符串返回,
itemNo = item.getString();
}
}
//3.1是type=file的输入域
if (!item.isFormField()) {
//3.2获取文件名,IE为绝对路径,Firefox只有文件名
String fileName = item.getName();
//3.3获得上传文件的大小
long size = item.getSize();
if ((fileName == null || fileName.equals("")) && size == 0) {
continue;
}
//截取字符串 ,获得文件名
fileName = fileName.substring(fileName.lastIndexOf("\\") + 1, fileName.length());
//3.4 将FileItem对象中保存的主体内容保存到指定的文件中
item.write(new File(uploadPath, fileName));
//调用业务逻辑层
itemManager.uploadItemImage(itemNo, fileName);
}
//重定向
res.sendRedirect(req.getContextPath() + "/servlet/item/SearchItemServlet");
} catch (Exception e) {
e.printStackTrace();
throw new ApplicationException("上传失败!");
}
}

public void init() throws ServletException {
//文件存放目录
//获取servlet容器对象,相当于tomacat容器,getRealPath("upload")获取upload文件在容器中的实际发布运行位置
uploadPath = new File(getServletContext().getRealPath("upload"));
//如果目录不存在
if (!uploadPath.exists()) {
//创建目录
uploadPath.mkdir();
}

//临时目录
tempPath = new File(getServletContext().getRealPath("temp"));
if (!tempPath.exists()) {
tempPath.mkdir();
}
//显示调用父类的init方法,因为该类继承了父类,覆盖了父类的init()方法
super.init();
}
}


apache的核心API:DiskFileItemFactory:是创建FileItem 对象的工厂

public void setSizeThreshold(int sizeThreshold)
:设置内存缓冲区的大小,默认值为10K。当上传文件大于缓冲区大小时,fileupload组件将使用临时文件缓存上传文件。

public void setRepository(Java.io.File repository)


指定临时文件目录,默认值为System.getProperty(“java.io.tmpdir”).

apache的核心API:ServletFileUpload ,负责处理上传的文件数据

setSizeMax(long sizeMax)
:设置上传文件总量的最大值(所有上传文件),用于设置请求消息实体内容(即所有上传数据)的最大尺寸限制,以防止客户端恶意上传超大文件来浪费服务器端的存储空间。其参数是以字节为单位的long型数字

setFileSizeMax(long fileSizeMax)
:设置上传文件的最大值(单个文件),用于设置单个上传文件的最大尺寸限制,以防止客户端恶意上传超大文件来浪费服务器端的存储空间。其参数是以字节为单位的long型数字

setHeaderEncoding(java.lang.String encoding)
:设置编码格式。在文件上传请求的消息体中,除了普通表单域的值是文本内容以外,文件上传字段中的文件路径名也是文本,在内存中保存的是它们的某种字符集编码的字节数组,Apache文件上传组件在读取这些内容时,必须知道它们所采用的字符集编码,才能将它们转换成正确的字符文本返回。

List parseRequest(HttpServletRequest request)
:解析request对象,并把表单中的每一个输入项包装成一个fileItem 对象,并返回一个保存了所有FileItem的list集合(form提交采用multipart/form-data,无法采用req.getParameter()取得数据)

boolean isMultipartContent(HttpServletRequest request) :判断上传表单是否为multipart/form-data类型

3. apache的核心API:FileItem:是个接口,用来阻止所有的文件,通过这个统一接口访问文件的信息

boolean isFormField()
: isFormField方法用于判断FileItem类对象封装的数据是一个普通文本表单字段,还是一个文件表单字段,如果是普通表单字段则返回true,否则返回false。

String getString()
:用于将FileItem对象中保存的数据流内容以一个字符串返回,它有两个重载的定义形式:

public Java.lang.String getString();使用缺省的字符集编码将主体内容转换成字符串

public java.lang.String getString(java.lang.String encoding) throws java.io.UnsupportedEncodingException

使用参数指定的字符集编码将主体内容转换成字符串。如果在读取普通表单字段元素的内容时出现了中文乱码现象,请调用第二个getString方法,并为之传递正确的字符集编码名称

void write(File file)
:用于将FileItem对象中保存的主体内容保存到某个指定的文件中。如果FileItem对象中的主体内容是保存在某个临时文件中,该方法顺利完成后,临时文件有可能会被清除。该方法也可将普通表单字段内容写入到一个文件中,但它主要用途是将上传的文件内容保存在本地文件系统中。在此,临时文件保存在项目发布的tomacat的根目录下的temp文件夹,但是文件最终保存的目录是upload文件夹

long  getSize()
:返回上传文件的大小

String getName()
:用于获得文件上传字段中的文件名。注意IE或FireFox中获取的文件名是不一样的,IE中是绝对路径,FireFox中只是文件名

问题:

上传的图片名字有中文时乱码,图片也加载不出来,调试检查元素时,手动把.jsp页面的
<img src="">
图片路径改为中文的也加载不出来,改为不是中文的就能加载出来,把
upload.setHeaderEncoding("UTF-8");
改为
upload.setHeaderEncoding("GBK");
就能加载出来了;尝试使用
public java.lang.String getString(java.lang.String encoding)
的构造函数,在此使用改变编码格式,但是不起作用

总结

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐