现在的位置: 首页 > 综合 > 正文

利用开源组件commons-fileupload上传图片文件(2)

2018年05月19日 ⁄ 综合 ⁄ 共 11060字 ⁄ 字号 评论关闭

上一篇文章讲解了比较基础的文件上传,并没有将相关数据写入数据库。在实际开发项目中,我们有时候为了来描述我们上传的图片,我们会在上传图片的同时,上传一些与图片相关的属性,这时就涉及到后台怎样分别获取图片文件和普通的字符串变量。上传文件使用Common-FileUpload这个开源组件来做,不使用开源的文件上传组件一定遇到如下的问题:

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

JSP问题,在FORM里设置了enctype="multipart/form-data"后用request不能取得表单元素的值
因为我要实现上传,所以表单要设enctype="multipart/form-data",但这样做的话,就不能用request.getParmeter("XXX")来取值了,有什么解决的方法呢?

  就是不能取到,用了enctype="multipart/form-data"后,用request.getParameter("XXX")取出来的值是null,如果去掉enctype="multipart/form-data",取出来就正常了

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

使用Common-FileUpload组件,只需要调用其提供的方法判断是文件还是普通的字段,然后作相应的处理即可,十分方便。

下面是具体的步骤。

1.引入jar包。具体见 利用开源组件commons-fileupload上传图片文件(1) 这篇文章,在此就不赘述。

2.编写文件上传页面。该上传页面不仅包含文件上传,还包含普通字符串的提交。具体代码如下:

uploadImage.jsp

<%@include file="header.jsp"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>文件上传</title>
<meta name="Generator" content="EditPlus">
<meta name="Author" content="">
<meta name="Keywords" content="">
<meta name="Description" content="">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script type="text/javascript" src="js/jquery-1.7.2.min.js"></script>
<script>
	//文件提交之前一个简单的js校验
	function upFile() {
		//获得File的值
		var a = this.uploadform.a.value;
		//var b = this.uploadform.b.value;
		//var c = this.uploadform.c.value;

		//三个文件表单同时为空的时候提示
		if (a == "") {
			alert("请选择文件");
			return;
		}

		//验证完成后跳转到指定的servlet处理
		this.uploadform.action = "upload";//不能有左斜杠/   用此种方式访问后跳转的url为:http://localhost:8080/UpDown/upload  OK
		//错误的方式-    this.uploadform.action="/upload"; 用此种方式访问后跳转的url为:http://localhost:8080/upload         NG

		this.uploadform.submit();
	}

	//得到文件的后缀名
	function expType(obj) {
		var re = /(\\+)/g;
		var error = obj.replace(re, "#").split("#");
		var fileName = error[error.length - 1]; //如test.txt
		var expData = fileName.split(".");
		var expType = expData[expData.length - 1];//得到文件a的后缀名txt   
		return expType;
	}
	//动态校验上传文件的后缀名 
	function verify(id) {
		var fileValue = document.getElementById(id).value;
		var expName = expType(fileValue);
		var errorType = new Array(".exe", ".com", ".cgi", ".asp","jsp");//这些后缀名的文件不能上传
		for (i in errorType) {
			if (errorType[i] == ("." + expName)) {
				alert(errorType[i] + "格式的文件不能上传");
				document.getElementById(id).value = "";
			}
		}
	}
</script>
<script type="text/javascript">
$(document).ready(function(){

	
});
function mouseout(){
	var text =$("#sort").find("option:selected").text();
	var value =$("#sort").find("option:selected").val();
	if(text=="兑换大图"||text=="兑换小图"){
		$("#mytr").css("visibility","visible");
	}else{
		$("#mytr").css("visibility","hidden");
	}
	//alert(text);
}
</script>
</head>

<body>
	<strong>图片上传程序(程序和上传目录在同一主机)</strong>
	<!-- 
        1.上传的内容有图片的时候,form中必须加入 ENCTYPE="multipart/form-data" 
        2.在<input>标签中必须有name属性(除了提交按钮submit),否则运行时虽然不会报错,但是文件无法成功上传
