图片上传之fileupload

最近学习了图片上传这个功能,这个功能比较常见,因此来整理一下,了解上传的基本原理,以便后期遇到图片上传功能可以很快上手。

要说图片上传,我们先来说一下图片上传后存储的两种方式:一种是将图片存储到数据库中;一种是将图片存储在服务器文件目录中。首先,对于将图片存储到数据库中适合数据量小的情况,因为写到数据库的图片需要转换成二进制流的格式,占用数据空间比较,适合少量图片的存储,比如,系统中某些小图标,写到数据库中的优点是比较安全,不容易被用户不小心删除。但是,图片存在数据库的操作方面的局限性太大,还要拼凑sql,db
server还要parse sql, write into file,读写性能不高,备份越来越大。如果是大量的图片存储通常的做法是保存到服务器的某个目录下。一方面,其完成图片上传有很多方式,可以采用流的方式,可以采用ftp的方式等;另一方面备份方便(只备DB),读取高性能。这种方式便于直接访问,适用于直接显示方面的需求,但路径与图片的映射容易出问题。对于超级大型应用,需要的是数据库的批量查询和返回结果,这时应用分布式将图片存储在数据库中,比如谷歌的Bigtable,也可以理解成nosql,以及Amazon的S3存储服务是基于文档型数据库的,也是nosql。现在很多网站直接把自己的二进制数据放在S3,能够满足全球分布式管理,并且不用自己动手。想说一句,看应用的规模,以及扩展性的需要,选择适合的图片存储方式,没有绝对的答案。

下面我将以图片存储在服务器目录中的形式,介绍一下fileupload方式的图片上传。common-fileupload组件是apache的一个开源项目之一,可以从http://jakarta.apache.org/commons/fileupload/下载。该组件简单易用,可实现一次上传一个或多个文件,并可限制文件大小。

下面我就讲一下基本实现:

首先需要在lib目录下引入:commons-io-1.3.2.jar和commons-fileupload-1.3.1.jar。

前端代码:

<span style="font-size:14px;"><%@ page language="java" import="java.util.*" pageEncoding="GB18030"%>
<html>
  <head>

    <title>fileUpload</title>

    <meta http-equiv="Content-Type" content="text/html; charset=GB18030">

  </head>

  <body>

   <form action="./servlet/FileUploadServlet" method="post" enctype="multipart/form-data" name="form1">

     <input type="file" name="file">

     <input type="submit" name="Submit" value="upload">

   </form>

   <form action="./servlet/HelloWord" method="post">

    <input type="submit"/>

   </form>

    <form name="uploadform" method="POST" action="./servlet/FileUploadServlet" ENCTYPE="multipart/form-data">

        <table border="1" width="450" cellpadding="4" cellspacing="2" bordercolor="#9BD7FF">

        <tr><td width="100%" colspan="2">

                        文件1:<input name="x" size="40" type="file">

        </td></tr>

        <tr><td width="100%" colspan="2">

                        文件2:<input name="y" size="40" type="file">

        </td></tr>

        <tr><td width="100%" colspan="2">

                        文件3:<input name="z" size="40" type="file">

        </td></tr>

        </table>

        <br/><br/>

        <table>

        <tr><td align="center"><input name="upload" type="submit" value="开始上传"/></td></tr>

       </table>

     </form>

  </body>
</html>
</span>

注意:文件上传在前端要使用file标签,采用form表单提交enctype=" multipart/form-data
" 。关于enctype="multipart/form-data"的说明:在jsp中使用了该格式,对应的Servlet就不能使用request.getParameter()取得参数,要使用ServletFileUpload对象的parseRequest方法先把request对象中的数据解析,然后,使用解析出的元素的isFormField标志,配合getFieldName方法来获取数据。

java代码:

<span style="font-size:14px;">package uploadPack;

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

@SuppressWarnings("serial")
public class FileUploadServlet extends HttpServlet {

	 //存储图片到数据库类的方法
	 ItemManager itemManager  = new  ItemManagerImpl() ; 

