当前位置: 代码迷 >> Web前端 >> smartupload组件(文件下传功能)
  详细解决方案

smartupload组件(文件下传功能)

热度:449   发布时间:2012-09-04 14:19:30.0
smartupload组件(文件上传功能)

smartupload 组件:完成上传文件功能。一般使用表单的 file 元素:

<form >

?????? 上传图片: <input type="file" name="pic">

</form>

常见的上传组件:

Smartupload Apache 公司的 Fileupload

上传:

完成上传功能需要 smartupload 组件的支持,也就是 smartupload.jar 文件,将他放到根目录下的 WEB-INF 下的 lib 文件夹中。

注意:开发中表单中上传文件时,表单的提交方式一定要设置成 post

图片上传(表单封装)

范例 :图片上传

upload.jsp

<%@page contentType="text/html;charset=gb2312"%>

<html>

?????? <body>

????????????? <form action="smart.jsp" method="post" >

???????????????????? 上传图片: <input type="file" name="pic">

???????????????????? <input type="submit" value=" 上传 ">

????????????? </form>

?????? </body>

</html>

smart.jsp

根目录下建立一个名为 upload 的文件夹。用于存放上传的文件。

<%@ page language="java" import="java.util.*" pageEncoding="GBK"%>

<jsp:useBean id="smartupload" class="org.lxh.smart.SmartUpload"/>

<html>

?????? <body>

?????? <%

????????????? smartupload.initialize(pageContext);?????? ??? // 初始化上传

????????????? smartupload.upload();???????????????????????????? // 准备上传

????????????? smartupload.save("upload"); ????????? ??? ? // 保存文件

?????? %>

?????? </body>

</html>

运行结果: 发现上传之后在 upload 中找不到我们上传的图片。

原因: 正常情况下我们用表单提交的是文本数据,而此处要上传文件,那么就必须对表单进行封装。

form 表单中存在的一个 enctype 属性。用于封装我们的表单。

修改 upload.jsp

<%@page contentType="text/html;charset=gb2312"%>

<html>

?????? <body>

????????????? <form action="smart.jsp" method="post" enctype="multipart/form-data" >

???????????????????? 上传图片: <input type="file" name="pic">

???????????????????? <input type="submit" value=" 上传 ">

????????????? </form>

?????? </body>

</html>

运行结果 :正常上传。而且文件名称与上传前的名称一致。

表单封装后, request 无法取得参数

范例:

修改 upload.jsp

<%@page contentType="text/html;charset=gb2312"%>

<html>

?????? <body>

????????????? <form action="smart.jsp" method="post" >

姓名: <input type=”text” name=”name”><br>

???????????????????? 上传图片: <input type="file" name="pic">

???????????????????? <input type="submit" value=" 上传 ">

????????????? </form>

?????? </body>

</html>

修改 smart.jsp

<%@ page language="java" import="java.util.*" pageEncoding="GBK"%>

<jsp:useBean id="smartupload" class="org.lxh.smart.SmartUpload"/>

<html>

?????? <body>

?????? <%

String name = request.getParameter(“name”);

????????????? smartupload.initialize(pageContext);???? ??? // 初始化上传

????????????? smartupload.upload();??????????????????????????????? // 准备上传

????????????? smartupload.save("upload"); ????????????? ???????? // 保存文件

?????? %>

?????? </body>

</html>

修改之后发现,通过 request.getParameter() 方法无法获取提交过来的参数 name

应该使用 smartupload request 方法。

修改 smart.jsp

<%@ page language="java" import="java.util.*" pageEncoding="GBK"%>

<jsp:useBean id="smartupload" class="org.lxh.smart.SmartUpload"/>

<html>

?????? <body>

?????? <%

????????????? smartupload.initialize(pageContext);???? ??? // 初始化上传

????????????? smartupload.upload();??????????????????????????????? // 准备上传

????????????? smartupload.save("upload"); ????????????? ???????? // 保存文件

