1. 过滤器
基本概念
为什么需用到过滤器?
项目开发中,经常会涉及到重复代码的实现!
注册 ----à Servlet 【1. 设置编码】 ----à JSP
修改 ----àServlet 【1. 设置编码】 ---à JSP
其他,
如判断用户是否登陆,只有登陆才能有操作权限!
涉及到重复判断: 获取session,取出session数据,判断是否为空,为空说明没有登陆,不能操作; 只有登陆后,才能操作!
如何解决:
1. 抽取重复代码,封装
2. 每个用到重复代码的地方,手动的调用!
过滤器,设计执行流程:
1. 用户访问服务器
2. 过滤器: 对Servlet请求进行拦截
3. 先进入过滤器, 过滤器处理
4. 过滤器处理完后, 在放行, 此时,请求到达Servlet/JSP
5. Servlet处理
6. Servlet处理完后,再回到过滤器, 最后在由tomcat服务器相应用户;
(过滤器就像回家的门!)
过滤器,HelloWorld案例
Javax.servlet.*;
|-- interface Filter 及过滤器
开发步骤:
1. 写一个普通java类,实现Filter接口
package cn.itcast.a_filter_hello;
import java.io.IOException;
import java.util.Enumeration;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
/**
* 过滤器,测试
* @author Jie.Yuan
*
*/
public class HelloFilter implements Filter{
// 创建实例
public HelloFilter(){
System.out.println("1. 创建过滤器实例");
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
// 过滤器业务处理方法: 在请求到达servlet之前先进入此方法处理公用的业务逻辑操作
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
System.out.println("3. 执行过滤器业务处理方法");
// 放行 (去到Servlet)
// 如果有下一个过滤器,进入下一个过滤器,否则就执行访问servlet
chain.doFilter(request, response);
System.out.println("5. Servlet处理完成,又回到过滤器");
}
@Override
public void destroy() {
System.out.println("6. 销毁过滤器实例");
}
}
2. Web.xml中配置过滤器
<!-过滤器配置 ->
<filter>
<filter-name>hello_filter</filter-name>
<filter-class>cn.itcast.a_filter_hello.HelloFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>hello_filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
过滤器执行流程
OOAD 面向对象的分析与设计
使用RationRose 时序图
过滤器相关Api
1)|-- interface Filter过滤器核心接口
Void init(filterConfig); 初始化方法,在服务器启动时候执行
Void doFilter(request,response,filterChain); 过滤器拦截的业务处理方法
Void destroy(); 销毁过滤器实例时候调用
2)|-- interface FilterConfig 获取初始化参数信息
String | getInitParameter(java.lang.String name) |
Enumeration |
需要在web.xml文件中添加:
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>path</param-name>
<param-value>c:/...</param-value>
</init-param>
添加后变成了:
<filter>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>path</param-name>
<param-value>c:/...</param-value>
</init-param>
<filter-name>hello_filter</filter-name>
<filter-class>cn.itcast.a_filter_hello.HelloFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>hello_filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
然后在HelloFilter类中的init方法中就可以获取相应的参数了
package cn.itcast.a_filter_hello;
import java.io.IOException;
import java.util.Enumeration;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
/**
* 过滤器,测试
* @author Jie.Yuan
*
*/
public class HelloFilter implements Filter{
// 创建实例
public HelloFilter(){
System.out.println("1. 创建过滤器实例");
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("2. 执行过滤器初始化方法");
// 获取过滤器在web.xml中配置的初始化参数
String encoding = filterConfig.getInitParameter("encoding");
System.out.println(encoding);
// 获取过滤器在web.xml中配置的初始化参数 的名称
Enumeration<String> enums = filterConfig.getInitParameterNames();
while (enums.hasMoreElements()){
// 获取所有参数名称:encoding、path
String name = enums.nextElement();
// 获取名称对应的值
String value = filterConfig.getInitParameter(name);
System.out.println(name + "\t" + value);
}
}
// 过滤器业务处理方法: 在请求到达servlet之前先进入此方法处理公用的业务逻辑操作
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
System.out.println("3. 执行过滤器业务处理方法");
// 放行 (去到Servlet)
// 如果有下一个过滤器,进入下一个过滤器,否则就执行访问servlet
chain.doFilter(request, response);
System.out.println("5. Servlet处理完成,又回到过滤器");
}
@Override
public void destroy() {
System.out.println("6. 销毁过滤器实例");
}
}
3)|-- interface FilterChain 过滤器链参数;一个个过滤器形成一个执行链;
void doFilter(ServletRequest request, ServletResponse response) ; 执行下一个过滤器或放行
对指定的请求拦截
web.xml文件里说明:
<!-- 配置第二个过滤器 -->
<!-- 演示: 拦截指定的请求 -->
<filter>
<filter-name>hello_filter2</filter-name>
<filter-class>cn.itcast.a_filter_hello.HelloFilter2</filter-class>
</filter>
<filter-mapping>
<filter-name>hello_filter2</filter-name>
<!-- 1. 拦截所有
<url-pattern>/*</url-pattern>
-->
<!-- 2. 拦截指定的jsp
<url-pattern>/index.jsp</url-pattern>
<url-pattern>/list.jsp</url-pattern>
-->
<!-- 拦截所有的jsp
<url-pattern>*.jsp</url-pattern>
-->
<!-- 3. 根据servlet的内部名称拦截
<servlet-name>IndexServlet</servlet-name>
-->
<!-- 拦截指定的servlet
<url-pattern>/index</url-pattern>
-->
<!-- 4. 指定拦截指定的类型
默认拦截的类型:(直接访问或者重定向)
<dispatcher>REQUEST</dispatcher>
拦截转发:
<dispatcher>FORWARD</dispatcher>
拦截包含的页面(RequestDispatcher.include(/page.jsp); 对page.jsp也执行拦截)
<dispatcher>INCLUDE</dispatcher>
拦截声明式异常信息:
<dispatcher>ERROR</dispatcher>
-->
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
共性问题:
1. 过滤器:方法参数没有自动命名,说明没有关联源码
--à 关联tomcat或servlet源代码
2. 连接池: 多刷新几次,报错!
-à 连接没关
QueryRunner qr = new QueryRunner();
qr.update(con,sql);
// 这里con一定要关闭
-à 注意:dataSource 确定一个项目创建一次
QueryRunner qr = new QueryRunner(dataSource);
à 修改连接池参数配置
3 . 编码
// 设置POST提交的请求的编码
request.setCharacterEncoding("UTF-8");
// 设置相应体的编码
response.setCharacterEncoding("UTF-8");
// 设置页面打开时候时候的编码格式、 设置相应体的编码
response.setContentType("text/html;charset=UTF-8");
开发中:
工作区间编码、项目编码、request/response、数据库编码一致!
2.案例
a)案例一:过滤器-编码统一处理
几乎每一个Servlet都要涉及编码处理:处理请求数据中文问题!
【GET/POST】
每个servlet都要做这些操作,把公用的代码抽取-过滤器实现!
代码实现思路:
1. Login.jsp 登陆,输入“中文”
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>My JSP 'index.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
</head>
<body>
<form name="frmLogin" action="${pageContext.request.contextPath }/login" method="post">
用户名: <input type="text" name="userName"><br/>
<input type="submit" value="POST提交" >
</form>
<hr/>
<form name="frmLogin" action="${pageContext.request.contextPath }/login" method="get">
用户名: <input type="text" name="userName"><br/>
<input type="submit" value="GET提交" >
</form>
</body>
</html>
2. LoginServlet.java 直接处理登陆请求
package cn.itcast.a_loginFilter;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class LoginServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 获取请求数据
String name = request.getParameter("userName");
System.out.println("用户:" + name);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
this.doGet(request, response);
}
}
3. EncodingFilter.java 过滤器处理请求数据编码:GET/POST
package cn.itcast.a_loginFilter;
import java.io.IOException;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 编码处理统一写到这里(servlet中不需要再处理编码)
* @author Jie.Yuan
*
*/
public class EncodingFilter implements Filter {
// 过滤器业务处理方法:处理的公用的业务逻辑操作
@Override
public void doFilter(ServletRequest req, ServletResponse res,
FilterChain chain) throws IOException, ServletException {
// 转型
final HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
// 一、处理公用业务
request.setCharacterEncoding("UTF-8"); // POST提交有效
response.setContentType("text/html;charset=UTF-8");
/*
* 出现GET中文乱码,是因为在request.getParameter方法内部没有进行提交方式判断并处理。
* String name = request.getParameter("userName");
*
* 解决:对指定接口的某一个方法进行功能扩展,可以使用代理!
* 对request对象(目标对象),创建代理对象!
*/
HttpServletRequest proxy = (HttpServletRequest) Proxy.newProxyInstance(
request.getClass().getClassLoader(), // 指定当前使用的累加载器
new Class[]{HttpServletRequest.class}, // 对目标对象实现的接口类型
new InvocationHandler() { // 事件处理器
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
// 定义方法返回值
Object returnValue = null;
// 获取方法名
String methodName = method.getName();
// 判断:对getParameter方法进行GET提交中文处理
if ("getParameter".equals(methodName)) {
// 获取请求数据值【 <input type="text" name="userName">】
String value = request.getParameter(args[0].toString()); // 调用目标对象的方法
// 获取提交方式
String methodSubmit = request.getMethod(); // 直接调用目标对象的方法
// 判断如果是GET提交,需要对数据进行处理 (POST提交已经处理过了)
if ("GET".equals(methodSubmit)) {
if (value != null && !"".equals(value.trim())){
// 处理GET中文
value = new String(value.getBytes("ISO8859-1"),"UTF-8");
}
}
return value;
}
else {
// 执行request对象的其他方法
returnValue = method.invoke(request, args);
}
return returnValue;
}
});
// 二、放行 (执行下一个过滤器或者servlet)
chain.doFilter(proxy, response); // 传入代理对象
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void destroy() {
}
}
4.web.xml
<filter>
<filter-name>encoding</filter-name>
<filter-class>cn.itcast.a_loginFilter.EncodingFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>encoding</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
b)案例二:过滤器-无效数据过滤
模拟:论坛过滤敏感词汇!
实现思路:
1. Dis.jsp 讨论区页面(JSP引入ckeditor组件:客户端组件,便于用户输入内容!)
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>My JSP 'index.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<!-- 引入ckeditor组件(给用户输入提供方便) -->
<script src="${pageContext.request.contextPath }/ckeditor/ckeditor.js"></script>
<link rel="stylesheet" href="${pageContext.request.contextPath }/ckeditor/samples/sample.css">
</head>
<body>
${requestScope.content }
<form name="frmDis" action="${pageContext.request.contextPath }/dis" method="post">
发表评论: <textarea class="ckeditor" rows="6" cols="30" name="content"></textarea>
<br/>
<input type="submit" value="评论" >
</form>
</body>
</html>
2. DisServlet.java 处理提交
---》 获取请求参数
---》 保存到request域
-----》 跳转dis.jsp 【从request取数据显示(处理后)】
package cn.itcast.b_filter_data;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class DisServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 获取请求数据
String content = request.getParameter("content");
// 保存到request
request.setAttribute("content", "Content:" + content);
// 转发
request.getRequestDispatcher("/dis.jsp").forward(request, response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
this.doGet(request, response);
}
}
3. DataFilter.java 过滤器
----》编码
---》 无效数据处理
即: 在上一个案例基础上,再添加无效数据过滤的相关代码!
package cn.itcast.b_filter_data;
import java.io.IOException;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 无效数据过滤
* @author Jie.Yuan
*
*/
public class DateFilter implements Filter {
// 初始化无效数据
private List<String> dirtyData;
@Override
public void init(FilterConfig filterConfig) throws ServletException {
// 模拟几个数据
dirtyData = new ArrayList<String>();
dirtyData.add("NND");
dirtyData.add("炸使馆");
}
@Override
public void doFilter(ServletRequest req, ServletResponse res,
FilterChain chain) throws IOException, ServletException {
// 转型
final HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
// 一、处理公用业务
request.setCharacterEncoding("UTF-8"); // POST提交有效
response.setContentType("text/html;charset=UTF-8");
HttpServletRequest proxy = (HttpServletRequest) Proxy.newProxyInstance(
request.getClass().getClassLoader(), // 指定当前使用的累加载器
new Class[]{HttpServletRequest.class}, // 对目标对象实现的接口类型
new InvocationHandler() { // 事件处理器
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
// 定义方法返回值
Object returnValue = null;
// 获取方法名
String methodName = method.getName();
// 判断:对getParameter方法进行GET提交中文处理
if ("getParameter".equals(methodName)) {
// 获取请求数据值【 <input type="text" name="userName">】
String value = request.getParameter(args[0].toString()); // 调用目标对象的方法
// 获取提交方式
String methodSubmit = request.getMethod(); // 直接调用目标对象的方法
// 判断如果是GET提交,需要对数据进行处理 (POST提交已经处理过了)
if ("GET".equals(methodSubmit)) {
if (value != null && !"".equals(value.trim())){
// 处理GET中文
value = new String(value.getBytes("ISO8859-1"),"UTF-8");
}
}
// 中文数据已经处理完: 下面进行无效数据过滤
//【如何value中出现dirtyData中数据,用****替换】
for (String data : dirtyData) {
// 判断当前输入数据(value), 是否包含无效数据
if (value.contains(data)){
value = value.replace(data, "*****");
}
}
// 处理完编码、无效数据后的正确数据
return value;
}
else {
// 执行request对象的其他方法
returnValue = method.invoke(request, args);
}
return returnValue;
}
});
// 二、放行 (执行下一个过滤器或者servlet)
chain.doFilter(proxy, response); // 传入代理对象
}
@Override
public void destroy() {
}
}
4.web.xml
<!-- 2. 无效数据过滤器配置 -->
<filter>
<filter-name>dataFilter</filter-name>
<filter-class>cn.itcast.b_filter_data.DateFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>dataFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
c)案例三:登陆权限判断
登陆, 提交到登陆Servlet处理其业务!
-à登陆成功, 跳转到首页,显示欢迎信息 + 列表信息
-à登陆失败,跳转到登陆!
要求:
只有登陆后,才可以访问首页, 显示列表
如果没有登陆,直接访问首页列表,要跳转到登陆!
实现步骤:
1. 建库、建表、建项目、引入jar文件
2. entity
a) Admin.java
b) Employee.java
3. Dao
a) AdminDao
b) EmployeeDao
4. Servcie
5. Servlet
6. Jsp
实现思路:
1. Login.jsp 登陆页面
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>My JSP 'index.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
</head>
<body>
<form name="frmLogin" action="${pageContext.request.contextPath }/login" method="post">
<table align="center" border="1">
<tr>
<td>用户名</td>
<td>
<input type="text" name="userName">
</td>
</tr>
<tr>
<td>密码</td>
<td>
<input type="password" name="pwd">
</td>
</tr>
<tr>
<td>
<input type="submit" value="亲,点我登陆!">
</td>
</tr>
</table>
</form>
</body>
</html>
2. List.jsp 列表显示
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!-- 引入jstl核心标签库 -->
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>My JSP 'index.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
</head>
<body>
<h1>欢迎你,${sessionScope.loginInfo.userName }</h1>
<!-- 列表展示数据 -->
<table align="center" border="1" width="80%" cellpadding="3" cellspacing="0">
<tr>
<td>序号</td>
<td>编号</td>
<td>员工名称</td>
</tr>
<c:if test="${not empty requestScope.listEmp}">
<c:forEach var="emp" items="${requestScope.listEmp}" varStatus="vs">
<tr>
<td>${vs.count }</td>
<td>${emp.empId }</td>
<td>${emp.empName }</td>
</tr>
</c:forEach>
</c:if>
</table>
</body>
</html>
3. LoginServlet.java 登陆处理servlet
package cn.itcast.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import cn.itcast.entity.Admin;
import cn.itcast.service.IAdminService;
import cn.itcast.service.impl.AdminService;
/**
* 处理登陆请求
* @author Jie.Yuan
*
*/
public class LoginServlet extends HttpServlet {
// Service实例
private IAdminService adminService = new AdminService();
// 跳转资源
private String uri;
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
//1. 获取参数
String userName = request.getParameter("userName");
String pwd = request.getParameter("pwd");
// 封装
Admin admin = new Admin();
admin.setUserName(userName);
admin.setPwd(pwd);
try {
//2. 调用service处理业务
Admin loginInfo = adminService.findByNameAndPwd(admin);
// 判断:
if (loginInfo == null){
// 登陆失败
uri = "/login.jsp";
} else {
// 登陆成功
// 先,保存数据到session
request.getSession().setAttribute("loginInfo", loginInfo);
// 再,跳转到首页显示servlet(/index)
uri = "/index";
}
} catch (Exception e) {
// 测试
e.printStackTrace();
// 错误
uri = "/error/error.jsp";
}
//3. 跳转
request.getRequestDispatcher(uri).forward(request, response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
this.doGet(request, response);
}
}
4. IndexServlet.java 首页列表查询Servlet
package cn.itcast.servlet;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import cn.itcast.entity.Admin;
import cn.itcast.entity.Employee;
import cn.itcast.service.IAdminService;
import cn.itcast.service.IEmployeeService;
import cn.itcast.service.impl.AdminService;
import cn.itcast.service.impl.EmployeeService;
public class IndexServlet extends HttpServlet {
// Service实例
private IEmployeeService employeeService = new EmployeeService();
// 跳转资源
private String uri;
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
try {
// 调用service查询所有
List<Employee> list = employeeService.getAll();
request.setAttribute("listEmp", list);
// 进入首页jsp
uri = "/list.jsp";
} catch (Exception e) {
e.printStackTrace();
uri = "/error/error.jsp";
}
// 转发
request.getRequestDispatcher(uri).forward(request, response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
this.doGet(request, response);
}
}
5. LoginFilter.java 登陆验证过滤器
package cn.itcast.filter;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
/**
* 登陆验证过滤器
*
* http://localhost:8080/emp_sys/login.jsp 可以直接访问
http://localhost:8080/emp_sys/login 可以直接访问
http://localhost:8080/emp_sys/index 不能直接访问
http://localhost:8080/emp_sys/list.jsp 不能直接访问
* @author Jie.Yuan
*
*/
public class LoginFilter implements Filter {
private String uri;
/**
* 分析:
*
1. 先指定放行的资源,哪些资源不需要拦截:
login.jsp + /login (request对象可以获取)
2. 获取session,从session中获取登陆用户
3. 判断是否为空:
为空, 说明没有登陆, 跳转到登陆
不为空, 已经登陆,放行!
*/
@Override
public void doFilter(ServletRequest req, ServletResponse res,
FilterChain chain) throws IOException, ServletException {
//0. 转换
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
//1. 获取请求资源,截取
String uri = request.getRequestURI(); // /emp_sys/login.jsp
// 截取 【login.jsp或login】
String requestPath = uri.substring(uri.lastIndexOf("/") + 1, uri.length());
//2. 判断: 先放行一些资源:/login.jsp、/login
if ("login".equals(requestPath) || "login.jsp".equals(requestPath)) {
// 放行
chain.doFilter(request, response);
}
else {
//3. 对其他资源进行拦截
//3.1 先获取Session、获取session中的登陆用户(loginInfo)
HttpSession session = request.getSession(false);
// 判断
if (session != null) {
Object obj = session.getAttribute("loginInfo");
//3.2如果获取的内容不为空,说明已经登陆,放行
if (obj != null) {
// 放行
chain.doFilter(request, response);
} else {
//3.3如果获取的内容为空,说明没有登陆; 跳转到登陆
uri = "/login.jsp";
}
} else {
// 肯定没有登陆
uri = "/login.jsp";
}
request.getRequestDispatcher(uri).forward(request, response);
}
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void destroy() {
}
}
6.web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<!-- 登陆验证过滤器 -->
<filter>
<filter-name>loginFilter</filter-name>
<filter-class>cn.itcast.filter.LoginFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>loginFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>LoginServlet</servlet-name>
<servlet-class>cn.itcast.servlet.LoginServlet</servlet-class>
</servlet>
<servlet>
<servlet-name>IndexServlet</servlet-name>
<servlet-class>cn.itcast.servlet.IndexServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>LoginServlet</servlet-name>
<url-pattern>/login</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>IndexServlet</servlet-name>
<url-pattern>/index</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>