100字范文,内容丰富有趣,生活中的好帮手!
100字范文 > Java学习路线-49:Servlet过滤器Filter

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

时间:2019-05-27 21:01:07

相关推荐

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

课时1 过滤器的入门

JavaWeb三大组件

1、都需要在web.xml中进行配置

Servlet

Filter

Listener

2、过滤器

会在一组资源(jsp, servlet, css, html等等)的前面执行

可以让请求得到目标资源,也可以不让请求达到

过滤器有拦截请求的能力

3、编写过滤器

(1)实现Filter接口

(2)在web.xml中进行配置

(3)Filter是单例的

4、配置web.xml

<web-app><filter><filter-name>FilerName</filter-name><filter-class>FilerClass</filter-class></filter><filter-mapping><filter-name>FilerName</filter-name><url-pattern>/*</url-pattern></filter-mapping></web-app>

继承示例

package com.pengshiyu.filtrer;import javax.servlet.*;import java.io.IOException;public class Afilter implements Filter {/*** 创建之后马上执行,用来做初始化*/@Overridepublic void init(FilterConfig filterConfig) throws ServletException {}/*** 每次过滤都会执行*/@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {System.out.println("进入过滤器");// 调用后序方法filterChain.doFilter(servletRequest, servletResponse);System.out.println("离开过滤器");}/*** 销毁之前的调用,用来释放资源*/@Overridepublic void destroy() {}}

FilterConfig -> 与ServletConfig相似

获取初始化参数 getInitParameter()

获取过滤器名称 getFilterName()

获取application getServletContext()

FilterChain

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

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

执行下一个过滤器或目标资源

FilterChain.doFilter()

Afilter进入过滤器Bfilter进入过滤器getAgeBfilter离开过滤器Afilter离开过滤器

课时3 四种拦截方式

请求 REQUEST 默认

转发 FORWARD

包含 INCLUDE

错误 ERROR

<filter-mapping><filter-name>FilerName</filter-name><url-pattern>/*</url-pattern><dispatcher>REQUEST</dispatcher></filter-mapping>

页面出错

<error-page><error-code>500</error-code><location>500.html</location></error-page>

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

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

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

预处理:执行目标资源之前做预处理工作,例如设置编码

拦截:通过条件判断是否放行,例如用户登录校验

回程拦截:目标资源执行之后,做一些后序的特殊处理工作,例如目标资源输出的数据进行处理

直接指定servlet-name

<filter-mapping><filter-name>FilerName</filter-name><servlet-name>ServletName</servlet-name></filter-mapping>

小结

Filter3个方法

FilterChain类

4中拦截方式

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

数据结构:

统计工作在所有资源之前都执行,使用Filter

这个过滤器只做统计,不做拦截

数据Map<String, Integer>

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 {// 服务器启动时创建mappublic void contextInitialized(ServletContextEvent sce) {Map<String, Integer> map = new LinkedHashMap<String, Integer>();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;/*** 创建之后马上执行,用来做初始化*/@Overridepublic void init(FilterConfig filterConfig) throws ServletException {this.config = filterConfig;}/*** 每次过滤都会执行*/@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {ServletContext app = this.config.getServletContext();Map<String, Integer> map = (Map<String, Integer>)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);}/*** 销毁之前的调用,用来释放资源*/@Overridepublic 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 {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {ServletContext app = getServletContext();Map<String, Integer> map = (Map<String, Integer>) app.getAttribute("map");response.setContentType("text/html; charset=UTF-8");response.getWriter().println(map.toString());}}

配置监听器和过滤器生效

web.xml

