文件上传:
今天学了Apache封装的文件上传的类:commons fileupload
Apache Commons Fileupload文件上传组件使开人员很方便地接收客户端上传的文件,其核思想是将用户的请求转换为一个List<FileItem>
的集合,基中FileItem是第一个表单项的封装。
1、 下载 commons-fileupload 库,下载地址:http://commons.apache.org/fileupload/
2、 下载 commons-fileupload 依赖库 commons-io,下载地址:http://commons.apache.org/io/
这个类中就有很多关于文件上传的各种方法,具体可以参考API。
下面是用这个类实现文件上传的一段代码:
package com.oracle.servlet;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Iterator;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
@WebServlet("/upload")
public class UploadServlet extends HttpServlet
{
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
{
resp.setContentType("text/html;charset=utf-8");
PrintWriter out=resp.getWriter();
try {
boolean isMultipart = ServletFileUpload.isMultipartContent(req);//看enctype是不是"multipart/form-data";也就是看是不是文件上传类型
// Create a factory for disk-based file items
DiskFileItemFactory factory = new DiskFileItemFactory();//新建一个工厂类对象
// Set factory constraints
// factory.setSizeThreshold(yourMaxMemorySize);
// factory.setRepository(yourTempDirectory);
// Create a new file upload handler
ServletFileUpload upload = new ServletFileUpload(factory);//用工厂类对象新建一个upload对象
// Set overall request size constraint
upload.setSizeMax(1024*1024*10);//设置最大上传大小,单位是字节,这里是10M
// Parse the request
List<FileItem> items = upload.parseRequest(req);//新建一个List,范型是Fileitem,list中存储了传进来的文件的各个部分。
// Process the uploaded items
Iterator<FileItem> iter = items.iterator();//迭代器
while (iter.hasNext())
{
FileItem item = iter.next();
if (item.isFormField()) //true就是普表单项
{
if("dis".equals(item.getFieldName()))
{
out.println("<h1>文件描述:"+item.getString("utf-8")+"</h1>");
}
} else//文件上传
{
//文件上传
if("pic".equals(item.getFieldName()))
{
out.println("<h1>ContentType:"+item.getContentType()+"</h1>"); //得到mime类型
out.println("<h1>fileName:"+item.getName()+"</h1>");//得到客户端要上传的文件的文件名。
out.println("<h1>Size:"+item.getSize()+"</h1>");//得到文件大小
//上传
item.write(new File(this.getServletContext().getRealPath("ups"),item.getName()));//里面写的是文件对象,文件对象用new File(文件要写入的绝对路径,要写的文件名)
}
}
}
} catch (FileUploadException e) {
out.println("<h1>文件超过大小。。。。</h1>");
System.out.println("<h1>文件超过大小。。。。</h1>");
e.printStackTrace();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
out.close();
}
}
文件下载:
直接将超链接指向要下载的文件
- 直接下载:
浏览器不能识辨的MIME类型会出现下载对话框 程序无法能过用户权限来识辨能否下载 - 间接(Servlet)下载:
用Servlet将二进制流数据响应给客户端,可以更自由地控制用户下载权限
响应报头:
response.setContentType(contentType)
response.setHeader("Content-Disposition", "attachment;filename=文件名");
写段代码实现直接下载和间接下载:
index.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<center>
<a href="ups/pic01.zip">直接下载</a><br/>
<a href="ups/pic01.jpg">直接下载</a><br/>
<a href="down?fname=pic01.jpg">Servlet下载 </a><!-- 在超链接的同时传一个参数fname,值为pic01.jpg -->
</center>
</body>
</html>
Servlet页面:
package com.oralce.servlet;
//文件下载,间接(Servlet)下载
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.io.IOUtils;
@WebServlet("/down")
public class DownServlet extends HttpServlet
{
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
{
// resp.setContentType("text/html;charset=utf-8");
// PrintWriter out=resp.getWriter();
resp.setContentType("image/jpeg");//设置返回mime类型为jpeg
//设置报头,如果不设置的话浏览器是可以识别这种文件类型的,就会直接显示出来,而不是下载。
//设置一个报头,报头名为Content-Disposition,值为attachment;filename=...值为attachment的意思是表示会下载文件,如果值为inline就表示浏览器内嵌显示一个文件。
resp.setHeader("Content-Disposition", "attachment;filename="+new String("中国.zip".getBytes("gbk"),"iso-8859-1"));
String fname=null!=req.getParameter("fname")?req.getParameter("fname"):"";//得到表单穿过来的fname的值。
//在这里可以判断有没有下载的权限(if...else...)这里没有写关于权限的代码。
FileInputStream fi=new FileInputStream(this.getServletContext().getRealPath("ups")+File.separator+fname);//读取输入流
ServletOutputStream so=resp.getOutputStream();//新建一个输出流
IOUtils.copy(fi, so);//将输入流中的东西copy到输出流中
System.out.println(this.getServletContext().getMimeType("ups/pic01.zip"));
// out.close();
so.close();
}
}
注意:一般浏览器不会识别zip文件,所以出现zip文件一般就会直接弹出下载框,可是如果想实现下载图片,要记得加上代码中的报头,不然浏览器就会直接将图片加载出来,因为一般浏览器是能识别出图片的mime类型的。