String name = smartupload.getRequest().getParameter(“name”);

?????? %>

?????? </body>

</html>

这样之后就可以接受表单提交过来的参数了。

但是要注意 :虽然 request getParameter 方法不能够在此处使用,但是 request 的其他方放照样可以继续使用。

?

但是这种情况下我们也不难发现,如果上传已经上传过的图片(因为上传后文件名称不变),所以存放上传照片的文件夹里会出现‘后上传的覆盖掉原来上传的同名文件’的情况。

为上传文件手动更改名称

前台输入文件名称。

修改文件名称时要保持文件后缀不变。

修改 smart.jsp

<%@ page language="java" import="java.util.*" pageEncoding="GBK"%>

<jsp:useBean id="smartupload" class="org.lxh.smart.SmartUpload"/>

<html>

?????? <body>

?????? <%

????????????? smartupload.initialize(pageContext);???? ??? // 初始化上传

????????????? smartupload.upload();??????????????????????????????? // 准备上传

String name = smartupload.getRequest().getParameter(“name”);// 从客户端获取文件名

String ext = smartupload.getFiles().getFile(0).getFileExt();// 获取上传文件的后缀, 0 表示第一个上传的文件

name = name + “.” +ext;// 完整的文件名称

String path = this.getServletContext().getRealPath(“/”)+”upload/”+name;// 获取完整的保存路径

smartupload.getFiles().getFile(0).saveAs(path);// 保存文件, saveAs 中的参数必须为完整的保存路径名

?????? %>

??? <img src = “upload/”<%=name%> width=”” height=””>// 显示上传后的图片

?????? </body>

</html>

但是以上程序也存在问题,就是无法保证用户输入的文件名称不会重复。

所以我们将对上传的文件自动更名。

为上传文件自动更改名称

如何才能让文件名称不会重复呢?

可以这样设置文件名称:

IP 地址 + 时间戳 + 三位随机数

但是这里又有问题了,就是 IP 的补 0 问题。例如 IP 162.198.80.7 。这样出来的名称要这样的形式 162198080007 。所以我们创建一个 javaBean 来用于生成文件名称。

范例: IPTimeStamp.java

import java.text.SimpleDateFormat;

import java.util.Random;

?

public class IPTimeStamp {

?????? private String ip;

?

?????? public IPTimeStamp() {

?????? }

?

?????? public IPTimeStamp(String ip) {

????????????? this.ip = ip; // 通过 IPTimeStamp 的构造方法设置 ip 地址

?????? }

??? // 生成时间的方法,例如: 20111201213523

?????? public String getTimeStamp() {

????????????? String temp = null;

????????????? SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS");

????????????? temp = sdf.format(new java.util.Date());

????????????? return temp;

?????? }

?? ? // 生成我们要求的格式的 IP

?????? public String getIPTimeStampRand() {

????????????? StringBuffer buf = new StringBuffer();

????????????? if (ip != null) {

???????????????????? String str[] = this.ip.split("\\.");// 按照“ . “来拆分

???????????????????? for (int i = 0; i < str.length; i++) {

??????????????????????????? buf.append(this.addZero(str[i], 3));// 将拆分完的并且补 0 之后的放入 buf

???????????????????? }

????????????? }

????????????? buf.append(this.getTimeStamp());// 将生成好格式的时间放入 buf

????????????? Random rand = new Random();

????????????? for (int i = 0; i < 3; i++) {

???????????????????? buf.append(rand.nextInt(10)) ;// 将生成好的随机数放入 buf

????????????? }

????????????? return buf.toString() ;

?????? }

?? ? //ip 被拆分后怎么补 0 的方法

?????? private String addZero(String str, int len) {

????????????? StringBuffer s = new StringBuffer();

????????????? s.append(str);

????????????? while (s.length() < len) {

???????????????????? s.insert(0, "0");

????????????? }

????????????? return s.toString();// 返回生成好的文件名称

?????? }

}