	 //用于存放上传文件
	 private File uploadPath;
	 //用于存放临时文件的目录
	 private File tempPath;

	 @Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {

		 doPost(req, resp);
	}

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {

		//从test_upload.jsp中拿取数据,因为上传页的编码格式跟一般的不同,使用的是enctype="multipart/form-data"
		//form提交采用multipart/form-data,无法采用req.getParameter()取得数据

		//DiskFileItemFactory:创建FileItem对象的工厂,这个工厂类中可以配置内存缓冲池大小和临时文件的目录
		 DiskFileItemFactory factory = new DiskFileItemFactory();
		// maximum size that will be stored in memory
		 factory.setSizeThreshold(4096);
		// the location for saving data that is larger than getSizeThreshold()
		 factory.setRepository(tempPath);

		 //ServletFileUpload:负责处理上传的文件数据,并将每部分的数据封装成到FileItem对象中

		 //在接收上传文件数据时,会将内容保存到内存缓存区中,如果文件内容超过了 DiskFileItemFactory 指定的缓冲区的大小,
         //那么文件将被保存到磁盘上,存储为DiskFileItemFactory指定目录中的临时文件
		 //等文件数据都接收完毕后,ServletFileUpload再从文件中将数据写入到上传文件目录下的文件中

		 ServletFileUpload upload = new ServletFileUpload(factory);
		// maximum size before a FileUploadException will be thrown
		 upload.setSizeMax(1000000* 100);

		 try {

			 //从test_upload.jsp中拿取数据,因为上传页的编码格式跟一般的不同,使用的是enctype="multipart/form-data"
			 //form提交采用multipart/form-data,无法采用req.getParameter()取得数据
			 List fileItems =upload.parseRequest(req);

			 //循环提交的表单
			 for (Iterator iter = fileItems.iterator(); iter.hasNext();) {

				 FileItem item = (FileItem) iter.next();
				 String itemNo = "";  

			    //判断是文件还是文本信息
                //是普通的表单输入域
                if(item.isFormField()) {
                    if ("itemNo".equals(item.getFieldName())) {  

                    	//将FileItem对象中保存的主体内容作为一个字符串返回,乱码可以加编码方式
                        itemNo = item.getString();
                    }
                }  

                 //是否为input="type"输入域
				 if(!item.isFormField()){

					//上传文件的名称和完整路径
				    String name =item.getName();
				    long size =item.getSize();

				  //判断是否选择了文件
				    if ((name ==null || name.equals("")) && size==0) {
						continue;
					}

				    //截取字符串
                    name = name.substring(name.lastIndexOf("\\") + 1, name.length());

                    //将文件保存到目录下,不修改文件名
                    item.write(new File(uploadPath, name));  

                    //将图片文件名写入打数据库
                    itemManager.uploadItemImage(itemNo, name);  

				 }

			}

			 resp.sendRedirect(req.getContextPath() + "/servlet/item/SearchItemServlet");  

		} catch (Exception e) {
			e.printStackTrace();
			throw new ApplicationException("上传失败!");  

		}
	}

	    /**
	     * 在系统启动的时候就初始化,在初始化时,检查上传图片的文件夹和存放临时文件的文件夹,如果不存在就创建
	     */
	    @Override
	    public void init() throws ServletException {  

		    //获取根目录对应的真实物理路径
	        uploadPath = new File(getServletContext().getRealPath("/upload"));  

	        //如果目录不存在
	        if (!uploadPath.exists()) {
	            //创建目录
	            uploadPath.mkdir();
	        }  

	        //临时目录
	        //File tempFile = new File(item.getName())构造临时对象
	        tempPath = new File(getServletContext().getRealPath("/temp"));
	        if (!tempPath.exists()) {
	            tempPath.mkdir();
	        }  

	 }
}
</span>

配置文件:

<span style="font-size:14px;"><?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4"
	xmlns="http://java.sun.com/xml/ns/j2ee"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
	http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
  <servlet>
     <servlet-name>FileUploadServlet</servlet-name>
     <servlet-class>uploadPack.FileUploadServlet</servlet-class>
     <load-on-startup>10</load-on-startup>
  </servlet>
  <servlet-mapping>
     <servlet-name>FileUploadServlet</servlet-name>
     <url-pattern>/servlet/FileUploadServlet</url-pattern>
  </servlet-mapping>