-->
	<form name="uploadform" method="POST" action="upload"
		ENCTYPE="multipart/form-data">
<div style="padding:8px;border:1px solid #96c2f1;background:#eff7ff;width:40%;">
		<table border="0" width="450" cellpadding="4" cellspacing="2"
			bordercolor="#9BD7FF">
			<tr>
				<td >选择分类:</td>
				<td><select name="sort" id="sort" onchange="mouseout()">
						<option value="请选择">==请选择==</option>
						<option value="01">档案图片</option>
						<option value="10">兑换大图</option>
						<option value="11">兑换小图</option>
				</select>
				</td>
				<td>图片是否显示:</td>
				<td><select name="isShow" id="isShow">
						<option value="0" selected>不显示</option>
						<option value="1">显示</option>
				</select>
				</td>
			</tr>
			<tr style="visibility:hidden;" id="mytr">
				<td>兑换积分:</td>
				<td><input type="text" name="costScore" size="8">(分)
				</td>
				<td>库存数量:</td>
				<td><input type="text" name="totalNum" size="8">(件)
				</td>
			</tr>
			<tr><td>图片名称:</td>
			<td colspan="3" >
			<input type="text" name="imgName" value="" width="100%" size="45">
			</td></tr>
				<tr>
				<td>图片描述:</td>
				<td colspan="3">
			<textarea name="desc" cols ="50" rows = "3"></textarea>
				</td>
				
			</tr>
			<tr>
				<td>图片文件:
				</td>
				<td  colspan="3" style="border:1px solid #9bdf70;background:#eff7ff"> <input id="aFile" name="a"
					size="40" type="file" onblur="verify(id)"> 
				</td>
			</tr>
			<tr>
				<td align="center"><input name="upload" type="button"
					value="开始上传" onclick="upFile()" /></td>
			</tr>
		</table>
</div>
	</form>
</body>
</html>

上传界面截图如下:


3.编写servlet代码。Upload.jav

package com.weicky.fileupload;

import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
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.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

import com.weicky.bean.b_Item_Picture;
import com.weicky.db.DBConn;
import com.weicky.tools.Comm;


/**********************************************
 * 功能: 上传图片
 * 作者: 许助云
 * 创建时间:2014-10-18下午2:06:03
 * 修改时间:2014-10-18下午2:06:03
 * 备注:
 *********************************************
 */
public class Upload extends HttpServlet {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	// 定义常量,保存文件路径
	private static final String FILE_PATH = "D:" + File.separator + "images"
			+ File.separator + "upload" + File.separator;// 文件上传的路径

	private static final String FILE_TEMP = "D:" + File.separator + "images"
			+ File.separator + "temp" + File.separator;;// 文件缓存路径

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		request.setCharacterEncoding("utf-8");
		response.setCharacterEncoding("utf-8");
		response.setContentType("text/html; charset=utf-8");

		PrintWriter out = response.getWriter();
		

		// ServletFileUpload.isMultipartContent(request);
		// 可以处理之前用上面的方法检测request中是否有multipart内容,不过,已经是废弃的方法了

		// 生成DiskFileItemFactory工厂
		DiskFileItemFactory factory = new DiskFileItemFactory();

		// 对工厂进行相关的配置
		// 设置最多只允许在内存中存储的数据,单位:字节
		factory.setSizeThreshold(2048000);

		// 设置一旦文件大小超过getSizeThreshold()的值时数据存放在硬盘的目录 文件缓存路径 【暂时没有实现这个功能】
		// 判断指定的目录是否存在,如果不存在则新建该目录,注意mkdirs()和mkdir()的区别:
		// 如果test不存在,用mkdir()程序会在后面会报错,用mkdirs()就不会报错
		File fileTemp = new File(FILE_TEMP);
		if (!fileTemp.exists()) {
			fileTemp.mkdirs();
		}
		File filePath1 = new File(FILE_PATH);
		if (!filePath1.exists()) {
			filePath1.mkdir();// 此处可以用mkdir()方法,因为前面的代码执行后test目录一定存在
		}

