上传
jar
Apache: commons-fileupload.jar 、commons-io.jar
代码:
前台:
<form action="UploadServlet" method="post" enctype="multipart/form-data">
studentNo:<input name="sno"><br>
studentName:<input name="sname"><br>
spicture:<input type="file" name="spicture"><br>
<input type="submit" value="upLoad">
</form>
enctype : 解析方式
值 | 描述 |
---|---|
application/x-www-form-urlencoded | 1、默认值 ,它会将表单中的数据变为键值对的形式 ; 2、如果action为get,则将表单数据编码为(name1=value1&name2=value2…),然后把这个字符串加到url后面,中间 ;3、如果action为post,浏览器把form数据封装到http body中,然后发送到服务器 |
text/plain | 1、将空格转换为 “+” 符号,但不编码特殊字符,2、以纯文本形式进行编码 |
multipart/form-data | 1、上传的含有非文本内容,即含有文件(txt、MP3等 ; 2、、将表单中的数据变成二进制数据进行上传,所以这时候这时如果用request是无法直接获取到相应表单的值的 |
后台 :servlet
request.setCharacterEncoding("utf-8"); // 设置编码格式
response.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
try {
//判断是否有 mutipart属性 如果有,及时true
boolean isMultipart = ServletFileUpload.isMultipartContent(request);
if(isMultipart) {
// FileItemFactory facotry= new DiskFileItemFactory();//不用缓冲区
DiskFileItemFactory facotry= new DiskFileItemFactory();//使用缓冲区
ServletFileUpload Upload = new ServletFileUpload (facotry);
// 限制条件在解析前加入
// 设置上传文件是 用到的 临时文件的大小DiskFileItemFactory
facotry.setSizeThreshold(10240); //缓冲区大小为10kb
facotry.setRepository(new File("F:\\uplodtemp")); //临时文件的位置
// 控制文件大小 20kb 单个文件大小 ServletFileUpload
Upload.setSizeMax(20480);//单位是b
// 通过parseRequest解析来自from中所请求的字段,并保存到items集合中(即前台所传过来的所有表单数据)
List<FileItem> items = Upload.parseRequest(request);
// 遍历items
Iterator<FileItem> iter = items.iterator();//迭代器遍历 也可用for etch遍历
while(iter.hasNext()) {//与rs相似
FileItem item = iter.next();
String itemName = item.getFieldName();
int sno = -1;
String sname = null;
// item.getString() 拿值
if(item.isFormField()) {
if(itemName.equals("sno")) {//根据name属性判断 item是 sno sname
sno = Integer.parseInt(item.getString());
System.out.println(sno);
}else if(itemName.equals("sname")) {
sname = item.getString();
System.out.println(sname);
}else {
System.out.println("其它字段======");
}
}else {//spicture文件字段
// 文件上传
// 文件名 getFielName 是获取普通字段Name值
// getName是获取文件名
String fileName = item.getName(); // 获取文件名
String ext = fileName.substring(fileName.indexOf(".")+1); //解析文件格式
if(!(ext.equals("txt") || ext.equals("docx"))) { // 对文件格式进行限制
System.out.println("文件格式有误");
return;
}//终止
//定义文件路径: 指定文件路径 (服务器路径)
// String path="D:\\apache-tomcat-8.5.35\\webapps";
// 动态获取文件路径 通过application获取
// 在servlet中获取application的方式
// String path = request.getSession().getServletContext().getRealPath("uplod"); // 获取服务器路径
// 指定非tomcat目录 来防止文件丢失
String path ="F:\\uplod";
System.out.println(path);
File file = new File(path,fileName);//文件名,文件路径
item.write(file);
System.out.println(fileName+"上传成功");
return ;
}
}
}
// SizeLimitExceededException是FileUploadException的一个子类
}catch(FileUploadBase.SizeLimitExceededException e) {
System.out.println("文件过大");
e.printStackTrace();
}catch (FileUploadException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
注意问题:
上传的目录 upload:
1、 如果修改代码,则tomcat重启时 删除
原因: 当修改代码的时候 tomcat会重新编译一份class文件 并且重新部署
2、 如果不修改代码,则不会被删除
原因:没有修改代码,class任然是之前的class
因此: 为了防止 上传目录丢失 : a.虚拟路径 b.直接更换上传路径 到非tomcat 目录
限制上传
1、类型: 可以用js来限制
2、大小:
注意: 对文件大小的限制 需要写在parseRequest之前
下载
前台:
<a href="DownloadServlet?filename=picture.png">图片下载</a>
后台:
request.setCharacterEncoding("utf-8");
//获取文件名
String filename = request.getParameter("filename");
//下载文件需要设置 消息头
response.addHeader("contentType", "application/octet-stream");//MIME类型 :二进制文件(任意文件)
// 对于不同浏览器 进行不同的处理
// 获取客户端的user-agent
String agent = request.getHeader("User-Agent");
// 判断是否有firefox
if(agent.toLowerCase().indexOf("firefox")!=-1) {
// 火狐文件名乱码
response.addHeader("content-Disposition","attachment;filename==?UTF-8?B?"+ new String(Base64.encodeBase64(filename.getBytes("utf-8")))+"?=");
}else {
// IE文件名乱码
response.addHeader("content-Disposition","attachment;filename="+URLEncoder.encode(filename, "UTF-8"));
}
// response.addHeader("content-Disposition","attachment;filename="+filename);//filename 包含了后缀名
//Servlet 通过文件的地址 将文件转为输入流 读到|Servlet中
InputStream in = getServletContext().getResourceAsStream("/res/"+ filename);
//将输出流 将刚才已经转为输出流的文件 输出给用户
ServletOutputStream out = response.getOutputStream();
byte[] bs = new byte[10];
int len = -1;
while((len = in.read(bs)) != -1) {
out.write(bs,0,len);
}
out.close();
in.close();
下载总结:
不需要任何jar包
a、请求(地址 a from)请求servlet
b、servlet通过文件地址 将文件转为输出流 读到servlet 中
c、将输出流 将刚才已经转为输出流的文件 输出给用户
//下载文件需要设置 消息头
response.addHeader(“contentType”, “application/octet-stream”);//MIME类型 :二进制文件(任意文件)
response.addHeader(“content-Disposition”,“attachment;filename”+filename);//filename 包含了后缀名
下载是文件名乱码
IE,Google
response.addHeader(“content-Disposition”,“attachment;filename=”+URLEncoder.encode(filename, “UTF-8”))
火狐:
给文件名 加
前缀 =?UTF-8?B?
后缀Base64.encode
response.addHeader(“content-Disposition”,“attachment;filename==?UTF-8?B?”+new String(Base64.encodeBase64(filename.getBytes(“utf-8”)))+"?=");