zoukankan      html  css  js  c++  java
  • 事件的监听及上传下载

    文件上传概述

    1.文件上传必须满足的条件:

          a.页面表单的method必须是post

          b.页面表单的enctype必须是multipart/form-data类型的

          c.表单中提供<input type="file">上传文件域    注意:不适合上传特别大的文件;

          

            2.请求正文内容的获取:

             

    文件上传原理分析

     1 <%@ page import="java.util.*" pageEncoding="UTF-8"%>
     2 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
     3 <html>
     4   <head>
     5     <title>文件上传</title> 
     6     <meta http-equiv="pragma" content="no-cache">
     7     <meta http-equiv="cache-control" content="no-cache">
     8     <meta http-equiv="expires" content="0">    
     9     <!--
    10     <link rel="stylesheet" type="text/css" href="styles.css">
    11     -->
    12 
    13   </head>
    14   
    15   <body>
    16       <!-- 
    17           enctype="application/x-www-form-urlencoded" 默认值 
    18           HTTP协议请求消息头:Content-Type,告知服务器,请求正文的内容的MIME类型(POST方式)
    19               Content-Type的默认值:application/x-www-form-urlencoded
    20               
    21               通过表单的enctype属性,实际上是指定的请求正文的MIME类型
    22               
    23       -->
    24     <form action="${pageContext.request.contextPath}/servlet/UploadServlet3" method="post"
    25         enctype="multipart/form-data">
    26         姓名:<input type="text" name="name"/><br/>
    27         靓照:<input type="file" name="photo"/><br/>
    28         靓照:<input type="file" name="photo"/><br/>
    29         <input type="submit" value="保存"/>
    30     </form>
    31   </body>
    32 </html>
    index.jsp
     1 import java.io.IOException;
     2 
     3 import javax.servlet.ServletException;
     4 import javax.servlet.ServletInputStream;
     5 import javax.servlet.http.HttpServlet;
     6 import javax.servlet.http.HttpServletRequest;
     7 import javax.servlet.http.HttpServletResponse;
     8 
     9 public class UploadServlet1 extends HttpServlet {
    10 
    11     public void doGet(HttpServletRequest request, HttpServletResponse response)
    12             throws ServletException, IOException {
    13         ServletInputStream in = request.getInputStream();//获取请求正文的输入流
    14         int len = -1;
    15         byte b[] = new byte[1024];
    16         while((len=in.read(b))!=-1){
    17             System.out.println(new String(b,0,len));
    18         }
    19         in.close();
    20         
    21     }
    22 
    23     private void test1(HttpServletRequest request) {
    24         /*
    25         request.getParameter(String paramName)
    26         只能获取请求正文为application/x-www-form-urlencoded类型的数据
    27         
    28         name=abc&password=123
    29         */
    30         
    31         
    32         String name = request.getParameter("name");
    33         String photo = request.getParameter("photo");
    34         System.out.println("name:"+name);
    35         System.out.println("photo:"+photo);//不靠谱
    36     }
    37 
    38     public void doPost(HttpServletRequest request, HttpServletResponse response)
    39             throws ServletException, IOException {
    40         doGet(request, response);
    41     }
    42 
    43 }
    UploadServlet1

              enctype=”multipart/form-data”

            

              可以使用流的方式获取请求正文内容,进一步解析;

    借助第三方开发包实现文件上传

      Servlet3.0内部提供对文件上传的支持(需要Tomcat7.0以上) 

        依赖:commons-io

           1、拷贝jar包:

                   commons-fileupload-1.2.2.jar 

                  commons-io-2.0.1.jar

           2、fileupload组件的解析过程

              

              3.主要的类:

                   1.DiskFileItemFactory:产生存在磁盘上的FileItem工厂;

                    public void setSizeThreshold(int SizeThreshold):设置上传文件时用的缓存大小,默认10KB;

                    public void setRepository(File  repository):设置上传文件超出缓存大小的磁盘临时文件存放目录,默认是系统的临时文件存放目录;这里的目录都是服务器的

                        构造方法:DiskFileItemFactory():使用默认缓存,默认临时的文件存放目录

                             DiskFileItemFactory(int  sizeThreshold,File  repository):使用自己制定的缓存和临时文件存放目录;

                   2.ServletFileUpload:核心的解析请求类;

                   public static final Boolean isMultipartContent(java.servlet.http.HTTPServlet  request);判断用户请求正文是否是multipart/form-data类型;

                   public List parseRequest(java.servlet.http.HTTPServletRequest  request):解析请求对象,得到所有的表单输入域(每一个域用FileItem表示);

                   3.FileItem:代表每一个表单输入域;

                   

                  4.上传代码:

                

                     

                     

                   

                     

                        

    代码撸上

      1 import java.io.File;
      2 import java.io.FileOutputStream;
      3 import java.io.IOException;
      4 import java.io.InputStream;
      5 import java.io.OutputStream;
      6 import java.util.List;
      7 import java.util.UUID;
      8 
      9 import javax.servlet.GenericServlet;
     10 import javax.servlet.ServletException;
     11 import javax.servlet.http.HttpServlet;
     12 import javax.servlet.http.HttpServletRequest;
     13 import javax.servlet.http.HttpServletResponse;
     14 
     15 import org.apache.commons.fileupload.FileItem;
     16 import org.apache.commons.fileupload.FileUploadBase;
     17 import org.apache.commons.fileupload.FileUploadException;
     18 import org.apache.commons.fileupload.ProgressListener;
     19 import org.apache.commons.fileupload.disk.DiskFileItemFactory;
     20 import org.apache.commons.fileupload.servlet.ServletFileUpload;
     21 //借助commons-fileupload实现文件上传:入门案例
     22 public class UploadServlet2 extends HttpServlet {
     23     protected String storeDirectoryRealPath;//存放文件目录的真实路径
     24     //获取初始化参数:上传文件的存放目录
     25     public void init() throws ServletException {
     26         String storeDirectory = "/upload";//默认的存放上传文件的位置
     27         String value = getServletContext().getInitParameter("storeDirectory");
     28         if(value!=null){
     29             storeDirectory = value;
     30         }
     31         //该目录可能不存在
     32             //得到文件的真实路径
     33             storeDirectoryRealPath = getServletContext().getRealPath(storeDirectory);
     34             //判断文件夹是否存在,不存在,创建它
     35             File directory = new File(storeDirectoryRealPath);
     36             if(!directory.exists())
     37                 directory.mkdirs();
     38     }
     39     public void doGet(HttpServletRequest request, HttpServletResponse response)
     40             throws ServletException, IOException {
     41         //判断用户的请求内容是否是mutlipart/form-data类型的
     42         boolean isMultipart = ServletFileUpload.isMultipartContent(request);
     43         if(!isMultipart){
     44             throw new RuntimeException("not a file upload request");
     45         }
     46         try {
     47             //创建DiskFileItemFactory,并设置缓存和临时文件的存放目录
     48             DiskFileItemFactory factory = new DiskFileItemFactory();
     49             
     50             factory.setRepository(new File("d:/"));
     51             
     52             //创建ServletFileUpload, 核心解析类
     53             ServletFileUpload upload = new ServletFileUpload(factory);
     54 //            upload.setProgressListener(new ProgressListener() {
     55 //                /**
     56 //                 * pBytesRead:已经读取的字节数
     57 //                 * pContentLength:总上传文件的大小
     58 //                 * pItems:当前处理的表单项
     59 //                 */
     60 //                public void update(long pBytesRead, long pContentLength, int pItems) {
     61 ////                    double d = (pBytesRead+0.0)/pContentLength;
     62 //                    System.out.println(pBytesRead+">>>"+pContentLength+">>"+pItems);
     63 //                }
     64 //            });
     65             
     66 //            upload.setFileSizeMax(2*1024*1024);//设置单文件大小
     67 //            upload.setSizeMax(3*1024*1024);//设置总文件大小
     68             //得到了List<FileItem>
     69             List<FileItem> items = upload.parseRequest(request);
     70             //遍历:
     71             for(FileItem item:items){
     72                 //遇到普通字段:做出自己的处理
     73                 if(item.isFormField()){
     74                     processFormField(item);
     75                 }else{
     76                 //遇到上传字段:实现文件的上传
     77                     
     78                     String mimeType = item.getContentType();//获取上传输入域的MIME类型
     79                     if(!mimeType.startsWith("image")){
     80                         //日志记录一下
     81                         continue;
     82                     }
     83                     processUploadField(item);
     84                 }
     85             }
     86             response.getWriter().write("上传成功!");
     87         }catch(FileUploadBase.FileSizeLimitExceededException e) {
     88             response.getWriter().write("单文件不能超过2M");
     89         }catch(FileUploadBase.SizeLimitExceededException e){
     90             response.getWriter().write("总文件不能超过3M");
     91         }catch (FileUploadException e) {
     92             e.printStackTrace();
     93             throw new RuntimeException("解析请求内容时遇到了错误");
     94         }
     95         
     96     }
     97     //处理上传文件
     98     protected void processUploadField(FileItem item) {
     99         try {
    100             //获取输入流
    101 //            InputStream in = item.getInputStream();
    102             //得到上传文件的文件名
    103             String fileName = getFileName(item.getName());//  浏览:C:UserswzhtingDesktopa.txt   浏览器:a.txt
    104             //构建输出流
    105 //            OutputStream out = new FileOutputStream(storeDirectoryRealPath+"/"+fileName);
    106 //            int len = -1;
    107 //            byte b[] = new byte[1024];
    108 //            while((len=in.read(b))!=-1){
    109 //                out.write(b, 0, len);
    110 //            }
    111 //            in.close();
    112 //            out.close();
    113 //            item.delete();//删除临时文件
    114             item.write(new File(storeDirectoryRealPath+"/"+fileName));
    115             
    116         } catch (IOException e) {
    117             throw new RuntimeException("读取上传文件出错");
    118         }catch(Exception e){
    119             throw new RuntimeException("写文件出错");
    120         }
    121         
    122     }
    123     /**
    124      * 如果文件路径是whole path,截取文件名
    125      * @param fileName
    126      */
    127     protected String getFileName(String fileName) {
    128         if(fileName.indexOf("\")!=-1){
    129             fileName = fileName.substring(fileName.lastIndexOf("\")+1);
    130         }
    131         return fileName;
    132     }
    133     //处理普通字段内容
    134     protected void processFormField(FileItem item) {
    135         String fieldName = item.getFieldName();//普通字段名
    136         String fieldValue = item.getString();//普通字段值
    137         System.out.println(fieldName+"="+fieldValue);
    138     }
    139 
    140     public void doPost(HttpServletRequest request, HttpServletResponse response)
    141             throws ServletException, IOException {
    142         doGet(request, response);
    143     }
    144 
    145 }
    UploadServlet2
     1 <?xml version="1.0" encoding="UTF-8"?>
     2 <web-app version="2.5" 
     3     xmlns="http://java.sun.com/xml/ns/javaee" 
     4     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     5     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
     6     http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
     7   <display-name></display-name>
     8   <context-param>
     9           <param-name>storeDirectory</param-name>
    10         <param-value>/WEB-INF/files</param-value>
    11   </context-param>
    12   <filter>
    13       <filter-name>SetAllCharacterEncodingFilter</filter-name>
    14       <filter-class>com.itheima.filter.SetAllCharacterEncodingFilter</filter-class>
    15   </filter>
    16   <filter-mapping>
    17       <filter-name>SetAllCharacterEncodingFilter</filter-name>
    18       <url-pattern>/*</url-pattern>
    19   </filter-mapping>
    20   <servlet>
    21     <servlet-name>UploadServlet2</servlet-name>
    22     <servlet-class>com.itheima.servlet.UploadServlet2</servlet-class>
    23   </servlet>
    24   <servlet-mapping>
    25     <servlet-name>UploadServlet2</servlet-name>
    26     <url-pattern>/servlet/UploadServlet2</url-pattern>
    27   </servlet-mapping>
    28   <welcome-file-list>
    29     <welcome-file>index.jsp</welcome-file>
    30   </welcome-file-list>
    31 </web-app>
    web.xml

    文件上传时需要考虑几个问题

    1.如何保证服务器安全问题:背景:将jsp文件上传,并访问,会出现安全问题

                解决方案:把存放目录放到WEB-INF目录下;

    2.中文乱码问题:

      2.1:普通字段的中文乱码:解决方案:FileItem.getString(encoding):编码要与浏览器的编码一致

      

      2.2:上传文件名是中文:解决方案:request.setCharacterEncoding(encoding):通知服务器,请求正文的编码类型

      

    3.同一个文件夹下文件同名被覆盖问题:

      1.解决方案:文件名唯一即可;a.txt---->UUID.randomUUID().toString()+"_"+a.txt(filename)

       

    4.上传文件分目录存储:

      1.分用户名目录存储:

      2.按照日期分目录存储: 

     1     //按照日期分目录存储文件
     2     protected String getFileName(String fileName) {
     3     String name = super.getFileName(fileName);// a.txt
     4     //按照日期创建目录
     5     Date now = new Date();
     6     DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
     7     String date = df.format(now);
     8     //拼接该目录的真实存放路径
     9     String directoryPath = storeDirectoryRealPath+"/"+date;
    10     File directory = new File(directoryPath);
    11     if(!directory.exists())
    12         directory.mkdirs();
    13     
    14     return date+"/"+UUID.randomUUID().toString()+"_"+name;
    15     }    
    View Code 

      3.按照文件名hashCode计算存放目录 (二级目录)

     1     //按照UUID文件名的hashCode计算存放目录
     2     protected String getFileName(String fileName) {
     3         String name = super.getFileName(fileName);// a.txt
     4         String uuidFileName = UUID.randomUUID().toString()+"_"+name;// ae427cfa-4920-418a-992a-59553e54a302_a.txt
     5         
     6         /*
     7         hashCode:
     8             1001 1100 0101 1010 1111 0001
     9             0000 0000 0000 0000 0000 1111  &0xf
    10             -----------------------------------
    11             0000 0000 0000 0000 0000 0001    取hash码的最低4位:0000~1111 十进制:0~15
    12         hashCode:
    13             1001 1100 0101 1010 1111 0001
    14             0000 0000 0000 0000 1111 0000 &0xf0
    15             -----------------------------------
    16             0000 0000 0000 0000 1111 0000  取hash码的最低5~8位
    17             -----------------------------------
    18                         >>4
    19             0000 0000 0000 0000 0000 1111:0000~1111 十进制:0~15
    20          */
    21         
    22         int hashCode = uuidFileName.hashCode();
    23         int dir1 = hashCode&0xf;//一级目录
    24         int dir2 = (hashCode&0xf0)>>4;//二级目录
    25         
    26         String newPath = dir1+"/"+dir2;
    27         String directoryPath = storeDirectoryRealPath+"/"+newPath;
    28         File directory = new File(directoryPath);
    29         if(!directory.exists())
    30             directory.mkdirs();
    31         
    32         return newPath+"/"+uuidFileName;
    33     }
    getFileName

    5.限制文件的上传大小:

      5.1:限制单个文件的上传大小

      5.2:限制总文件上传大小(多个上传域)

      1 import java.io.File;
      2 import java.io.FileOutputStream;
      3 import java.io.IOException;
      4 import java.io.InputStream;
      5 import java.io.OutputStream;
      6 import java.util.List;
      7 import java.util.UUID;
      8 
      9 import javax.servlet.GenericServlet;
     10 import javax.servlet.ServletException;
     11 import javax.servlet.http.HttpServlet;
     12 import javax.servlet.http.HttpServletRequest;
     13 import javax.servlet.http.HttpServletResponse;
     14 
     15 import org.apache.commons.fileupload.FileItem;
     16 import org.apache.commons.fileupload.FileUploadBase;
     17 import org.apache.commons.fileupload.FileUploadException;
     18 import org.apache.commons.fileupload.ProgressListener;
     19 import org.apache.commons.fileupload.disk.DiskFileItemFactory;
     20 import org.apache.commons.fileupload.servlet.ServletFileUpload;
     21 //借助commons-fileupload实现文件上传:入门案例
     22 public class UploadServlet2 extends HttpServlet {
     23     protected String storeDirectoryRealPath;//存放文件目录的真实路径
     24     //获取初始化参数:上传文件的存放目录
     25     public void init() throws ServletException {
     26         String storeDirectory = "/upload";//默认的存放上传文件的位置
     27         String value = getServletContext().getInitParameter("storeDirectory");
     28         if(value!=null){
     29             storeDirectory = value;
     30         }
     31         //该目录可能不存在
     32             //得到文件的真实路径
     33             storeDirectoryRealPath = getServletContext().getRealPath(storeDirectory);
     34             //判断文件夹是否存在,不存在,创建它
     35             File directory = new File(storeDirectoryRealPath);
     36             if(!directory.exists())
     37                 directory.mkdirs();
     38     }
     39     public void doGet(HttpServletRequest request, HttpServletResponse response)
     40             throws ServletException, IOException {
     41         //判断用户的请求内容是否是mutlipart/form-data类型的
     42         boolean isMultipart = ServletFileUpload.isMultipartContent(request);
     43         if(!isMultipart){
     44             throw new RuntimeException("not a file upload request");
     45         }
     46         try {
     47             //创建DiskFileItemFactory,并设置缓存和临时文件的存放目录(服务器)
     48             DiskFileItemFactory factory = new DiskFileItemFactory();
     49             
     50             factory.setRepository(new File("d:/"));
     51             
     52             //创建ServletFileUpload, 核心解析类
     53             ServletFileUpload upload = new ServletFileUpload(factory);
     54 //            upload.setProgressListener(new ProgressListener() {
     55 //                /**
     56 //                 * pBytesRead:已经读取的字节数
     57 //                 * pContentLength:总上传文件的大小
     58 //                 * pItems:当前处理的表单项
     59 //                 */
     60 //                public void update(long pBytesRead, long pContentLength, int pItems) {
     61 ////                    double d = (pBytesRead+0.0)/pContentLength;
     62 //                    System.out.println(pBytesRead+">>>"+pContentLength+">>"+pItems);
     63 //                }
     64 //            });
     65             
     66 //            upload.setFileSizeMax(2*1024*1024);//设置单文件大小
     67 //            upload.setSizeMax(3*1024*1024);//设置总文件大小
     68             //得到了List<FileItem>
     69             List<FileItem> items = upload.parseRequest(request);
     70             //遍历:
     71             for(FileItem item:items){
     72                 //遇到普通字段:做出自己的处理
     73                 if(item.isFormField()){
     74                     processFormField(item);
     75                 }else{
     76                 //遇到上传字段:实现文件的上传
     77                     
     78                     String mimeType = item.getContentType();//获取上传输入域的MIME类型
     79                     if(!mimeType.startsWith("image")){
     80                         //日志记录一下
     81                         continue;
     82                     }
     83                     processUploadField(item);
     84                 }
     85             }
     86             response.getWriter().write("上传成功!");
     87         }catch(FileUploadBase.FileSizeLimitExceededException e) {
     88             response.getWriter().write("单文件不能超过2M");
     89         }catch(FileUploadBase.SizeLimitExceededException e){
     90             response.getWriter().write("总文件不能超过3M");
     91         }catch (FileUploadException e) {
     92             e.printStackTrace();
     93             throw new RuntimeException("解析请求内容时遇到了错误");
     94         }
     95         
     96     }
     97     //处理上传文件
     98     protected void processUploadField(FileItem item) {
     99         try {
    100             //获取输入流
    101 //            InputStream in = item.getInputStream();
    102             //得到上传文件的文件名
    103             String fileName = getFileName(item.getName());//  浏览:C:UserswzhtingDesktopa.txt   浏览器:a.txt
    104             //构建输出流
    105 //            OutputStream out = new FileOutputStream(storeDirectoryRealPath+"/"+fileName);
    106 //            int len = -1;
    107 //            byte b[] = new byte[1024];
    108 //            while((len=in.read(b))!=-1){
    109 //                out.write(b, 0, len);
    110 //            }
    111 //            in.close();
    112 //            out.close();
    113 //            item.delete();//删除临时文件
    114             item.write(new File(storeDirectoryRealPath+"/"+fileName));
    115             
    116         } catch (IOException e) {
    117             throw new RuntimeException("读取上传文件出错");
    118         }catch(Exception e){
    119             throw new RuntimeException("写文件出错");
    120         }
    121         
    122     }
    123     /**
    124      * 如果文件路径是whole path,截取文件名
    125      * @param fileName
    126      */
    127     protected String getFileName(String fileName) {
    128         if(fileName.indexOf("\")!=-1){
    129             fileName = fileName.substring(fileName.lastIndexOf("\")+1);
    130         }
    131         return fileName;
    132     }
    133     //处理普通字段内容
    134     protected void processFormField(FileItem item) {
    135         String fieldName = item.getFieldName();//普通字段名
    136         String fieldValue = item.getString();//普通字段值
    137         System.out.println(fieldName+"="+fieldValue);
    138     }
    139 
    140     public void doPost(HttpServletRequest request, HttpServletResponse response)
    141             throws ServletException, IOException {
    142         doGet(request, response);
    143     }
    144 
    145 }
    View Code

    6.限制文件上传类型:

        MIME类型+文件的扩展名

        只允许上传图片:MIME设置(大类型/小类型)

     

    7.临时文件的处理:

      超出缓存会采用磁盘临时文件来缓存

       FileItem.writer():使用该方法处理上传。临时文件会自动清理。(推荐)

      

      手动删除:FileItem.delete();

    8.文件上传进度条:(ajax)

      

     1 upload.setProgressListener(new ProgressListener() {
     2     /**
     3      * pBytesRead:已经读取的字节数
     4      * pContentLength:总上传文件的大小
     5      * pItems:当前处理的表单项
     6      */
     7     public void update(long pBytesRead, long pContentLength, int pItems) {
     8             double d = (pBytesRead+0.0)/pContentLength;
     9         System.out.println(pBytesRead+">>>"+pContentLength+">>"+pItems);
    10     }
    11 });
    上传进度监听器

      

    文件的下载

     1 import java.io.IOException;
     2 import java.io.UnsupportedEncodingException;
     3 
     4 import javax.servlet.Filter;
     5 import javax.servlet.FilterChain;
     6 import javax.servlet.FilterConfig;
     7 import javax.servlet.ServletException;
     8 import javax.servlet.ServletRequest;
     9 import javax.servlet.ServletResponse;
    10 import javax.servlet.http.HttpServletRequest;
    11 import javax.servlet.http.HttpServletRequestWrapper;
    12 import javax.servlet.http.HttpServletResponse;
    13 //解决GET和POST请求参数和响应输出的编码过滤器
    14 public class SetAllCharacterEncodingFilter implements Filter {
    15     private FilterConfig filterConfig;
    16     public void init(FilterConfig filterConfig) throws ServletException {
    17         this.filterConfig = filterConfig;
    18     }
    19 
    20     public void doFilter(ServletRequest req, ServletResponse resp,
    21             FilterChain chain) throws IOException, ServletException {
    22         HttpServletRequest request;
    23         HttpServletResponse response;
    24         try{
    25             request = (HttpServletRequest)req;
    26             response = (HttpServletResponse)resp;
    27         }catch(Exception e){
    28             throw new RuntimeException("non-http request");
    29         }
    30         String encoding = "UTF-8";//默认参数
    31         String value = filterConfig.getInitParameter("encoding");
    32         if(value!=null){
    33             encoding = value;
    34         }
    35         
    36         request.setCharacterEncoding(encoding);//POST请求方式
    37         response.setCharacterEncoding(encoding);
    38         response.setContentType("text/html;charset="+encoding);
    39         MyHttpServletRequest mrequest = new MyHttpServletRequest(request);
    40         chain.doFilter(mrequest, response);
    41     }
    42 
    43     public void destroy() {
    44 
    45     }
    46 
    47 }
    48 class MyHttpServletRequest extends HttpServletRequestWrapper{
    49     private HttpServletRequest request;
    50     public MyHttpServletRequest(HttpServletRequest request){
    51         super(request);
    52         this.request = request;
    53     }
    54     public String getParameter(String name) {
    55         String value = request.getParameter(name);
    56         if(value==null)
    57             return value;
    58         try {
    59             if("get".equalsIgnoreCase(request.getMethod()))
    60                 value = new String(value.getBytes("ISO-8859-1"),request.getCharacterEncoding());
    61         } catch (UnsupportedEncodingException e) {
    62             e.printStackTrace();
    63         }
    64         return value;
    65     }
    66     
    67 }
    编码过滤器
     1 package com.itheima.servlet;
     2 
     3 import java.io.File;
     4 import java.io.UnsupportedEncodingException;
     5 import java.text.DateFormat;
     6 import java.text.SimpleDateFormat;
     7 import java.util.Date;
     8 import java.util.UUID;
     9 
    10 import org.apache.commons.fileupload.FileItem;
    11 
    12 public class UploadServlet3 extends UploadServlet2 {
    13     
    14     protected void processFormField(FileItem item) {
    15         String fieldName = item.getFieldName();//普通字段名
    16         String fieldValue;
    17         try {
    18             fieldValue = item.getString("UTF-8");//普通字段值,指定编码,该编码和浏览器使用的编码要对应
    19         System.out.println(fieldName+"="+fieldValue);
    20         } catch (UnsupportedEncodingException e) {
    21             // TODO Auto-generated catch block
    22             e.printStackTrace();
    23         }
    24     }
    25 
    26     //按照日期分目录存储文件
    27 //    protected String getFileName(String fileName) {
    28 //        String name = super.getFileName(fileName);// a.txt
    29 //        //按照日期创建目录
    30 //        Date now = new Date();
    31 //        DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
    32 //        String date = df.format(now);
    33 //        //拼接该目录的真实存放路径
    34 //        String directoryPath = storeDirectoryRealPath+"/"+date;
    35 //        File directory = new File(directoryPath);
    36 //        if(!directory.exists())
    37 //            directory.mkdirs();
    38 //        
    39 //        return date+"/"+UUID.randomUUID().toString()+"_"+name;
    40 //    }
    41     //按照UUID文件名的hashCode计算存放目录
    42     protected String getFileName(String fileName) {
    43         String name = super.getFileName(fileName);// a.txt
    44         String uuidFileName = UUID.randomUUID().toString()+"_"+name;// ae427cfa-4920-418a-992a-59553e54a302_a.txt
    45         
    46         /*
    47         hashCode:
    48             1001 1100 0101 1010 1111 0001
    49             0000 0000 0000 0000 0000 1111  &0xf
    50             -----------------------------------
    51             0000 0000 0000 0000 0000 0001    取hash码的最低4位:0000~1111 十进制:0~15
    52         hashCode:
    53             1001 1100 0101 1010 1111 0001
    54             0000 0000 0000 0000 1111 0000 &0xf0
    55             -----------------------------------
    56             0000 0000 0000 0000 1111 0000  取hash码的最低5~8位
    57             -----------------------------------
    58                         >>4
    59             0000 0000 0000 0000 0000 1111:0000~1111 十进制:0~15
    60          */
    61         
    62         int hashCode = uuidFileName.hashCode();
    63         int dir1 = hashCode&0xf;//一级目录
    64         int dir2 = (hashCode&0xf0)>>4;//二级目录
    65         
    66         String newPath = dir1+"/"+dir2;
    67         String directoryPath = storeDirectoryRealPath+"/"+newPath;
    68         File directory = new File(directoryPath);
    69         if(!directory.exists())
    70             directory.mkdirs();
    71         
    72         return newPath+"/"+uuidFileName;
    73     }
    74 
    75 }
    上传文件servlet
     1 package com.itheima.servlet;
     2 
     3 import java.io.File;
     4 import java.io.FileInputStream;
     5 import java.io.IOException;
     6 import java.io.InputStream;
     7 import java.io.OutputStream;
     8 import java.net.URLEncoder;
     9 
    10 import javax.servlet.ServletException;
    11 import javax.servlet.http.HttpServlet;
    12 import javax.servlet.http.HttpServletRequest;
    13 import javax.servlet.http.HttpServletResponse;
    14 
    15 public class DownloadServlet extends HttpServlet {
    16 
    17     public void doGet(HttpServletRequest request, HttpServletResponse response)
    18             throws ServletException, IOException {
    19         String uuidfilename = request.getParameter("filename");//get方式,注意编码问题
    20         //计算文件所在的目录
    21         String storeDirectory = getServletContext().getRealPath("/WEB-INF/files");
    22         String path = makeDirs(storeDirectory, uuidfilename);
    23         File file = new File(storeDirectory+"\"+path+"\"+uuidfilename);
    24         if(file.exists()){
    25             //通知客户端以下载的方式打开
    26             
    27             String filename = uuidfilename.substring(uuidfilename.indexOf("_")+1);//获取老文件名  哈里波波.jpg
    28             response.setHeader("Content-Disposition", "attachment;filename="+URLEncoder.encode(filename, "UTF-8"));
    29             response.setHeader("Content-Type", "application/octet-stream");//通知客户端正文的MIME类型
    30             //开始下载
    31             InputStream in = new FileInputStream(file);
    32             OutputStream out = response.getOutputStream();
    33             int len = -1;
    34             byte b[] = new byte[1024];
    35             while((len=in.read(b))!=-1){
    36                 out.write(b, 0, len);
    37             }
    38             in.close();
    39         }else{
    40             response.getOutputStream().write("您下载的资源不存在".getBytes("UTF-8"));
    41         }
    42     }
    43 
    44     
    45     public String makeDirs(String storeDirectoryRealPath,String uuidFilename){
    46         int hashCode = uuidFilename.hashCode();
    47         int dir1 = hashCode&0xf;//一级目录
    48         int dir2 = (hashCode&0xf0)>>4;//二级目录
    49         
    50         String newPath = dir1+"/"+dir2;
    51         String directoryPath = storeDirectoryRealPath+"/"+newPath;
    52         File directory = new File(directoryPath);
    53         if(!directory.exists())
    54             directory.mkdirs();
    55         return newPath;
    56     }
    57     
    58     public void doPost(HttpServletRequest request, HttpServletResponse response)
    59             throws ServletException, IOException {
    60         doGet(request, response);
    61     }
    62 
    63 }
    下载servlet
     1 import java.io.File;
     2 import java.io.IOException;
     3 import java.util.HashMap;
     4 import java.util.Map;
     5 
     6 import javax.servlet.ServletException;
     7 import javax.servlet.http.HttpServlet;
     8 import javax.servlet.http.HttpServletRequest;
     9 import javax.servlet.http.HttpServletResponse;
    10 //遍历:WEB-INF/files目录下的所有文件。
    11 //交给JSP去显示
    12 public class ShowAllFilesServlet extends HttpServlet {
    13     public void doGet(HttpServletRequest request, HttpServletResponse response)
    14             throws ServletException, IOException {
    15         Map<String, String> map = new HashMap<String, String>();// key:UUID的文件名  value:老文件名 a.txt
    16         //遍历WEB-INF/files下的所有文件,并把文件名放到map中
    17         
    18         String storeDirectory = getServletContext().getRealPath("/WEB-INF/files");
    19         File file = new File(storeDirectory);
    20         treeWalk(file,map);
    21         
    22         //封装参数,交给JSP显示
    23         request.setAttribute("map", map);
    24         request.getRequestDispatcher("/listFile.jsp").forward(request, response);
    25     }
    26     //递归遍历,找出所有的文件名称
    27     private void treeWalk(File file, Map<String, String> map) {
    28         if(file.isFile()){
    29             String uuidFileName = file.getName();// UUID_a_a.txt
    30             String fileName =uuidFileName.substring(uuidFileName.indexOf("_")+1);//a_a.txt
    31             map.put(uuidFileName, fileName);
    32         }else{
    33             File[] files = file.listFiles();
    34             for(File f:files){
    35                 treeWalk(f, map);
    36             }
    37         }
    38     }
    39 
    40     public void doPost(HttpServletRequest request, HttpServletResponse response)
    41             throws ServletException, IOException {
    42         doGet(request, response);
    43     }
    44 
    45 }
    展示所有文件servlet
     1 <%@ page import="java.util.*" pageEncoding="UTF-8"%>
     2 <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
     3 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
     4 <html>
     5   <head>
     6     <title>title</title> 
     7     <meta http-equiv="pragma" content="no-cache">
     8     <meta http-equiv="cache-control" content="no-cache">
     9     <meta http-equiv="expires" content="0">    
    10     <!--
    11     <link rel="stylesheet" type="text/css" href="styles.css">
    12     -->
    13 
    14   </head>
    15   
    16   <body>
    17     <h1>本站有以下不堪入目的图片</h1>
    18     <c:forEach items="${map}" var="me">
    19         <c:url value="/servlet/DownloadServlet" var="url">
    20             <c:param name="filename" value="${me.key}"></c:param>
    21         </c:url>
    22         ${me.value}&nbsp;&nbsp;<a href="${url}">下载</a><br/>
    23     </c:forEach>
    24   </body>
    25 </html>
    ListFile
     1 <?xml version="1.0" encoding="UTF-8"?>
     2 <web-app version="2.5" 
     3     xmlns="http://java.sun.com/xml/ns/javaee" 
     4     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     5     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
     6     http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
     7   <display-name></display-name>
     8   <context-param>
     9           <param-name>storeDirectory</param-name>
    10         <param-value>/WEB-INF/files</param-value>
    11   </context-param>
    12   <filter>
    13       <filter-name>SetAllCharacterEncodingFilter</filter-name>
    14       <filter-class>com.itheima.filter.SetAllCharacterEncodingFilter</filter-class>
    15   </filter>
    16   <filter-mapping>
    17       <filter-name>SetAllCharacterEncodingFilter</filter-name>
    18       <url-pattern>/*</url-pattern>
    19   </filter-mapping>
    20   <servlet>
    21     <servlet-name>UploadServlet1</servlet-name>
    22     <servlet-class>com.itheima.servlet.UploadServlet1</servlet-class>
    23     
    24   </servlet>
    25   <servlet>
    26     <servlet-name>UploadServlet2</servlet-name>
    27     <servlet-class>com.itheima.servlet.UploadServlet2</servlet-class>
    28   </servlet>
    29   <servlet>
    30     <servlet-name>UploadServlet3</servlet-name>
    31     <servlet-class>com.itheima.servlet.UploadServlet3</servlet-class>
    32   </servlet>
    33   <servlet>
    34     <servlet-name>ShowAllFilesServlet</servlet-name>
    35     <servlet-class>com.itheima.servlet.ShowAllFilesServlet</servlet-class>
    36   </servlet>
    37   <servlet>
    38     <servlet-name>DownloadServlet</servlet-name>
    39     <servlet-class>com.itheima.servlet.DownloadServlet</servlet-class>
    40   </servlet>
    41 
    42 
    43 
    44 
    45 
    46   <servlet-mapping>
    47     <servlet-name>UploadServlet1</servlet-name>
    48     <url-pattern>/servlet/UploadServlet1</url-pattern>
    49   </servlet-mapping>
    50   <servlet-mapping>
    51     <servlet-name>UploadServlet2</servlet-name>
    52     <url-pattern>/servlet/UploadServlet2</url-pattern>
    53   </servlet-mapping>
    54   <servlet-mapping>
    55     <servlet-name>UploadServlet3</servlet-name>
    56     <url-pattern>/servlet/UploadServlet3</url-pattern>
    57   </servlet-mapping>
    58   <servlet-mapping>
    59     <servlet-name>ShowAllFilesServlet</servlet-name>
    60     <url-pattern>/servlet/ShowAllFilesServlet</url-pattern>
    61   </servlet-mapping>
    62   <servlet-mapping>
    63     <servlet-name>DownloadServlet</servlet-name>
    64     <url-pattern>/servlet/DownloadServlet</url-pattern>
    65   </servlet-mapping>    
    66   <welcome-file-list>
    67     <welcome-file>index.jsp</welcome-file>
    68   </welcome-file-list>
    69 </web-app>
    web.xml

    观察者设计模式(监听器)

    1、事件源:发生事件的对象

    2、监听器:监听事件源上的发送的事件

    3、事件对象:每发生一个事件都会产生一个事件对象,事件对象中封装了事件源

     1 package com.itheima;
     2 //事件源
     3 public class Student {
     4     private String name;
     5     private StudentListener listener;
     6     public Student(String name){
     7         this.name = name;
     8     }
     9     public void sleep(){
    10         System.out.println(name+"睡觉");
    11     }
    12     public void study(){
    13         if(listener!=null){//注册了监听器
    14             listener.preStudent(new StudentEvent(this));
    15         }
    16         System.out.println(name+"学习Java编程");
    17     }
    18     //注册监听器
    19     public void addStudentListener(StudentListener listener){
    20         this.listener = listener;
    21     }
    22     public String getName() {
    23         return name;
    24     }
    25     public void setName(String name) {
    26         this.name = name;
    27     }
    28     
    29 }
    Student
     1 package com.itheima;
     2 
     3 public class StudentDemo {
     4     public static void main(String[] args) {
     5         Student s = new Student("王斐");
     6         
     7         //注册事件监听器
     8         s.addStudentListener(new MyStudentListener());
     9         
    10         s.sleep();
    11         s.study();
    12     }
    13 }
    14 class MyStudentListener implements StudentListener{
    15 
    16     public void preStudent(StudentEvent e) {
    17         Student s = (Student)e.getSource();
    18         String name = s.getName();
    19         System.out.println(name+"一定要边学边练,还得做好笔记");
    20     }
    21 
    22     public void preSleep(StudentEvent e) {
    23         
    24     }
    25     
    26 }
    StudentDemo
     1 package com.itheima;
     2 //事件对象
     3 public class StudentEvent {
     4     private Object source;
     5     public StudentEvent(Object source){
     6         this.source = source;
     7     }
     8     public Object getSource() {
     9         return source;
    10     }
    11     
    12 }
    StudentEvent
    1 package com.itheima;
    2 //监听器
    3 public interface StudentListener {
    4     void preStudent(StudentEvent e);
    5     void preSleep(StudentEvent e);
    6 }
    StudentListener 

    Servlet规范中的八个监听器

    7.1监听ServletContext、HttpSession、ServletRequest对象的创建和销毁的监听器

    注册监听:web.xml

    <listener></listener>

        ServletContextListener

     1 import javax.servlet.ServletContext;
     2 import javax.servlet.ServletContextEvent;
     3 import javax.servlet.ServletContextListener;
     4 /*
     5 非常有用:
     6 ServletContext初始化一次,contextInitialized也就调用一次
     7 完成系统启动时的初始化工作。
     8 
     9 比如:
    10 一个配置文件中定义了很多的JavaBean
    11 <beans>
    12     <bean id="xxDao1" class="XXXDao1Impl"/>
    13     <bean id="xxDao2" class="XXXDao2Impl"/>
    14     ...
    15 </beans>
    16 
    17 问题:用某个dao。在用dao实例时已经创建好的对象效率要高
    18 
    19 在启动时,读取xml配置文件,把所有的bean都实例化,并放到内存中。
    20 
    21 Spring:
    22 
    23 
    24  */
    25 public class MyServletContextListener implements ServletContextListener {
    26     
    27     public void contextInitialized(ServletContextEvent sce) {
    28         ServletContext sc = sce.getServletContext();
    29         System.out.println("ServletContext对象创建了"+sc);
    30     }
    31 
    32     public void contextDestroyed(ServletContextEvent sce) {
    33         ServletContext sc = sce.getServletContext();
    34         System.out.println("ServletContext对象销毁了"+sc);
    35     }
    36 
    37 }
    MyServletContextListener 

        HttpSessionListener

     1 import javax.servlet.http.HttpSessionEvent;
     2 import javax.servlet.http.HttpSessionListener;
     3 /*
     4 统计当前有多少个客户端在访问
     5  */
     6 public class MyHttpSessionListener implements HttpSessionListener {
     7 
     8     //第一次调用 request.getSession()时
     9     public void sessionCreated(HttpSessionEvent se) {
    10         System.out.println(se.getSession()+"创建了一个会话对象");
    11     }
    12 
    13     public void sessionDestroyed(HttpSessionEvent se) {
    14         System.out.println(se.getSession()+"会话对象销毁了");
    15     }
    16 
    17 }
    MyHttpSessionListener

     

    配置Httpsession的过时时间及存放位置:

        ServletRequestListener:统计网站中资源的访问次数:

                                Map<String,Integer>  key:资源的URL,value:访问次数

    7.2监听ServletContext、HttpSession、ServletRequest对象中域中数据变化的监听器

    • ServletContextAttributeListener
    • HttpSessionAttributeListener
    • ServletRequestAttributeListener
    •  1 import javax.servlet.ServletContextAttributeEvent;
       2 import javax.servlet.ServletContextAttributeListener;
       3 
       4 public class MyServletContextAttributeListener implements
       5         ServletContextAttributeListener {
       6 
       7     public void attributeAdded(ServletContextAttributeEvent scab) {
       8         System.out.println("添加了新数据");
       9     }
      10 
      11     public void attributeRemoved(ServletContextAttributeEvent scab) {
      12         System.out.println("移除了数据");
      13 
      14     }
      15 
      16     public void attributeReplaced(ServletContextAttributeEvent scab) {
      17         System.out.println("数据被替换了");
      18     }
      19 
      20 }
      MyServletContextAttributeListener

    7.3感知型监听器:不需要注册。谁实现了该类型的监听器,就能检测到自身的变化

    HttpSessionBindingListener:感知自己何时被绑/解绑HttpSession域中。

    HttpSessionActivationListener:感知自己何时随着HttpSession钝化/激活。

    踢人案例

    查看文件

    合群是堕落的开始 优秀的开始是孤行
  • 相关阅读:
    IDEA tomcat热部署方法及乱码问题解决
    访问WEB-INF下JSP资源的几种方式(转)
    SpringMVC 静态资源处理
    SpringMVC中的拦截器
    SpringMVC中的异常处理
    SpringMVC实现文件上传
    IDEA 热部署
    响应数据和结果视图
    SpringMVC中的常用注解
    js获取当前根目录的方法
  • 原文地址:https://www.cnblogs.com/biaogejiushibiao/p/9344521.html
Copyright © 2011-2022 走看看