<?xml version="1.0" encoding="utf-8"?><web-app><servlet><servlet-name>BServlet</servlet-name><servlet-class>com.pengshiyu.servlet.BServlet</servlet-class></servlet><servlet-mapping><servlet-name>BServlet</servlet-name><url-pattern>/b</url-pattern></servlet-mapping><filter><filter-name>AFilter</filter-name><filter-class>com.pengshiyu.filter.AFilter</filter-class></filter><filter-mapping><filter-name>AFilter</filter-name><url-pattern>/*</url-pattern></filter-mapping><listener><listener-class>com.pengshiyu.listener.AListener</listener-class></listener></web-app>

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

基于角色的权限控制RBAC

tb_user

tb_role

tb_userrole

tb_menu

tb_rolemenu

web.xml

<?xml version="1.0" encoding="utf-8"?><web-app><servlet><servlet-name>AServlet</servlet-name><servlet-class>com.pengshiyu.servlet.AServlet</servlet-class></servlet><servlet-mapping><servlet-name>AServlet</servlet-name><url-pattern>/hello</url-pattern></servlet-mapping><filter><filter-name>AFilter</filter-name><filter-class>com.pengshiyu.filter.AFilter</filter-class></filter><filter-mapping><!-- 不能将过滤器设置在login.html上,不然没法登录了--><filter-name>AFilter</filter-name><url-pattern>/hello.html</url-pattern></filter-mapping></web-app>

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 {@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {String username = request.getParameter("username");System.out.println("post: " + username);// 设置sessionrequest.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;@Overridepublic void init(FilterConfig filterConfig) throws ServletException {this.config = filterConfig;}@Overridepublic 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);}}@Overridepublic 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);}@Overridepublic 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 {@Overridepublic void init(FilterConfig filterConfig) throws ServletException {}@Overridepublic 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);}}@Overridepublic 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 {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {System.out.println(request.getParameter("name"));response.getWriter().print("你好");}}

web.xml

<?xml version="1.0" encoding="utf-8"?><web-app><!-- 注册 Servlet,帮助web服务器反射该类 --><servlet><servlet-name>AServlet</servlet-name><servlet-class>com.pengshiyu.servlet.AServlet</servlet-class></servlet><!-- 映射 Servlet 资源,用url-pattern元素标示 URL --><servlet-mapping><servlet-name>AServlet</servlet-name><url-pattern>/hello</url-pattern></servlet-mapping><filter><filter-name>AFilter</filter-name><filter-class>com.pengshiyu.filter.AFilter</filter-class></filter><filter-mapping><!-- 不能将过滤器设置在login.html上,不然没法登录了--><filter-name>AFilter</filter-name><url-pattern>/*</url-pattern></filter-mapping></web-app>

课时9 案例4:页面静态化之准备工作(图书管理小项目)

功能:查询所有按分类查看BookServletfindAll() 查询全部findByCategory() 按分类查询BookService: 省略BookDao:List<Book> findAll()List<Book> findByCategory()Book:bidbnamepricecategory

静态化:

第一次访问从数据库取数据,保存到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;}@Overridepublic String toString() {return "Book{" +"bid=" + bid +", bname='" + bname + '\'' +", price=" + price +", category=" + category +'}';}}

BookDao.java

package com.pengshiyu.dao;import com.pengshiyu.bean.Book;import mons.dbutils.QueryRunner;import mons.dbutils.handlers.BeanListHandler;import util.TxQueryRunner;import java.sql.SQLException;import java.util.List;public class BookDao {private QueryRunner qr = new TxQueryRunner();public List<Book> findAll() {String sql = "select * from tb_book";try {List<Book> list = qr.query(sql, new BeanListHandler<Book>(Book.class));System.out.println(list);return list;} catch (SQLException e) {throw new RuntimeException(e);}}public List<Book> findByCategory(int category) {String sql = "select * from tb_book where category = ?";try {return qr.query(sql, new BeanListHandler<Book>(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 mons.dbutils.QueryRunner;import mons.dbutils.ResultSetHandler;public class TxQueryRunner extends QueryRunner {@Overridepublic int[] batch(String sql, Object[][] params) throws SQLException {Connection con = JdbcUtil.getConnection();int[] result = super.batch(con, sql, params);JdbcUtil.releaseConnection(con);return result;}@Overridepublic <T> T query(String sql, ResultSetHandler<T> rsh, Object... params)throws SQLException {Connection con = JdbcUtil.getConnection();T result = super.query(con, sql, rsh, params);JdbcUtil.releaseConnection(con);return result;}@Overridepublic <T> T query(String sql, ResultSetHandler<T> rsh) throws SQLException {Connection con = JdbcUtil.getConnection();T result = super.query(con, sql, rsh);JdbcUtil.releaseConnection(con);return result;}@Overridepublic int update(String sql) throws SQLException {Connection con = JdbcUtil.getConnection();int result = super.update(con, sql);JdbcUtil.releaseConnection(con);return result;}@Overridepublic int update(String sql, Object param) throws SQLException {Connection con = JdbcUtil.getConnection();int result = super.update(con, sql, param);JdbcUtil.releaseConnection(con);return result;}@Overridepublic 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.boPooledDataSource;import javax.sql.DataSource;import java.sql.Connection;import java.sql.SQLException;public class JdbcUtil {// 需要配置c3p0-config.xmlprivate 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

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%><%@ taglib uri="/jsp/jstl/core" prefix="c"%><h2>图书列表</h2>分类:<a href="book?method=findAll">全部</a><a href="book?method=findByCategory&category=1">第一类</a><a href="book?method=findByCategory&category=2">第二类</a><table border="1"><tr><th>ID</th><th>书名</th><th>价格</th><th>分类</th></tr><c:forEach items="${bookList}" var="book"><tr><td>${book.bid}</td><td>${book.bname}</td><td>${book.price}</td><td>${book.category}</td></tr></c:forEach></table>

配置文件

pom.xml

<dependency><groupId>jstl</groupId><artifactId>jstl</artifactId><version>1.2</version></dependency><dependency><groupId>taglibs</groupId><artifactId>standard</artifactId><version>1.1.2</version></dependency>

web.xml

<servlet-mapping><servlet-name>BookServlet</servlet-name><url-pattern>/book</url-pattern></servlet-mapping><servlet><servlet-name>BookServlet</servlet-name><servlet-class>com.pengshiyu.servlet.BookServlet</servlet-class></servlet>

c3p0-config.xml

<?xml version="1.0" encoding="utf-8"?><c3p0-config><!-- 这是默认配置信息 --><default-config><!-- 连接四大参数配置 --><property name="driverClass">com.mysql.cj.jdbc.Driver</property><property name="jdbcUrl">jdbc:mysql://localhost:3306/data</property><property name="user">root</property><property name="password">123456</property><!-- 池参数配置 --><property name="acquireIncrement">2</property><property name="initialPoolSize">2</property><property name="minPoolSize">2</property><property name="maxPoolSize">10</property></default-config></c3p0-config>

访问路径

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;@Overridepublic 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*/@Overridepublic 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);}@Overridepublic 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);}@Overridepublic PrintWriter getWriter() throws IOException {// 掉包输出流return this.pw;}}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。