</web-app>
</span>

后面还会遇到很多其他上传图片的方法,会继续总结整理。

时间: 2025-01-22 12:09:18

图片上传之fileupload的相关文章

Asp.net中FileUpload控件实现图片上传并带预览显示

单一图片上传——“选择”+“上传”,.NET默认模式: 1.实现原理: 采用FileUpload控件默认的使用方式,先由“选择”按钮选择图片,然后单击“上传”按钮完成上传,并可在“上传”按钮的单击事件中加载已上传图片. 2.关键代码:     页面代码: 1 <asp:FileUpload ID="FileUpload" runat="server" /> 2 <asp:Button ID="BtnUp" runat="

图片上传

1.Body标签中增加元素 <div class="m"><img src="~/Content/images/addp.png" width="100%" onclick="uploadLogoImage(this)"/></div> <input type="file" style="display: none" id="fileU

[原创]超强C#图片上传,加水印,自动生成缩略图源代码

<%@ Page Language=“C#“ AutoEventWireup=“true“ %> <%@ Import Namespace=“System“ %> <%@ Import Namespace=“System.IO“ %> <%@ Import Namespace=“System.Net“ %> <%@ Import NameSpace=“System.Web“ %> <%@ Import NameSpace=“Legalsof

kindeditor图片上传 struts2实现

一.kindeditor以及struts2部署搭建不再赘述,如需要请参考kindeditor使用方法 Struts2框架搭建 二.kindeditor图片上传所依赖jar包在kindeditor\jsp\lib下有 三.以下列出部分核心代码,如需要全部源码可点击下载(待上传) JSP <textarea id="editor_id" name="content" style="width:950px;height:300px;"> 这

spring mvc 图片上传,图片压缩、跨域解决、 按天生成目录 ,删除,限制为图片代码等相关配置

spring mvc 图片上传,跨域解决 按天生成目录 ,删除,限制为图片代码,等相关配置 fs.root=data/ #fs.root=/home/dev/fs/ #fs.root=D:/fs/ #fs.domains=182=http://172.16.100.182:18080,localhost=http://localhost:8080 <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE be

ASP.NET Core 简单实现七牛图片上传(FormData 和 Base64)

七牛图片上传 SDK(.NET 版本):https://developer.qiniu.com/kodo/sdk/1237/csharp UpoladService示例代码: public class UpoladService : IUpoladService {     private readonly static string[] _imageExtensions = new string[] { ".jpg", ".png", ".gif&quo

springmvc上传图片并显示图片--支持多图片上传

实现上传图片功能在Springmvc中很好实现.现在我将会展现完整例子. 开始需要在pom.xml加入几个jar,分别是: [java] view plain copy <dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>1.3.1</version> </dep

CKEditor实现图片上传

本人用的CKEditor版本为4.3 CKEditor配置和部署参考CKEditor4.x部署和配置. CKEditor编辑器的工具栏中初始的时候应该是这样子的,没有图片上传按钮 并且预览中有一堆火星文,可以修改相应配置删除它. 第一种方法:打开ckeditor/plugins/image/dialogs/image.js文件,搜索“b.config.image_previewText”,(b.config.image_previewText||'')单引号中的内容全删了,注意别删多了.(由于c

图片上传那些事

简述: 一个项目上,之前已经做好了用flash上传图片的功能,但是现在因为客户端的限制,要求不用flash,可以使用html5,于是改造开始了. 先给出之前flash的界面: 需求:  上面的图片里面可以看出三个需求: 1. 文件选择按钮外观需要美化 2. 可以预览图片 3. 上传图片(上传后的图片存在形式需要与之前flash上传的一样,也就是说需要byte[]的形式) 用户上传图片之后,需要把新的图片显示到其他位置,所以还有一个需求: 4. 上传成功后调用回调函数 思考: 1. 文件选择按钮外