servlet文件上传有三种方法,
第一种是用IOutils来实现
第二种是servlet的@MultipartConfig实现,
第三种是通过Apache的文件上传的方法来实现,
我的程序使用IDEA跑的,是一个maven程序,程序中所导入的依赖有:
commons-io,这是第一种方法需要的包,
commons-fileupload这是apache的文件上传需要的包
这是我的程序的目录
这是我的index页面代码:(文件上传必须用post方法,enctype的类型必须是multipart/form-data)
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>文件上传原理</title>
</head>
<body>
<center>
<form action="upload" method="post" enctype="multipart/form-data">
文件:<input type="file" name="pic"/><br/>
描述:<input type="text" name="dis"/><br/>
<input type="submit" value="OK"/>
</form>
</center>
</body>
</html>
第一种方法:
@WebServlet("/upload")
public class UploadServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletInputStream is=req.getInputStream();
FileOutputStream os=new FileOutputStream("E:\\aaa.txt");
IOUtils.copy(is, os);
resp.setContentType("text/html;charset=utf-8");
PrintWriter out=resp.getWriter();
out.println("<h1>Ok</h1>");
out.close();
}
}
IOUtils.copy(is, os);是把输入流中的数据写入到了输出流中,这个程序执行完,我上传的文件会保存到我的E盘的根目录,但是其中写入的过程中会带有一些请求参数之类的其他数据,可以自己使用字符串的截取得到想要的部分
第二种方法:
直接得到request的part的部分,用一个part类型的对象来接收,最后写入目的文件中
但是必须加@MultipartConfig
代码如下:得到文件的名字可以在报头中用正则表达式截取,同时为了防止两个人上传的文件名相同(上传的文件名相同有可能第二个文件就覆盖了第一个文件)可以加一个随机的数字
@MultipartConfig
@WebServlet("/upload1")
public class UploadServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
resp.setContentType("text/html;charset=utf-8");
PrintWriter out=resp.getWriter();
out.println("<h1>Ok</h1>");
Part part=req.getPart("pic");
if(null!=part)
{
out.println("<ul>");
out.println("<li>dis:"+req.getParameter("dis")+"</li>");
out.println("<li>getContentType:"+part.getContentType()+"</li>");
out.println("<li>getName:"+part.getName()+"</li>");
out.println("<li>getSize:"+part.getSize()+"</li>");
Collection<String> all=part.getHeaderNames();
Iterator<String> it=all.iterator();
while(it.hasNext())
{
String key=it.next();
String value=part.getHeader(key);
out.println("<li>"+key+":::"+value+"</li>");
}
String s=getFileName(part);
String s1=getExtName(s);
String s3=randName();
part.write("E:\\"+s.substring(0,s.lastIndexOf("."))+s3+s1);
out.println("</ul>");
}
out.close();
}
/**
* 得到上传文件名
* @param part
* @return
*/
public String getFileName(Part part)
{
String fname=null;
String hvalue=part.getHeader("Content-Disposition");
Pattern pattern=Pattern.compile("(form-data; name=\"(.*?)\"; filename=\"(.*?)\")");
Matcher mat=pattern.matcher(hvalue);
if(mat.find())
{
fname=mat.group(3);
}
return fname;
}
/**
* 得到后缀名,即去掉前面的字符串
* @param fname
* @return
*/
public String getExtName(String fname)
{
String re=null;
re=fname.toLowerCase().substring(fname.lastIndexOf("."));
return re;
}
private SimpleDateFormat sf=new SimpleDateFormat("yyyyMMddHHmmssSSS");
public String randName()
{
String re=null;
re=sf.format(new Date())+"_"+(int)(Math.floor(Math.random()*1000));
return re;
}
}
第三种方法:
导入Apache fileupload的依赖,这种方法直接可以得到文件名,可以不用正则去获文件名,它是把请求封装了好几个FileItem对象,我们需要遍历得到非普通的FileItem域,也就是我们需要的文件域
(我们可以直接把文件上传的那个例子的一部分拿过来用)
@WebServlet("/upload")
public class UploadServlet1 extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html;charset=utf-8");
PrintWriter out=resp.getWriter();
out.println("<h1>Commons file upload</h1>");
out.println("<ul>");
boolean isMultipart = ServletFileUpload.isMultipartContent(req);
try {
if(isMultipart)
{
DiskFileItemFactory factory = new DiskFileItemFactory();
ServletContext servletContext = this.getServletContext();
File repository = (File) servletContext.getAttribute("javax.servlet.context.tempdir");
factory.setRepository(repository);
ServletFileUpload upload = new ServletFileUpload(factory);
List<FileItem> items = upload.parseRequest(req);
if(null!=items)
{
for(FileItem item:items)
{
if(!item.isFormField())
{
String path=this.getServletContext().getRealPath("ups")+"/";
String ext=this.getExtName(item.getName());
File target=new File(path+randName()+ext);
item.write(target);
}
}
}
}else
{
out.println("不是mutipart/formdata");
}
} catch (Exception e) {
// TODO: handle exception
}
out.println("</ul>");
out.println("<center><a href='show'>显示图片列表</a></center>");
out.close();
}
public String getExtName(String fname)
{
String re=null;
re=fname.toLowerCase().substring(fname.lastIndexOf("."));
return re;
}
private SimpleDateFormat sf=new SimpleDateFormat("yyyyMMddHHmmssSSS");
public String randName()
{
String re=null;
re=sf.format(new Date())+"_"+(int)(Math.floor(Math.random()*1000));
return re;
}
}
我的代码中的"ups"是我的webapp下面建立的一个文件夹。
在tomcat的webapps的bin目录的root下面是servletContext的所在位置,文件上传到那个地方
以上是我的心得,希望对你有所帮助。