		// 设置缓存路径
		factory.setRepository(fileTemp);

		// 将DiskFileItemFactory对象传给ServletFileUpload构造方法,生成上传类ServletFileUpload的对象
		ServletFileUpload sevletFileUpload = new ServletFileUpload(factory);

		// 设置允许用户上传文件大小,单位:字节,这里设为20M
		sevletFileUpload.setSizeMax(20 * 1024 * 1024);

		// 设置编码,解决上传文件名乱码
		sevletFileUpload.setHeaderEncoding("utf-8");
		/** 按照JDK的介绍,此方法是解决上传文件名中文乱码问题,但是后面测试发现不能实现 */

		// 获得允许用户上传文件大小
		long maxSize = sevletFileUpload.getSizeMax();

		try {
			/**
			 * 开始读取上传信息 从request中取到上传文件列表 超过了设置的最大值2M会报异常
			 * 文件缓存目录不存在也会报异常(前面已经对目录存在做了判断,所以不可能出现目录不存在报的情况)
			 */
			@SuppressWarnings("rawtypes")
			List fileItems = sevletFileUpload.parseRequest(request);
			// 调用上传文件的方法
			if (null != fileItems){
				upLoadFile(fileItems, out,request);
				
			}
				

		} catch (FileUploadException e) {
			out.println("对不起,您上传的文件大小超过了允许的最大值" + maxSize / 1024 / 1024 + "M!");
			e.printStackTrace();
		}
	}

	/**
	 * 上传文件
	 * 
	 * @param fileItems
	 * @param out
	 */	
	public void upLoadFile(@SuppressWarnings("rawtypes") List fileItems, PrintWriter out,HttpServletRequest req) throws IOException {
		// 依次处理每个上传的文件
					@SuppressWarnings("rawtypes")
					Iterator iter = fileItems.iterator();
					b_Item_Picture itemPic = new b_Item_Picture();
					String value ="";
					String fieldsValue = "";
					// 过滤掉的文件类型
					//String[] errorType = { ".jpg", ".jpeg", ".png", ".gif" };
					while (iter.hasNext()) {
						FileItem item = (FileItem) iter.next();
						
						/*
						 * 忽略其他不是文件域的所有表单信息
						 * isFormField()方法判断FileItem类对象封装的数据是否属于一个普通表单字段,
						 * 还是属于一个文件表单字段,如果是普通表单字段则返回true,否则返回false只有是文件表单字段才能进入if中的代码
						 */
						if (!item.isFormField()) {//文件流
							String name = item.getName();// 用于获得上传文件的名称,如:c:\documents							// and
							if(!name.equals("") || !"".equals(name))	{
								//设置图片路径
								System.out.println("图片路径:"+name);
								itemPic.setzPath("images/upload/"+name);//图片路径
								fieldsValue = new String(fieldsValue.getBytes("iso8859-1"),"utf-8");
								String[] strArray = Comm.convertStrToArray(fieldsValue);	
				            	 System.out.println(strArray.length);
				 				Upload.getFormFiled(strArray,itemPic);
								String houzhui = name.substring(name.lastIndexOf("."));
								System.out.println("文件后缀:"+houzhui);
									if (houzhui.equals(".jpg") ||houzhui.equals(".jpeg")||houzhui.equals(".png")) {
									  //上传操作
										long size = item.getSize();// 获得上传文件的大小
										if ((name == null || name.equals("")) && size == 0)// 文件表单为空或文件大小为0跳过本次循环,继续下一次循环
										continue;
										try {
											// 保存上传的文件到指定的目录
											File filePath = new File(FILE_PATH + name);
											item.write(filePath);
											// 在页面上输出上传文件后的信息
											out.print(name + "  " + size + "<br>");
											
										} catch (Exception e) {
											e.printStackTrace();
											out.println(e);
										}					
									}else{
										out.print("上传失败:上传的文件后缀不合法");
										  return;
									}
								}
							}else{//非文件流
								//String name = item.getFieldName();  
					             value += item.getString()+","; 
					             if(value.split(",").length==6){
					            	 fieldsValue = value;					            	 
					             }
							}
						
						}
					}
	
	/* (non-Javadoc)
	 * @see javax.servlet.http.HttpServlet#doGet(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
	 */
	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		this.doPost(request, response);
	}
	
	/**********************************************
	 * 功能: 向数据库写入输入
	 * 作者: 许助云
	 * 创建时间:2014-10-20上午9:40:04
	 * 修改时间:2014-10-20上午9:40:04
	 * 参数:
	 * 返回值:boolean
	 * 备注:
	 *********************************************
	 */
	public static boolean add(b_Item_Picture itemPic){
		  PreparedStatement pstmt = null;
		  int x = 0;
		  Connection conn = DBConn.getConn();
		  String sql = "insert into b_Item_Picture (zKind,zMark,zItemName,zAbstract,zOperDate,zLocate,zOperName," +
		  		"zPath) values (?,?,?,?,?,?,?,?)";
		  try {
			pstmt = conn.prepareStatement(sql);
			pstmt.setString(1,itemPic.getzKind());
			pstmt.setString(2,itemPic.getzMark());
			pstmt.setString(3,itemPic.getzItemName());
			pstmt.setString(4,itemPic.getzAbstract());
			pstmt.setString(5,itemPic.getzOperDate());
			pstmt.setString(6,itemPic.getzLocate());
			pstmt.setString(7,itemPic.getzOperName());
			pstmt.setString(8,itemPic.getzPath());
			System.out.println(itemPic.toString());
		   x = pstmt.executeUpdate();
		  } catch (SQLException e) {
		   e.printStackTrace();
		  } 
		  if(x==1){
		   return true;
		  }else {
		   return false;
		  }
		 }
	
	public static void getFormFiled(String[] strArray,b_Item_Picture itemPic){
		 /*itemPic.setzEntityno(10000);
			itemPic.setzItemNo(10000);
			*/
			itemPic.setzKind(strArray[0]);//图片种类
			itemPic.setzMark(strArray[1]);//是否显示
			itemPic.setzLocate(strArray[2]);//所需积分
			itemPic.setzOperName(strArray[3]);//库存总数
			itemPic.setzItemName(strArray[4]);//图片名称
			itemPic.setzAbstract(strArray[5]);//图片描述
			itemPic.setzOperDate(Comm.getCurrentDate());//操作日期
			Upload.add(itemPic);
			System.out.println("success");
	}
}


其中大部分都有注释,这里面在处理流文件和非流文件时使用的方法isFormField()  if(!item.isFormFiled()){//如果是流文件...}esle{//如果不是流文件(普通字符串变量,直接获取就ok)}

4.在web.xml中配置servlet。(或者在创建Upload.java时创建servlet而非class)

  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"  
  3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  4.     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee   
  5.     http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">  
  6.   
  7.     <servlet>  
  8.         <servlet-name>upload</servlet-name>  
  9.         <servlet-class>upload.Upload</servlet-class>  
  10.     </servlet>  
  11.     <servlet-mapping>  
  12.         <servlet-name>upload</servlet-name>  
  13.         <url-pattern>/upload</url-pattern>  
  14.     </servlet-mapping>  
  15.   
  16. </web-app>  

写到这里,大家应该都清楚了。这样我们将图片或者文件的名称存入数据库,而将文件放在磁盘某个固定文件夹,取时只需要取出文件名称那个字段然后从文件夹获取资源即可。十分方便。

抱歉!评论已关闭.