Servlet笔记 (九) 过滤器及文件上传下载

一、过滤器高级配置
page指令的错误页面,用的是转发技术
注意:servlet2.5有4个拦截选项,而servlet3.0有5个拦截选项
在web.xml中进行如下配置
    <filter>
        <filter-name>FilterDemo</filter-name>
        <filter-class>com.itheima.filter.FilterDemo</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>FilterDemo</filter-name>
        <url-pattern>/*</url-pattern>
        <!-- 所有错误都会被过滤 -->
        <dispatcher>ERROR</dispatcher>
        <!-- 所有转发都会被过滤-->
        <dispatcher>FORWARD</dispatcher>
        <!-- 所有动态包含都会被过滤 -->
        <dispatcher>INCLUDE</dispatcher>
        <!-- 所有请求都会被过滤 -->
        <dispatcher>REQUEST</dispatcher>
    </filter-mapping>
    <error-page><!-- 配置错误页面 -->
        <!-- 需要抓住的异常是什么类型 -->
        <exception-type>java.lang.Exception</exception-type>
        <!-- 出现错误后,需要转发到哪个页面 -->
        <location>/error.jsp</location>
    </error-page>
 
二、巩固包装设计模式(复习)
建立BufferedReaderDemo
public class BufferedReaderDemo {
    public static void main(String[] args) throws IOException {
        //记住,不能加/
        Reader r = new FileReader("src/com/itheima/filter/FilterDemo.java");
        BufferedReader br = new BufferedReader(r);
        MyBufferedReader mbr = new MyBufferedReader(br);
        String str = null;//记录读到的数据
        while((str=mbr.readLine())!=null){
            System.out.println(str);
        }
        mbr.close();
    }
}
 
建立MyBufferedReader包装类
//包装五步之一,实现被包装相同的接口
public class MyBufferedReader extends BufferedReader {
    private int linenum=1;//行号
    //包装五步之二,引用被包装的对象
    private BufferedReader br;
    //包装五步之三,构造函数传入被包装类的对象
    public MyBufferedReader(BufferedReader br){
        super(br);
        this.br=br;
    }
    //包装五步之四,改写需要修改的方法
    //先拿到原有对象的放回值,然后再做判断后进行包装
    public String readLine() throws IOException {
        String str = br.readLine();
        if(str==null)
            return null;
        if(linenum<10)
            return linenum++ +"  "+":"+str;
        if(linenum>9&&linenum<100)
            return linenum++ +" "+":"+str;
        return linenum++ +":"+str;
    }
    //包装五步之五,不需要改写的方法调用原有对象
}
 
三、过滤器高级案例:4个(有一个很难)
案例一:全站乱码解决
建立AllCharacterEncodingFilter
//实现解决全站乱码问题的过滤器
public class AllCharacterEncodingFilter implements Filter {
    private String encoding = "UTF-8";//设置默认编码
    public void init(FilterConfig filterConfig) throws ServletException {
        //获取配置文件中的信息,初始化信息encoding的值
        String value = filterConfig.getInitParameter("encoding");
        if(value!=null){
            encoding = value;
        }
    }
    public void doFilter(ServletRequest req, ServletResponse resp,
            FilterChain chain) throws IOException, ServletException {
        //必须转成HTTP协议的request类,因为放行后的servlet有可能会使用http协议的方法
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) resp;
        //解决POST请求参数中文编码问题
        request.setCharacterEncoding(encoding);
        //输出编码及通知客户端编码
        response.setCharacterEncoding(encoding);
        response.setContentType("text/html;charset="+encoding);
        //写一个包装类,对request进行包装,包装类必须把被包装的对象传进来;
        MyHttpServletRequest mrequest = new MyHttpServletRequest(request);
        chain.doFilter(mrequest, response);
    }
    public void destroy() {
    }
}
class MyHttpServletRequest extends HttpServletRequestWrapper{
    private HttpServletRequest request;//引用原有对象
    public MyHttpServletRequest(HttpServletRequest request) {
        super(request);
        this.request=request;
    }
    //覆盖方法
    public String getParameter(String name) {
        //获取name的值,后续使用
        String value = request.getParameter(name);
        if(value==null){
            return null;
        }
        //只解决GET请求参数编码问题        //获取提交方式
        String method = request.getMethod();
        //因为浏览器提交的方法名大小写不同,所以比较的时候需要忽略大小写
        if("get".equalsIgnoreCase(method)){
            try {
                //Tomcat的默认编码是ISO-8859-1,所以设置编码的时候需要注意
                value = new String(value.getBytes("ISO-8859-1"), request.getCharacterEncoding());
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
        }
        return value;
    }
}
 
设置配置文
    <filter>
        <filter-name>AllCharacterEncodingFilter</filter-name>
        <filter-class>com.itheima.filter.AllCharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>AllCharacterEncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
 
案例二:脏话过滤器
DirtyWordsFilter(注意要有解决全站乱码的过滤器)
public class DirtyWordsFilter implements Filter {
    public void destroy() {
    }
    public void doFilter(ServletRequest arg1, ServletResponse arg2,
            FilterChain chain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) arg1;
        HttpServletResponse response = (HttpServletResponse) arg2;
        //对request进行包装,过滤
        DwHttpServletRequest dwrequest = new DwHttpServletRequest(request);
        chain.doFilter(dwrequest, response);
    }
    public void init(FilterConfig filterConfig) throws ServletException {
    }
}
class DwHttpServletRequest extends HttpServletRequestWrapper{
    private HttpServletRequest request;
    public DwHttpServletRequest(HttpServletRequest request){
        super(request);
        this.request = request;
    }
    public String getParameter(String name) {
        String value = request.getParameter(name);
        if(value==null){
            return null;
        }//定义脏话字典
        String[] dws = new String[]{"畜生","禽兽"};
        for(String s:dws){
            //判断value里面是否包含脏话字典里的词
            if(value.contains(s)){
                //
                value = value.replace(s, "**");
            }
        }
        return value;
    }
}
 
案例四:全站压缩
注意在进行配置文件设置的时候,只需要设置和文本相关的*.jsp;*.html,*.js;*.css
public class GzipFilter implements Filter {
    public void destroy() {
    }
    public void doFilter(ServletRequest arg1, ServletResponse arg2,
            FilterChain chain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) arg1;
        HttpServletResponse response = (HttpServletResponse) arg2;
        GzipHttpServletResponse gresponse = new GzipHttpServletResponse(response);
        chain.doFilter(request, gresponse);
        //获取原始字节,进行压缩
        byte[] b = gresponse.getBufferData();
        System.out.println("压缩前的大小:"+b.length);//测试用
        //建立一个byte[]输出流,关联到Gzip压缩流
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        //Gzip流需要一个字节输出流来关联,压缩流内的数据
        GZIPOutputStream gos = new GZIPOutputStream(baos);
        gos.write(b);
        gos.close();
        b = baos.toByteArray();//取出缓存中被压缩后的数据
        System.out.println("压缩有的大小:"+b.length);
        //告知浏览器压缩方式,就是设置头
        response.setHeader("Content-Encoding""gzip");
        response.getOutputStream().write(b);
    }
    public void init(FilterConfig filterConfig) throws ServletException {
    }
}
class GzipHttpServletResponse extends HttpServletResponseWrapper{
    private ByteArrayOutputStream baos = new ByteArrayOutputStream();
    private PrintWriter pw;
    public GzipHttpServletResponse(HttpServletResponse response) {
        super(response);
    }
    //servlet是使用getOutputStream获取流输出的
    //覆盖这个方法,把数据写到一个缓存中,就可以进行获得数据
    public ServletOutputStream getOutputStream() throws IOException {
        ServletOutputStream sos = super.getOutputStream();
        MyServletOutputStream msos = new MyServletOutputStream(sos,baos);
        return msos;
    }
    //1如果是字符流则转成字符流,2把数据弄到baos中去
    //查看API文档,PrintWriter的构造函数可以直接调用字符流进行输出
    public PrintWriter getWriter() throws IOException {
        pw = new PrintWriter(new OutputStreamWriter(baossuper.getCharacterEncoding()));
        return pw;
    }
    public byte[] getBufferData() {
        try {
            //关闭Printwriter
            if(pw!=null)
                pw.close();
            baos.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return baos.toByteArray();
    }
}
class MyServletOutputStream extends ServletOutputStream{
    private ServletOutputStream sos;
    private ByteArrayOutputStream baos;
    public MyServletOutputStream(ServletOutputStream sos,ByteArrayOutputStream baos){
        this.sos = sos;
        this.baos = baos;
    }
    public void write(int b) throws IOException {
        baos.write(b);
    }
}
 
案例五,对于常用的动态资源生成的结果进行缓存
web.xml配置  CacheResultFilter
只为category.jsp服务
建立CacheResultFilter 过滤器
建立cache  HashMap。
 
四、文件上传与下载
1.文件上传需要具备的前提:
    a,form表单的method必须是post
    b,form表单的enctype必须是multipart/form-data(一定要记住头和值)
    c,提供。。。。。
2,当表单的enctype=multipart/form-data请求正文的数据如下
 
 
 
建立工程01
建立upload.jsp
建立UploadServlet   servlet---不需要记录
通过输入流得到数据
 
使用Commons-fileupload 组建
还要借助Commons-io
ServletFileupLoad是核心类   需要DiskFilterItemFactory(环境)来创建
tmpdir---java的临时目录
 
修改upload.jsp
建立Upload2Servlet  servlet
拷贝jar包
取得真实的文件路径,非常的重要
 
修改upload.jsp
建立Upload3Servlet  servlet
文件上传,需要考虑的9个问题
 
1,如何保证服务器的安全
把上传文件的目录设置在WEB-INF,客户端无法访问
2,中文乱码:
    普通字段乱码
    上传文件名中文乱码
        
 
 
1,文件名重复
 
3,文件格式限制(比如只允许上传图片)
4,上传文件的大小限制
    一个文件的大小限制
    总文件的大小限制
 
6,同一个目录中文件太多
7,多个文件上传,没有选择文件
8,上传进度提示问题
9,
 
 
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值