修改 upload.jsp

<%@page contentType="text/html;charset=gb2312"%>

<html>

?????? <body>

????????????? <form action="smart.jsp" method="post" >

???????????????????? 上传图片: <input type="file" name="pic">

???????????????????? <input type="submit" value=" 上传 ">

????????????? </form>

?????? </body>

</html>

修改 smart.jsp

<%@ page language="java" import="java.util.*" pageEncoding="GBK"%>

<%@ page import="org.lxh.util.*"%>

<jsp:useBean id="smartupload" class="org.lxh.smart.SmartUpload"/>

<html>

?????? <body>

?????? <%

????????????? IPTimeStamp its = new IPTimeStamp(request.getRemoteAddr()) ; // IP 传入,获取生成文件名称类的对象

????????????? request.setCharacterEncoding("GBK") ;

????????????? smartupload.initialize(pageContext) ;??? // 初始化上传

????????????? smartupload.upload() ;?????????????????????????????? // 准备上传

????????????? String name=its. getIPTimeStampRand()+"."+ smartupload.getFiles().getFile(0).getFileExt() ;// 通过 IPTimeStamp 的对象获取到生成好的文件名称,并组合好完整的文件名称(包含后缀名)

????????????? String fileName = this.getServletContext().getRealPath("/") + "upload/" + name ;// 将上传好的文件放到虚拟目录下的 upload 文件夹下

????????????? smartupload.getFiles().getFile(0).saveAs(fileName) ;

?????? %>

?????? <img src="upload/<%=name%>" width="300" height="200">

?????? </body>

</html>

上传说明

一般在系统开发中,需要将一些图片的信息保存在数据库中。一般有两种方式。

第一种:

?????? 直接在数据库中保存图片信息,通过 BLOG 字段存储。

?????? ?? 如果上传文件比较大,那么这种方式不方便。

如果数据库备份时,仅仅备份数据库即可。

第二种:

????????????? 直接将图片放到指定的文件夹中,然后在数据库中以普通文本的信息保存图片的路径。

????????????? 如果上传文件比较大,那么这种方式方便。

????????????? 如果数据库备份时,不仅得备份数据库,还有备份图片信息。

范例: 保存图片路径。(第二种方式)

