使用jsp/servlet簡單實現文件上傳與下載

使用JSP/Servlet簡單實現文件上傳與下載

   經過學習黑馬jsp教學視頻,我學會了使用jsp與servlet簡單地實現web的文件的上傳與下載,首先感謝黑馬。好了,下面來簡單瞭解如何經過使用jsp與servlet實現文件上傳與下載。
       在寫代碼以前,咱們須要導入兩個額外的jar包,一個是common-io-2.2.jar,另外一個是commons-fileupload-1.3.1.jar,將這個兩個jar 包導入WEB-INF/lib目錄裏。
       首先,想要在web端即網頁上實現文件上傳,必需要提供一個選擇文件的框,即設置一個<input type="file"/>的元素,光有這個還不行,還須要對<input>元素外的表單form進行設置,將form的enctype屬性設置爲「multipart/form-data」,即<form action="" method="post" enctype="multipart/form-data">,固然請求方式也必須是post。讓咱們來簡單作一個上傳的jsp頁面:
 
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>  
  
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">  
<html>  
  <head>  
    <title>文件上傳</title>  
      
    <meta http-equiv="pragma" content="no-cache">  
    <meta http-equiv="cache-control" content="no-cache">  
    <meta http-equiv="expires" content="0">  
    <!-- 
    <link rel="stylesheet" type="text/css" href="styles.css"> 
    -->  
  
  </head>  
    
  <body>  
    <form action="${pageContext.request.contextPath}/servlet/UploadServlet" method="post" enctype="multipart/form-data">  
        name:<input name="name"/><br/>  
        file1:<input type="file" name="f1"/><br/>  
          
        <input type="submit" value="上傳">  
    </form>  
  </body>  
</html>  

 jsp頁面作好以後,咱們就要寫一個UploadServlet,在編寫上傳servlet時,咱們須要考慮到若是上傳的文件出現重名的狀況,以及上傳的文件可能會出現的亂碼狀況,因此咱們須要編碼與客戶端一致,而且根據文件名的hashcode計算存儲目錄,避免一個文件夾中的文件過多,固然爲了保證服務器的安全,咱們將存放文件的目錄放在用戶直接訪問不到的地方,好比在WEB-INF文件夾下建立一個file文件夾。具體作法以下:css

public class UploadServlet extends HttpServlet {  
  
    public void doGet(HttpServletRequest request, HttpServletResponse response)  
            throws ServletException, IOException {  
        request.setCharacterEncoding("UTF-8");  
        response.setContentType("text/html;charset=UTF-8");  
        PrintWriter out = response.getWriter();  
        System.out.print(request.getRemoteAddr());  
        boolean isMultipart = ServletFileUpload.isMultipartContent(request);  
        if(!isMultipart){  
            throw new RuntimeException("請檢查您的表單的enctype屬性,肯定是multipart/form-data");  
        }  
        DiskFileItemFactory dfif = new DiskFileItemFactory();  
        ServletFileUpload parser = new ServletFileUpload(dfif);  
          
        parser.setFileSizeMax(3*1024*1024);//設置單個文件上傳的大小  
        parser.setSizeMax(6*1024*1024);//多文件上傳時總大小限制  
          
        List<FileItem> items = null;  
        try {  
            items = parser.parseRequest(request);  
        }catch(FileUploadBase.FileSizeLimitExceededException e) {  
            out.write("上傳文件超出了3M");  
            return;  
        }catch(FileUploadBase.SizeLimitExceededException e){  
            out.write("總文件超出了6M");  
            return;  
        }catch (FileUploadException e) {  
            e.printStackTrace();  
            throw new RuntimeException("解析上傳內容失敗,請從新試一下");  
        }  
          
        //處理請求內容  
        if(items!=null){  
            for(FileItem item:items){  
                if(item.isFormField()){  
                    processFormField(item);  
                }else{  
                    processUploadField(item);  
                }  
            }  
        }  
          
        out.write("上傳成功!");  
    }  
    private void processUploadField(FileItem item) {  
        try {  
            String fileName = item.getName();  
              
              
            //用戶沒有選擇上傳文件時  
            if(fileName!=null&&!fileName.equals("")){  
                fileName = UUID.randomUUID().toString()+"_"+FilenameUtils.getName(fileName);  
                  
                //擴展名  
                String extension = FilenameUtils.getExtension(fileName);  
                //MIME類型  
                String contentType = item.getContentType();  
                  
                  
                  
                //分目錄存儲:日期解決  
    //          Date now = new Date();  
    //          DateFormat df = new SimpleDateFormat("yyyy-MM-dd");  
    //            
    //          String childDirectory  = df.format(now);  
                  
                  
                //按照文件名的hashCode計算存儲目錄  
                String childDirectory = makeChildDirectory(getServletContext().getRealPath("/WEB-INF/files/"),fileName);  
                  
                String storeDirectoryPath = getServletContext().getRealPath("/WEB-INF/files/"+childDirectory);  
                File storeDirectory = new File(storeDirectoryPath);  
                if(!storeDirectory.exists()){  
                    storeDirectory.mkdirs();  
                }  
                System.out.println(fileName);  
                item.write(new File(storeDirectoryPath+File.separator+fileName));//刪除臨時文件  
                  
            }  
        } catch (Exception e) {  
            throw new RuntimeException("上傳失敗,請重試");  
        }  
          
    }  
    //計算存放的子目錄  
    private String makeChildDirectory(String realPath, String fileName) {  
        int hashCode = fileName.hashCode();  
        int dir1 = hashCode&0xf;// 取1~4位  
        int dir2 = (hashCode&0xf0)>>4;//取5~8位  
          
        String directory = ""+dir1+File.separator+dir2;  
        File file = new File(realPath,directory);  
        if(!file.exists())  
            file.mkdirs();  
          
        return directory;  
    }  
    private void processFormField(FileItem item) {  
        String fieldName = item.getFieldName();//字段名  
        String fieldValue;  
        try {  
            fieldValue = item.getString("UTF-8");  
        } catch (UnsupportedEncodingException e) {  
            throw new RuntimeException("不支持UTF-8編碼");  
        }  
        System.out.println(fieldName+"="+fieldValue);  
    }  
  
