JSP教程(九)—— 文件上传

使用工具:SmartUpload组件,该包已在https://pan.baidu.com/s/1qZcymBE中。

1  上传单个文件

要想进行上传,则必须使用HTML中提供的file控件,而且<form>也必须使用enctype进行封装。

【注】使用enctype封装:表示表单将按照二进制的方式提交,即所有操作表单此时不再是分别提交,而是将所有内容都按照二进制的方式提交。

实例1

上传表单(demo1_1.html)

 1 <html>
 2     <head>
 3         <title>上传单个文件</title>
 4     </head>
 5     <body>
 6         <form action="demo1_2.jsp" method="post" enctype="multipart/form-data">
 7             请选择文件:<input type="file" name="pic">
 8             <input type="submit" value="上传">
 9         </form>
10     </body>
11 </html>

接收图片并保存(demo1_2.jsp)

 1 <%@ page contentType="text/html" pageEncoding="GBK" %>
 2 <%@ page import="org.lxh.smart.*" %>
 3 <html>
 4     <head>
 5         <title>上传单个文件</title>
 6     </head>
 7     <body>
 8         <%
 9             SmartUpload smart = new SmartUpload();//实例化SmartUpload上传组件
10             smart.initialize(pageContext);//初始化上传操作
11             smart.upload();//上传准备
12             smart.save("upload");//将上传文件保存在upload文件夹中
13         %>
14     </body>
15 </html>

在使用SmartUpload时必须严格按照如上程序进行,而最后在保存时只是写了一个upload,表示上传文件的保存文件夹,此文件夹要在根目录中手工建立。

通过demo1_1.html选择的文件,提交到demo1_2.jsp时将会自动保存,而且保持的文件名称与上传的文件名称一样,所以当上传了同样名称的图片时将会出现覆盖的情况。

2  混合表单

如果要上传文件,则表单必须封装,但是当一个表单使用了enctype封装后,其他的非表单控件的内容就无法通过request内置对象取得,此时必须通过SmartUpload类中提供的getRequest()方法取得全部的请求参数。

实例2

上传表单(demo2_1.html)

 1 <html>
 2     <head>
 3         <title>混合表单</title>
 4     </head>
 5     <body>
 6         <form action="demo2_2.jsp" method="post" enctype="multipart/form-data">
 7             姓名:<input type="text" name="uname"><br>
 8             照片:<input type="file" name="pic"><br>
 9             <input type="submit" value="上传">
10             <input type="reset" value="重置">
11         </form>
12     </body>
13 </html>

接收表单文本、图片并保存(demo2_2.jsp)

 1 <%@ page contentType="text/html" pageEncoding="GBK"%>
 2 <%@ page import="org.lxh.smart.*"%>
 3 <html>
 4     <head>
 5         <title>混合表单</title>
 6     </head>
 7     <body>
 8         <%
 9             request.setCharacterEncoding("GBK") ;
10         %>
11         <%
12             SmartUpload smart = new SmartUpload();//实例化SmartUpload上传组件
13             smart.initialize(pageContext);//初始化上传操作
14             smart.upload();//上传准备
15             String name = smart.getRequest().getParameter("uname");//接受请求参数
16             smart.save("upload");//将上传文件保存在upload文件夹中
17         %>
18         <%=smart.getFiles().getFile(0).getFileName().matches("^\\w+.(jpg|gif)$")%>
19         <h2>姓名:<%=name%></h2>
20         <img src="../upload/<%=fileName%>">
21     </body>
22 </html>

由于表单进行了二进制封装,所以单纯靠request对象是无法取得提交参数的,必须依靠SmartUpload类中的getRequest().getParameter()方法才能取得请求的参数。

3  为上传文件自动命名

在上传操作中,如果多个用户上传的文件名称一样,则肯定会发生覆盖的情况。为了解决这个问题,可以采用为上传文件自动命名的方式。为了防止重名,自动命名可以采用如下的格式:IP地址+时间戳+三位随机数。

实例3

定义取得IP时间戳的操作类(IPTimeStamp.java)

 1 package cn.mldn.lxh.util ;
 2 import java.text.SimpleDateFormat ;
 3 import java.util.Date ;
 4 import java.util.Random ;
 5 public class IPTimeStamp {
 6     private SimpleDateFormat sdf = null ;
 7     private String ip = null ;
 8     public IPTimeStamp(){
 9     }
10     public IPTimeStamp(String ip){
11         this.ip = ip ;
12     }
13     public String getIPTimeRand(){
14         StringBuffer buf = new StringBuffer() ;
15         if(this.ip != null){
16             String s[] = this.ip.split("\\.") ;
17             for(int i=0;i<s.length;i++){
18                 buf.append(this.addZero(s[i],3)) ;
19             }
20         }
21         buf.append(this.getTimeStamp()) ;
22         Random r = new Random() ;
23         for(int i=0;i<3;i++){
24             buf.append(r.nextInt(10)) ;
25         }
26         return buf.toString() ;
27     }
28     public String getDate(){
29         this.sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS") ;
30         return this.sdf.format(new Date()) ;
31     }
32     public String getTimeStamp(){
33         this.sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS") ;
34         return this.sdf.format(new Date()) ;
35     }
36     private String addZero(String str,int len){
37         StringBuffer s = new StringBuffer() ;
38         s.append(str) ;
39         while(s.length() < len){
40             s.insert(0,"0") ;
41         }
42         return s.toString() ;
43     }
44     public static void main(String args[]){
45         System.out.println(new IPTimeStamp("192.168.1.1").getIPTimeRand()) ;
46     }
47 }