有如下数据库脚本( Oracle

DROP SEQUENCE myseq ;

DROP TABLE person ;

CREATE SEQUENCE myseq ;

CREATE TABLE person(

?????? id?????????? NUMBER???????????? PRIMARY KEY NOT NULL ,

?????? name????????????? VARCHAR2(60)??? NOT NULL ,

?????? photo???????????? VARCHAR2(100)?

) ;

完成两个功能: 1. 插入信息。 2. 从数据库中将全部的信息列表显示。

insert.htm

<html>

?????? <body>

????????????? <form action="insert.jsp" method="post" enctype="multipart/form-data">

???????????????????? 姓名: <input type="text" name="name"><br>

???????????????????? 上传的图片: <input type="file" name="pic"><br>

???????????????????? <input type="submit" value=" 上传 ">

????????????? </form>

?????? </body>

</html>

之后建立一个连接数据库类,用于连接数据库操作。

DataBaseConnection.java

import java.sql.Connection;

import java.sql.DriverManager;

import java.sql.SQLException;

?

public class DataBaseConnection {

?????? public static final String DBDRIVER = "oracle.jdbc.driver.OracleDriver" ;

?????? public static final String DBURL = "jdbc:oracle:thin:@localhost:1521:MLDN" ;

?????? public static final String DBUSER = "scott" ;

?????? public static final String DBPASS = "tiger" ;

?????? private Connection conn? = null ;

?????? public DataBaseConnection(){

????????????? try {

???????????????????? Class.forName(DBDRIVER) ;

???????????????????? conn = DriverManager.getConnection(DBURL,DBUSER,DBPASS) ;

????????????? } catch (ClassNotFoundException e) {

???????????????????? // TODO Auto-generated catch block

???????????????????? e.printStackTrace();

????????????? } catch (SQLException e) {

???????????????????? // TODO Auto-generated catch block

???????????????????? e.printStackTrace();

????????????? }

?????? }

?????? public Connection getConnection(){

????????????? return this.conn ;

?????? }

?????? public void close(){

????????????? if(this.conn!=null){

???????????????????? try {

??????????????????????????? this.conn.close() ;

???????????????????? } catch (SQLException e) {

??????????????????????????? e.printStackTrace();

???????????????????? }

????????????? }

?????? }

}

insert.jsp

<%@ page language="java" import="java.util.*" pageEncoding="GBK"%>

<%@ page import="java.sql.*"%>

<%@ page import="org.lxh.util.*"%>

<jsp:useBean id="smartupload" class="org.lxh.smart.SmartUpload"/>

<jsp:useBean id="dbc" class="org.lxh.dbc.DataBaseConnection"/>

<html>

?????? <body>

?????? <%

????????????? request.setCharacterEncoding("GBK") ;

?????? try{

????????????? IPTimeStamp its = new IPTimeStamp(request.getRemoteAddr()) ;

????????????? request.setCharacterEncoding("GBK") ;

????????????? smartupload.initialize(pageContext) ;??? // 初始化上传

????????????? smartupload.upload() ;?????????????????????????????? // 准备上传

????????????? String photoname = its.getIPTimeStampRand() + "." + smartupload.getFiles().getFile(0).getFileExt() ;

????????????? String sql = "INSERT INTO person(id,name,photo) VALUES (myseq.nextVal,?,?)" ;

????????????? PreparedStatement pstmt = dbc.getConnection().prepareStatement(sql) ;

????????????? pstmt.setString(1,smartupload.getRequest().getParameter("name")) ;

????????????? pstmt.setString(2,photoname) ;

????????????? pstmt.executeUpdate() ;

????????????? pstmt.close() ;

????????????? String fileName = this.getServletContext().getRealPath("/") + "upload/" + photoname ;

????????????? smartupload.getFiles().getFile(0).saveAs(fileName) ;

?????? }catch(Exception e){

?????? }finally{

?????? ?????? dbc.close() ;

?????? }

?????? %>

?????? </body>

</html>

显示

list.jsp

<%@ page language="java" import="java.util.*" pageEncoding="GBK"%>

<%@ page import="java.sql.*"%>

<%@ page import="org.lxh.util.*"%>

<jsp:useBean id="dbc" class="org.lxh.dbc.DataBaseConnection"/>

<html>

?????? <body>

?????? <%

????????????? request.setCharacterEncoding("GBK") ;

?????? try{

????????????? String sql = "SELECT id,name,photo FROM person " ;

????????????? PreparedStatement pstmt = dbc.getConnection().prepareStatement(sql) ;

????????????? ResultSet rs = pstmt.executeQuery() ;

?????? %>

????????????? <center>

????????????? <table border="1" width="80%">

???????????????????? <tr>

??????????????????????????? <td> 编号 </td>

??????????????????????????? <td> 姓名 </td>

??????????????????????????? <td> 照片 </td>

???????????????????? </tr>

????????????? <%

???????????????????? while(rs.next()){

??????????????????????????? int id = rs.getInt(1) ;

??????????????????????????? String name = rs.getString(2) ;

??????????????????????????? String photo = rs.getString(3) ;

????????????? %>

???????????????????? <tr>

??????????????????????????? <td><%=id%></td>

??????????????????????????? <td><%=name%></td>

??????????????????????????? <td><img src="upload/<%=photo%>" width="30" height="25"></td>

???????????????????? </tr>

????????????? <%

???????????????????? }

????????????? %>

????????????? </table>

????????????? </center>

?????? <%

????????????? pstmt.close() ;

?????? }catch(Exception e){

?????? }finally{

????????????? dbc.close() ;

?????? }

?????? %>

?????? </body>

</html>