您当前的位置: 首页 >  Java

彭世瑜

暂无认证

  • 0浏览

    0关注

    2791博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

Java学习路线-49:Servlet过滤器Filter

彭世瑜 发布时间:2020-02-23 11:14:13 ,浏览量:0

课时1 过滤器的入门

JavaWeb三大组件 1、都需要在web.xml中进行配置 Servlet Filter Listener

2、过滤器 会在一组资源(jsp, servlet, css, html等等)的前面执行 可以让请求得到目标资源,也可以不让请求达到 过滤器有拦截请求的能力

3、编写过滤器 (1)实现Filter接口 (2)在web.xml中进行配置 (3)Filter是单例的

4、配置web.xml


    
        FilerName
        FilerClass
    
    
        FilerName
        /*
    

继承示例

package com.pengshiyu.filtrer;

import javax.servlet.*;
import java.io.IOException;

public class Afilter implements Filter {
    /**
     * 创建之后马上执行,用来做初始化
     */
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    /**
     * 每次过滤都会执行
     */
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, 
        FilterChain filterChain) throws IOException, ServletException {
        System.out.println("进入过滤器");
        // 调用后序方法
        filterChain.doFilter(servletRequest, servletResponse);
        System.out.println("离开过滤器");
    }

    /**
     * 销毁之前的调用,用来释放资源
     */
    @Override
    public void destroy() {

    }
}

FilterConfig -> 与ServletConfig相似 获取初始化参数 getInitParameter() 获取过滤器名称 getFilterName() 获取application getServletContext()

FilterChain 放行,执行后序方法 doFilter()

课时2 多个过滤器的执行顺序

执行下一个过滤器或目标资源 FilterChain.doFilter()

Afilter进入过滤器
Bfilter进入过滤器
getAge
Bfilter离开过滤器
Afilter离开过滤器
课时3 四种拦截方式

请求 REQUEST 默认 转发 FORWARD 包含 INCLUDE 错误 ERROR


    FilerName
    /*
    REQUEST

页面出错


    500
    500.html

课时4 使用filter-mapping控制多个Filter的执行顺序

filter-mapping的配置顺序决定过滤器执行顺序

课时5 Filter的应用场景、Filter的目标资源、小结

预处理:执行目标资源之前做预处理工作,例如设置编码 拦截:通过条件判断是否放行,例如用户登录校验 回程拦截:目标资源执行之后,做一些后序的特殊处理工作,例如目标资源输出的数据进行处理

直接指定servlet-name


    FilerName
    ServletName

小结 Filter3个方法 FilterChain类 4中拦截方式

课时6 案例1:分IP统计访问次数

数据结构:

ipcount192.168.0.132192.168.0.222

统计工作在所有资源之前都执行,使用Filter 这个过滤器只做统计,不做拦截 数据Map Map保存到ServletContext中 从request中获取客户端ip

使用监听器创建 map AListener.java

package com.pengshiyu.listener;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import java.util.LinkedHashMap;
import java.util.Map;

public class AListener implements ServletContextListener {
    // 服务器启动时创建map
    public void contextInitialized(ServletContextEvent sce) {
        Map map = new LinkedHashMap();
        sce.getServletContext().setAttribute("map", map);
    }

    public void contextDestroyed(ServletContextEvent sce) {
    }
}

使用过滤器统计数据 AFilter.java

package com.pengshiyu.filter;

import javax.servlet.*;
import java.io.IOException;
import java.util.Map;

public class AFilter implements Filter {
    private FilterConfig config;

    /**
     * 创建之后马上执行,用来做初始化
     */
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        this.config = filterConfig;
    }

    /**
     * 每次过滤都会执行
     */
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, 
        FilterChain filterChain) throws IOException, ServletException {
        ServletContext app = this.config.getServletContext();
        Map map = (Map)app.getAttribute("map");

        String ip  =  request.getRemoteAddr();
        System.out.println("ip: " + ip);

        if(map.containsKey(ip)){
            Integer count = map.get(ip);
            map.put(ip, count+1);
        } else{
            map.put(ip, 1);
        }

        // 放行
        filterChain.doFilter(request, response);

    }

    /**
     * 销毁之前的调用,用来释放资源
     */
    @Override
    public void destroy() {

    }
}