上传表单(demo3_1.html)

 1 <html>
 2     <head>
 3         <title>混合表单</title>
 4     </head>
 5     <body>
 6         <form action="demo3_2.jsp" method="post" enctype="multipart/form-data">
 7             姓名:<input type="text" name="uname"><br>
 8             照片:<input type="file" name="pic"><br>
 9             <input type="submit" value="上传">
10             <input type="reset" value="重置">
11         </form>
12     </body>
13 </html>

自动命名在上传操作页中不能像之前那样直接使用save()方法保存,而要取得一个具体的上传文件对象才可以保存,而且由于上传文件时文件的后缀需要统一,所以可以使用getFileExt方法取得后缀。

接收表单文本、图片并保存(demo3_2.jsp)

 1 <%@ page contentType="text/html" pageEncoding="GBK"%>
 2 <%@ page import="org.lxh.smart.*"%>
 3 <%@ page import="cn.mldn.lxh.util.*"%>
 4 <html>
 5     <head>
 6         <title>混合表单</title>
 7     </head>
 8     <body>
 9         <%
10             request.setCharacterEncoding("GBK") ;
11         %>
12         <%
13             SmartUpload smart = new SmartUpload() ;
14             smart.initialize(pageContext) ;    // 初始化上传操作
15             smart.upload() ;            // 上传准备
16             String name = smart.getRequest().getParameter("uname") ;
17             IPTimeStamp its = new IPTimeStamp(request.getRemoteAddr()) ;    // 取得客户端的IP地址
18             String ext = smart.getFiles().getFile(0).getFileExt() ;    // 扩展名称
19             String fileName = its.getIPTimeRand() + "." + ext ;
20             smart.getFiles().getFile(0).saveAs(this.getServletContext().getRealPath("/")+"upload"+java.io.File.separator + fileName) ;
21         %>
22         <h2>姓名:<%=name%></h2>
23         <img src="../upload/<%=fileName%>">
24     </body>
25 </html>

上述程序在进行上传操作时,使用了IPTimeStamp类完成文件的自动命名操作,由于SmartUpload可以同时接收多个上传文件,所以此时通过smart.getFiles().getFile(0).getFileExt()取得第一个上传文件的文件后缀,在与之前IPTimeStamp类生成的文件名称一起拼凑出一个新的文件名,由于此事要用新的文件名称保存上传文件,所以要通过smart.getFiles().getFile(0).saveAs()方法进行手工保存。

可以通过正则表达式限制文件后缀:

1 if(smart.getFiles().getFile(0).getFileName().matches("^\\w+.(jpg|gif)$")) {
2     
3 }

4  批量上传

实例4

上传表单(demo4_1.html)

 1 <html>
 2     <head>
 3         <title>混合表单</title>
 4     </head>
 5     <body>
 6         <form action="demo4_2.jsp" method="post" enctype="multipart/form-data">
 7             照片1:<input type="file" name="pic1"><br>
 8             照片2:<input type="file" name="pic2"><br>
 9             照片3:<input type="file" name="pic3"><br>
10             <input type="submit" value="上传">
11             <input type="reset" value="重置">
12         </form>
13     </body>
14 </html>

如果要完成批量上传,则肯定要是使用循环的方式进行,那么就必须通过如下方法取得上传数量。

取得全部上传文件数量:smart.getFiles().getCount()

 1 <%@ page contentType="text/html" pageEncoding="GBK"%>
 2 <%@ page import="org.lxh.smart.*"%>
 3 <%@ page import="cn.mldn.lxh.util.*"%>
 4 <html>
 5     <head>
 6         <title>混合表单</title>
 7     </head>
 8     <body>
 9         <%
10             request.setCharacterEncoding("GBK") ;
11         %>
12         <%
13             SmartUpload smart = new SmartUpload() ;
14             smart.initialize(pageContext) ;    // 初始化上传操作
15             smart.upload() ;            // 上传准备
16             String name = smart.getRequest().getParameter("uname") ;
17             IPTimeStamp its = new IPTimeStamp(request.getRemoteAddr()) ;    // 取得客户端的IP地址
18             for(int x=0;x<smart.getFiles().getCount();x++){
19                 String ext = smart.getFiles().getFile(x).getFileExt() ;    // 扩展名称
20                 String fileName = its.getIPTimeRand() + "." + ext ;
21                 smart.getFiles().getFile(x).saveAs(this.getServletContext().getRealPath("/")+"upload"+java.io.File.separator + fileName) ;
22             }
23         %>
24     </body>
25 </html>

程序运行后,会在根目录下的upload文件夹中发现已经同时保存了3个上传文件,并且文件名称没有重复。

posted @ 2018-02-19 15:42  祁俊辉  阅读(422)  评论(0编辑  收藏  举报