1.文件上传原理: 将表单的内容以二进制的方式上传到后台,用流的读取和写入.
2.上传三要素:
2.1:表单的上传方式:method=“post”
2.2:表单的以二进制编码方式上传内容:enctype=“multipart/form-data”
2.3:表单中需要有文件上传的表单元素:<input type= "file" name="upload">
这个元素必须要有name属性和值;
3.解决文件上传重名:
3.1:UUID+原文件名
3.2:系统时间+原文件名
3.3:UUID+系统时间+原文件名
Servlet3.0及以后支持文件上传:将表单以多部分上传的.实验代码如下:
前端注册页面参考代码:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<style type="text/css">
form{
width:600px;
height:auto;
margin:0px auto;
}
</style>
<script type="text/javascript">
//验证用户名
function isUname() {
//获得用户名框中值
var uname=document.getElementById("uname").value;
//判断用户名
if (uname=="") {
document.getElementById("uname1").innerHTML="用户名不能为空";
document.getElementById("uname1").style.color="red";
return false;
} else {
/*用ajax进行 验证 */
//1.创建ajax引擎对象
var ajaxObject;
//1.1.判断浏览器,提升兼容性
if (window.XMLHttpRequest) {//新浏览器
ajaxObject = new XMLHttpRequest();
} else {//IE5、IE6
ajaxObject = new ActiveXObject("Microsoft.XMLHTTP");
}
//2.ajax引擎对象创建请求
//创建get请求(因为ajax在用get提交时并未提交表单内容所以可以直接将参数拼接在url中不会存在覆盖的情况)
ajaxObject.open("get", "UserServlet?flag=isUname&uname="+uname, true)
//3.ajax引擎对象发送请求
ajaxObject.send();
//4.调用回调函数
ajaxObject.onreadystatechange=function(){
//判断请求是否完成和响应是否正常
if (ajaxObject.readyState==4 && ajaxObject.status==200) {
//用ajax引擎对象接收响应结果
var result = ajaxObject.responseText;
//将json字符串转换为json对象
var ob = eval("("+result+")");
if (ob.flag==1) {//已存在
document.getElementById("uname1").innerHTML="× 用户名已存在";
document.getElementById("uname1").style.color="red";
}else {
document.getElementById("uname1").innerHTML="√";
document.getElementById("uname1").style.color="green";
}
}
}
return true;
}
}
//验证密码
function isPwd() {
//获得密码框中值
var pwd=document.getElementById("pwd").value;
//声明一个正则表达式
var reg=/^\d{6,12}$/;
//判断密码
if (reg.test(pwd)) {
document.getElementById("pwd1").innerHTML="√";
document.getElementById("pwd1").style.color="green";
return true;
} else {
document.getElementById("pwd1").innerHTML="密码输入有误!";
document.getElementById("pwd1").style.color="red";
return false;
}
}
//判断是否同意协议
function isAgree() {
//获得协议的多选框
var agree=document.getElementById("agree");
//判断协议的多选框是否选中
if (agree.checked==true) {
document.getElementById("sub").disabled=false;
} else {
document.getElementById("sub").disabled=true;
}
}
//验证表单
function check() {
//调用验证用户名和密码的函数
if (isUname()==true&&isPwd()==true) {
return true;
}else{
return false;
}
}
</script>
</head>
<body>
<form method="post" action="UpLoad2Servlet" enctype="multipart/form-data" οnsubmit="return check()">
<input type="hidden" name="flag" value="register"/>
<table>
<tr>
<td></td>
<td><h1>注册信息</h1></td>
<td></td>
</tr>
<tr>
<td>用户名:</td>
<td><input type="text" name="uname" id="uname" οnblur="isUname()"/></td>
<td id="uname1"></td>
</tr>
<tr>
<td>密码:</td>
<td><input type="password" name="pwd" id="pwd" οnblur="isPwd()"/></td>
<td id="pwd1">密码必须为6-12位数字</td>
</tr>
<tr>
<td>性别:</td>
<td>
<input type="radio" name="sex" value="man" checked="checked"/>男
<input type="radio" name="sex" value="woman" />女
</td>
<td></td>
</tr>
<tr>
<td>头像</td>
<td><input type="file" name="myfile"/></td>
<td></td>
</tr>
<tr>
<td>爱好:</td>
<td>
<input type="checkbox" name="hobby" value="sing" />唱歌
<input type="checkbox" name="hobby" value="dancing" />跳舞
<input type="checkbox" name="hobby" value="rap" />rap
<input type="checkbox" name="hobby" value="basketball" />篮球
</td>
<td></td>
</tr>
<tr>
<td>所在城市:</td>
<td>
<select name="city">
<option value="shenzhen">深圳</option>
<option value="beijing">北京</option>
<option value="shanghai">上海</option>
<option value="chongqing">重庆</option>
<option value="wuhan">武汉</option>
</select>
</td>
<td></td>
</tr>
<tr>
<td>协议:</td>
<td>
<textarea rows="6" cols="20">
请阅读以下内容:
我是中国人
我爱中国
</textarea>
</td>
<td></td>
</tr>
<tr>
<td></td>
<td>
<input type="checkbox" id="agree" οnchange="isAgree()"/>同意协议
</td>
<td></td>
</tr>
<tr>
<td></td>
<td>
<input type="submit" value="提交" id="sub" disabled="disabled"/>
<input type="reset" value="重置"/>
</td>
<td></td>
</tr>
</table>
</form>
</body>
</html>
servlet代码:
package FileUpLoad;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;
/**
* Servlet3.0实现文件上传
*/
@WebServlet("/UpLoad2Servlet")
@MultipartConfig()//表示当前Servlet支持文件上传
public class UpLoad2Servlet extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获得文件上传目录upload
String path = request.getServletContext().getRealPath("WEB-INF/upload");
//获得上传文件的表单元素
Part part = request.getPart("myfile");
/*实现上传*/
if (part.getSize()>1024*20) {
response.getWriter().write("上传文件过大,超过20K");
return;
}
//获得part头部信息
String head = part.getHeader("Content-Disposition");
System.out.println(head);
//获得上传文件的原文件名
String fileName = head.substring(head.lastIndexOf("=")+2, head.length()-1);
//通过文件名的hash算法获得要存放的子文件夹(当需要将文件打散存储时,如果已知目标路径则用path即可)
String childpath = String.valueOf((fileName.hashCode()&0xf0)>>4);
//判断上传目录是否存在
File f = new File(path, childpath);
if (!f.exists()) {
f.mkdirs();//没有就创建
}
//上传
part.write(f.getPath()+File.separator+fileName);
response.getWriter().write("上传成功");
/*以下为实验代码可忽略*/
//获得上传文件路径名+文件名
String imgurl = f.getPath()+File.separator+fileName;
//获得普通表单值
String uname=request.getParameter("uname");
String pwd=request.getParameter("pwd");
String sex=request.getParameter("sex");
String[] hobby=request.getParameterValues("hobby");
String city=request.getParameter("city");
System.out.println("servlet 3.0 支持getParameter方法从二进制表单获取参数值");
System.out.println("imgurl="+imgurl+"uname="+uname+",pwd="+pwd+",sex="+sex+",hobby="+Arrays.toString(hobby)+",city="+city);
}
}
实验代码的后台打印内容(印证:servlet 3.0 支持getParameter方法从二进制表单获取参数值):
form-data; name="myfile"; filename="手机扫码体验.jpg"
servlet 3.0 支持getParameter方法从二进制表单获取参数值
imgurl=D:\PKG\apache-tomcat-7.0.57-windows-x86\apache-tomcat-7.0.57\webapps\UpLoad\WEB-INF\upload\13\手机扫码体验.jpguname=aa,pwd=111111,sex=woman,hobby=[sing],city=shenzhen