    public void doPost(HttpServletRequest request, HttpServletResponse response)  
            throws ServletException, IOException {  
        doGet(request, response);  
    }  
  
}  

 至此,上傳的任務就基本完成了,有了上傳固然也要有下載功能,在下載以前,咱們須要將全部已經上傳的文件顯示在網頁上,經過一個servlet與一個jsp頁面來顯示,servlet代碼以下:html

public class ShowAllFilesServlet extends HttpServlet {  
  
    public void doGet(HttpServletRequest request, HttpServletResponse response)  
            throws ServletException, IOException {  
        String storeDirectory = getServletContext().getRealPath("/WEB-INF/files");  
        File root = new File(storeDirectory);  
          
        //用Map保存遞歸的文件名:key:UUID文件名   value:老文件名  
        Map<String, String> map = new HashMap<String, String>();  
        treeWalk(root,map);  
          
        request.setAttribute("map", map);  
        request.getRequestDispatcher("/listFiles.jsp").forward(request, response);  
    }  
    //遞歸,把文件名放到Map中  
    private void treeWalk(File root, Map<String, String> map) {  
        if(root.isFile()){  
            String fileName = root.getName();//文件名       
            String oldFileName = fileName.substring(fileName.indexOf("_")+1);  
            map.put(fileName, oldFileName);  
        }else{  
            File fs[] = root.listFiles();  
            for(File file:fs){  
                treeWalk(file, map);  
            }  
        }  
          
    }  
  
    public void doPost(HttpServletRequest request, HttpServletResponse response)  
            throws ServletException, IOException {  
        doGet(request, response);  
    }  
  
}  

 經過上面的servlet轉發到listFiles.jsp頁面,listFiles.jsp頁面:java

 

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>  
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>  
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">  
<html>  
  <head>  
    <title>title</title>  
      
    <meta http-equiv="pragma" content="no-cache">  
    <meta http-equiv="cache-control" content="no-cache">  
    <meta http-equiv="expires" content="0">  
    <!--  
    <link rel="stylesheet" type="text/css" href="styles.css">  
    -->  
  
  </head>  
    
  <body>  
    <h1>如下資源可供下載</h1>  
    <c:forEach items="${map}" var="me">  
        <c:url value="/servlet/DownloadServlet" var="url">  
            <c:param name="filename" value="${me.key}"></c:param>  
        </c:url>  
        ${me.value}  <a href="${url}">下載</a><br/>  
    </c:forEach>  
  </body>  
</html>  

 到這裏,文件也顯示出來了,就須要點擊下載進行下載文件了,最後一步,咱們再編寫一個DownloadServlet:web

public class DownloadServlet extends HttpServlet {  
  
    public void doGet(HttpServletRequest request, HttpServletResponse response)  
            throws ServletException, IOException {  
        String uuidfilename = request.getParameter("filename");//get方式提交的  
        uuidfilename = new String(uuidfilename.getBytes("ISO-8859-1"),"UTF-8");//UUID的文件名  
          
        String storeDirectory = getServletContext().getRealPath("/WEB-INF/files");  
        //獲得存放的子目錄  
        String childDirecotry = makeChildDirectory(storeDirectory, uuidfilename);  
          
        //構建輸入流  
        InputStream in = new FileInputStream(storeDirectory+File.separator+childDirecotry+File.separator+uuidfilename);  
        //下載  
        String oldfilename = uuidfilename.substring(uuidfilename.indexOf("_")+1);  
        //通知客戶端如下載的方式打開  
        response.setHeader("Content-Disposition", "attachment;filename="+URLEncoder.encode(oldfilename, "UTF-8"));  
          
        OutputStream out = response.getOutputStream();  
          
        int len = -1;  
        byte b[] = new byte[1024];  
        while((len=in.read(b))!=-1){  
            out.write(b,0,len);  
        }  
        in.close();  
        out.close();  
          
    }  
  
    public void doPost(HttpServletRequest request, HttpServletResponse response)  
            throws ServletException, IOException {  
        doGet(request, response);  
    }  
    //計算存放的子目錄  
    private String makeChildDirectory(String realPath, String fileName) {  
        int hashCode = fileName.hashCode();  
        int dir1 = hashCode&0xf;// 取1~4位  
        int dir2 = (hashCode&0xf0)>>4;//取5~8位  
          
        String directory = ""+dir1+File.separator+dir2;  
        File file = new File(realPath,directory);  
        if(!file.exists())  
            file.mkdirs();  
          
        return directory;  
    }  
}  

  文件上傳與下載就已經所有完成了。安全

 

本文來源於 http://blog.csdn.net/wetsion/article/details/50890031服務器

相關文章
相關標籤/搜索