表单封装问题
在Smartupload上传组件【上】中我们学习了Smartupload上传的应用,但是我们说那个程序有一点问题,什么问题呢?我们已经知道了要进行文件上传,则肯定要对表单进行封装,问题就在表单封装这里,表单一旦封装之后,就无法使用request.getParameter()来接受参数了。例如:在表单中定义了姓名等变量,在.jsp中就不能用request.getParameter()来接受这个名字了。一个例子看一下到底怎么不能接受。
- smart_02.html
- <html>
- <head>
- <title>WEB开发title>
- head>
- <body>
- <form action="smart_02.jsp" method="post" enctype="multipart/form-data">
- 姓名:<input type="text" name="uname"><br> //定义名字
- 照片:<input type="file" name="pic">
- <input type="submit" value="上传"><br>
- <input type="reset" value="重置">
- form>
- body>
- html>
有了.html页了 再来做.jsp页面用来接受图片和姓名
- smart_02.jsp
- <%@ page language="java" contentType="text/html" pageEncoding="utf-8"%>
- <%@ page import="com.jspsmart.upload.*" %>
- <html>
- <head>
- <title>WEB开发项目title>
- head>
- <body>
- <%
- request.setCharacterEncoding("utf-8");
- %>
- <%
- SmartUpload smart=new SmartUpload();
- smart.initialize(pageContext);// 初始化上传操作
- smart.upload(); //上传准备
- smart.save("upload"); //文件保存
- %>
- <h2><%=request.getParameter("uname") %>h2>
- body>
- html>
在smart_02.jsp中用了request.getParameter()来接受参数,但是运行一下(如下图):结果为null 是一个空值。
也就是说根本就无法接受参数,而且使用getParameterValues()也无法接受,因为在smart_02.html中,姓名属性随着表单被封装了,所有的数据不再是文本了,而是二进制byte流了,那么这个时候要想接受参数就必须使用Smartload中提供的方法支持。
- 将smart_02.jsp改成如下;
- <%@ page language="java" contentType="text/html" pageEncoding="utf-8"%>
- <%@ page import="com.jspsmart.upload.*" %>
- <html>
- <head>
- <title>WEB开发项目title>
- head>
- <body>
- <%
- request.setCharacterEncoding("utf-8");
- %>
- <%
- SmartUpload smart=new SmartUpload();
- smart.initialize(pageContext);// 初始化上传操作
- smart.upload(); //上传准备
- String name=smart.getRequest().getParameter("uname");
- smart.save("upload"); //文件保存
- %>
- <h2>姓名:<%=name %>h2>
- body>
- html>
这个时候在运行一下,结果就能正常显示了,但是又有一个新的问题出现了,细心的读者就会发现,如果两次都上传同一张图片,那么在Upload文件夹中只是存在了一张图片,也就是说第二次上传的图片覆盖了第一张,它是 一个覆盖的过程,但是我们希望两张一样的图片都能上传,并且让他们的名字不一样那该怎么办?
为上传文件自动命名功能
大家应该都有过这样的经历:在网上下载一张图片,点击右键图片另存为,接着会弹出图片保存的路径的对话框(如下图),红色区域的名字为一串看不懂的字符,那个字符就是系统为图片自动命名的,而我们所要实现的就是为上传的图片自动分配名字。
关于自动命名功能的实现原理
如果多个用户上传的文件名称一样,则肯定会发生覆盖的情况,为了解决这种问题,可以采用为上传文件自动命名的方式,为了防止重名,自动命名可以采用如下格式:
1. IP地址+时间戳+三位随机数
2. 例如:现在连接的IP地址为192.168.12.19,日期时间是:2013-03-02 17:58:12,三位随机数为678,则拼凑出的新文件名称就是19216801201920130302125812678.文件后缀名
为了进行文件后缀的拼凑,我们建立一个专门用于此种操作的类---IPTimeStamp,此类作为一个javaBean,在simple包下创建。
- IPTimeStamp.java
- package simpl;
- import java.text.SimpleDateFormat;
- import java.util.Date;
- import java.util.Random;//随机数
- public class IPTimeStamp {
- private SimpleDateFormat sdf=null; //定义SimpleDateFormat对象
- private String ip=null; //接受IP地址
- public IPTimeStamp(){ //无参构造
- }
- public IPTimeStamp(String ip){//接受IP地址
- this.ip=ip;
- }
- public String getIPTimeRand(){ //得到IP地址+时间+三位随机数
- StringBuffer buf=new StringBuffer(); //实例化StringBuffer对象
- if(this.ip!=null){
- String s[]=this.ip.split("\\.");//转义,进行拆分操作
- for(int i=0;i<s.length;i++){ //循环设置IP地址
- buf.append(this.addZero(s[i],3)); //不够三位数字要补0
- }
- }
- buf.append(this.getTimeStamp()); //取得时间戳
- Random r=new Random(); //定义Random对象,以产生随机数
- for(int i=0;i<3;i++){ //循环三次
- buf.append(r.nextInt(10)); //增加一个随机数
- }
- return buf.toString(); //返回名称
- }
- private String addZero(String str,int len){ //补0操作
- StringBuffer s=new StringBuffer(); //定义StringBuffer对象
- s.append(str); //将传递的内容放到StringBuffer中
- while(s.length()<len){ //如果不够指定位数,,则在前面补0
- s.insert(0, "0"); //补0
- }
- return s.toString();
- }
- public String getDate(){ //取得当前的系统时间
- this.sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
- return this.sdf.format(new Date());
- }
- public String getTimeStamp(){ //取得时间戳
- this.sdf=new SimpleDateFormat("yyyyMMddHHmmssSSS");
- return this.sdf.format(new Date());
- }
- }
将smart_02.jsp改成如下:
- <%@ page language="java" contentType="text/html" pageEncoding="utf-8"%>
- <%@ page import="com.jspsmart.upload.*" %>
- <%@ page import="simpl.IPTimeStamp"%> //导入javaBean
- <html>
- <head>
- <title>WEB开发项目title>
- head>
- <body>
- <%
- request.setCharacterEncoding("utf-8");
- %>
- <%
- SmartUpload smart=new SmartUpload();
- smart.initialize(pageContext);// 初始化上传操作
- smart.upload(); //上传准备
- String name=smart.getRequest().getParameter("uname");
- //实例化IPTimeStamp对象
- IPTimeStamp its=new IPTimeStamp(request.getLocalAddr());
- String ext=smart.getFiles().getFile(0).getFileExt();//取得文件后缀
- String fileName=its.getIPTimeRand()+"."+ext;//拼凑文件名称
- smart.getFiles().getFile(0).saveAs(getServletContext().getRealPath("/")
- +"upload"+java.io.File.separator+fileName);//保存文件
- %>
- <h2>姓名:<%=name %>h2>
- <img src="../upload/<%=fileName %>">
- body>
- html>
我们来运行一下,写上我的名字:赵玉强,然后上传一张名字为dahai.jpg的图片,结果如下:
可以看见图片和名字都能够正常显示,我们在来看一下upload文件中是否上传上了图片呢?而且图片的名字是否是系统自动命名的呢?打开tomcat/webapps下的项目找到upload文件夹。图片确实有了,如下图所示:
可以发现上传的图片的名字不是上传之前的名字了,而是系统自动上传的名字,而且不管对同一张图片上传多少次,都不会出现只有一张的情况了,因为系统会自动分配给上传图片不同的名字。