显示数据 BServlet.java

package com.pengshiyu.servlet;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Map;

public class BServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) 
    throws IOException {
        ServletContext app = getServletContext();
        Map map = (Map) app.getAttribute("map");
        
        response.setContentType("text/html; charset=UTF-8");
        response.getWriter().println(map.toString());

    }
}


配置监听器和过滤器生效 web.xml




    
        BServlet
        com.pengshiyu.servlet.BServlet
    
    
        BServlet
        /b
    

    
        AFilter
        com.pengshiyu.filter.AFilter
    
    
        AFilter
        /*
    

    
        com.pengshiyu.listener.AListener
    

课时7 案例2:粗粒度权限管理

基于角色的权限控制RBAC tb_user tb_role tb_userrole tb_menu tb_rolemenu

web.xml




    
        AServlet
        com.pengshiyu.servlet.AServlet
    
    
        AServlet
        /hello
    

    
        AFilter
        com.pengshiyu.filter.AFilter
    
    

        AFilter
        /hello.html
    


AServlet.java

package com.pengshiyu.servlet;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class AServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) 
    throws ServletException, IOException {
        String username = request.getParameter("username");
        System.out.println("post: " + username);
        // 设置session
        request.getSession().setAttribute("username", username);
        // 跳转页面
        request.getRequestDispatcher("hello.html").forward(request, response);
    }
}

过滤器进行简单的权限校验 AFilter.java

package com.pengshiyu.filter;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;

public class AFilter implements Filter {
    private FilterConfig config;
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        this.config = filterConfig;
    }

    @Override
    public void doFilter(ServletRequest req, ServletResponse response, 
        FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest)req;

        String username = (String) request.getSession().getAttribute("username");
        System.out.println("filter: " + username);

        if(username != null){
            // 放行
            filterChain.doFilter(request, response);
        } else{
            // 跳转到登录页
            request.getRequestDispatcher("login.html").forward(request, response);
        }
    }

    @Override
    public void destroy() {

    }
}

课时8 案例3:全站编码问题
// post编码
request.setCharacterEncoding("utf-8");

// get编码
String username = request.getParameter("username");
username = new String(username.getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8);

// 响应编码
response.setContentType("text/html; charset=UTF-8");

HttpServletRequest装饰类 EncodingRequest.java

package com.pengshiyu.filter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.nio.charset.StandardCharsets;

// 装饰器
public class EncodingRequest extends HttpServletRequestWrapper {

    public EncodingRequest(HttpServletRequest request) {
        super(request);
    }

    @Override
    public String getParameter(String name) {
        // 处理编码问题
        String value = super.getParameter(name);
        value = new String(value.getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8);
        return value;

    }
}

过滤器AFilter.java

package com.pengshiyu.filter;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;

public class AFilter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, 
        FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest httpServletRequest = (HttpServletRequest) request;
        String method = httpServletRequest.getMethod();

        // 设置响应编码
        response.setContentType("text/html; charset=UTF-8");

        if ("GET".equals(method)) {
            // 放行
            EncodingRequest encodingRequest = new EncodingRequest(httpServletRequest);
            filterChain.doFilter(encodingRequest, response);
        } else if ("POST".equals(method)) {
            request.setCharacterEncoding("utf-8");
            filterChain.doFilter(request, response);
        }
    }

    @Override
    public void destroy() {

    }
}

响应处理AServlet.java

package com.pengshiyu.servlet;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class AServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) 
    throws ServletException, IOException {
        System.out.println(request.getParameter("name"));
        response.getWriter().print("你好");
    }
}

web.xml




    
    
        AServlet
        com.pengshiyu.servlet.AServlet
    
    
    
        AServlet
        /hello
    

    
        AFilter
        com.pengshiyu.filter.AFilter
    
    

        AFilter
        /*
    

课时9 案例4:页面静态化之准备工作(图书管理小项目)
功能:
查询所有
按分类查看

BookServlet
    findAll()       查询全部
    findByCategory() 按分类查询

BookService: 省略

BookDao:
    List findAll()
    List findByCategory()

Book:
    bid
    bname
    price
    category

静态化: 第一次访问从数据库取数据,保存到html中 第二次之后访问就直接从html中读取,不再从数据库中取数据

数据准备:

create table tb_book(
    bid int primary key auto_increment,
    bname varchar(50),
    price decimal(10, 2),
    category int
);

insert into tb_book(bname, price, category) values("Java", 12, 1);
insert into tb_book(bname, price, category) values("Python", 12, 1);
insert into tb_book(bname, price, category) values("JavaScript", 12, 1);
insert into tb_book(bname, price, category) values("Go", 12, 1);

insert into tb_book(bname, price, category) values("三国演义", 12, 2);
insert into tb_book(bname, price, category) values("西游记", 12, 2);
insert into tb_book(bname, price, category) values("水浒传", 12, 2);
insert into tb_book(bname, price, category) values("红楼梦", 12, 2);

创建对应的Book类

package com.pengshiyu.bean;

public class Book {
    private int bid;
    private String bname;
    private double price;
    private int category;

    public Book() {
    }

    public int getBid() {
        return bid;
    }

    public void setBid(int bid) {
        this.bid = bid;
    }

    public String getBname() {
        return bname;
    }

    public void setBname(String bname) {
        this.bname = bname;
    }

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }

    public int getCategory() {
        return category;
    }

    public void setCategory(int category) {
        this.category = category;
    }

    @Override
    public String toString() {
        return "Book{" +
                "bid=" + bid +
                ", bname='" + bname + '\'' +
                ", price=" + price +
                ", category=" + category +
                '}';
    }
}

BookDao.java

package com.pengshiyu.dao;

import com.pengshiyu.bean.Book;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import util.TxQueryRunner;

import java.sql.SQLException;
import java.util.List;

public class BookDao {
    private QueryRunner qr = new TxQueryRunner();

    public  List findAll() {
        String sql = "select * from tb_book";

        try {
            List list = qr.query(sql, new BeanListHandler(Book.class));
            System.out.println(list);
            return list;
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }

    public  List findByCategory(int category) {
        String sql = "select * from tb_book where category = ?";

        try {
            return qr.query(sql, new BeanListHandler(Book.class), category);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }
}

BookServlet

package com.pengshiyu.servlet;

import com.pengshiyu.dao.BookDao;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class BookServlet extends BaseServlet {
    private BookDao bookDao = new BookDao();

    public void findAll(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
        request.setAttribute("bookList", bookDao.findAll());
        request.getRequestDispatcher("book.jsp").forward(request, response);
    }

    public void findByCategory(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        int category = Integer.parseInt(request.getParameter("category"));
        request.setAttribute("bookList", bookDao.findByCategory(category));
        request.getRequestDispatcher("book.jsp").forward(request, response);

    }
}

用到的工具类 TxQueryRunner.java

package util;

import java.sql.Connection;
import java.sql.SQLException;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.ResultSetHandler;

public class TxQueryRunner extends QueryRunner {

    @Override
    public int[] batch(String sql, Object[][] params) throws SQLException {
        Connection con = JdbcUtil.getConnection();
        int[] result = super.batch(con, sql, params);
        JdbcUtil.releaseConnection(con);
        return result;
    }

    @Override
    public  T query(String sql, ResultSetHandler rsh, Object... params)
            throws SQLException {
        Connection con = JdbcUtil.getConnection();
        T result = super.query(con, sql, rsh, params);
        JdbcUtil.releaseConnection(con);
        return result;
    }

    @Override
    public  T query(String sql, ResultSetHandler rsh) throws SQLException {
        Connection con = JdbcUtil.getConnection();
        T result = super.query(con, sql, rsh);
        JdbcUtil.releaseConnection(con);
        return result;
    }

    @Override
    public int update(String sql) throws SQLException {
        Connection con = JdbcUtil.getConnection();
        int result = super.update(con, sql);
        JdbcUtil.releaseConnection(con);
        return result;
    }

    @Override
    public int update(String sql, Object param) throws SQLException {
        Connection con = JdbcUtil.getConnection();
        int result = super.update(con, sql, param);
        JdbcUtil.releaseConnection(con);
        return result;
    }

    @Override
    public int update(String sql, Object... params) throws SQLException {
        Connection con = JdbcUtil.getConnection();
        int result = super.update(con, sql, params);
        JdbcUtil.releaseConnection(con);
        return result;
    }
}

JdbcUtil.java

package util;

import com.mchange.v2.c3p0.ComboPooledDataSource;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;

public class JdbcUtil {
    // 需要配置c3p0-config.xml
    private static ComboPooledDataSource dataSource = new ComboPooledDataSource();

    // 返回连接对象
    public static Connection getConnection() {
        try {
            return dataSource.getConnection();
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }

    // 返回连接池对象
    public static DataSource getDataSource() {
        return dataSource;
    }

    // 释放连接
    public static void releaseConnection(Connection connection) {

        try {
            connection.close();
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }

}

book.jsp




图书列表
分类:
全部
第一类
第二类


    
        ID
        书名
        价格
        分类
    
    
        
            ${book.bid}
            ${book.bname}
            ${book.price}
            ${book.category}
        
    

配置文件

pom.xml


    jstl
    jstl
    1.2


    taglibs
    standard
    1.1.2

web.xml


    BookServlet
    /book



    BookServlet
    com.pengshiyu.servlet.BookServlet

c3p0-config.xml



    
    
        
        com.mysql.cj.jdbc.Driver
        jdbc:mysql://localhost:3306/data
        root
        123456

        
        2
        2
        2
        10
    

访问路径 http://localhost:8080/demo/book?method=findAll http://localhost:8080/demo/book?method=findByCategory&category=1

课时10 案例4:页面静态化之如果文件存在直接重定向到html

使用一个过滤器,把servlet请求的资源输出保存到html中 第二次访问资源的时候,如果已存在就直接重定向到html文件

课时11 案例5:页面静态之生成html页面

CacheFilter.java

package com.pengshiyu.filter;

import com.pengshiyu.response.StaticResponse;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;

public class CacheFilter implements Filter {
    private FilterConfig config;
    private final String cacheFileName = "cache";
    private String cacheFilePath = null;

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        this.config = filterConfig;
        this.cacheFilePath = this.config.getServletContext().getRealPath(this.cacheFileName);

        File file = new File(this.cacheFilePath);
        if(file.exists()){
            file.mkdir();
        }
        
    }

    /**
     * 访问路径
     * http://localhost:8080/demo/book?method=findByCategory&category=4
     */
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
                         FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest)servletRequest;
        HttpServletResponse response = (HttpServletResponse)servletResponse;

        String category = request.getParameter("category");

        String filepath = this.cacheFilePath + "/" + category + ".html";
        File file = new File(filepath);

        // 如果页面不存在就缓存页面
        if(!file.exists()){
            StaticResponse staticResponse = new StaticResponse(response, filepath);
            filterChain.doFilter(request, staticResponse);
        }

        System.out.println("文件存在了");
        request.getRequestDispatcher(this.cacheFileName + "/" + category + ".html").forward(request, response);

    }

    @Override
    public void destroy() {

    }
}

StaticResponse.java

package com.pengshiyu.response;

import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintWriter;

public class StaticResponse extends HttpServletResponseWrapper {
    private PrintWriter pw;

    public StaticResponse(HttpServletResponse response, String filename) throws FileNotFoundException {
        super(response);
        this.pw = new PrintWriter(filename);
    }

    @Override
    public PrintWriter getWriter() throws IOException {
        // 掉包输出流
        return this.pw;
    }
}

关注
打赏
1665367115
查看更多评论
立即登录/注册

微信扫码登录

0.1185s