Servlet过滤器
由Servlet容器管理的对象,过滤器的功能是在原数据和目的数据之间起过滤作用的中间组件。
简单实例实现:
过滤器功能:在访问指定资源之前,打印一条日志,访问指定资源之后,打印一条日志
package com.jike.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.annotation.WebFilter;
/**
* Servlet Filter implementation class FilterOne
*/
public class FilterOne implements Filter {
/**
* Default constructor.
*/
public FilterOne() {
System.out.println("=======构造函数==========");
}
/**
* @see Filter#init(FilterConfig)
*/
public void init(FilterConfig fConfig) throws ServletException {
//Servlet启动时执行init方法,
// 这点和Servlet是有区别的
// servlet在第一次被访问是执行init方法,过滤器在容器启动时执行init方法
System.out.println("=======初始化=========");
String initParam = fConfig.getInitParameter("param");
System.out.println("param=" + initParam);
}
/**
* @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain)
*/
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
System.out.println("=======开始doFilter=========");
chain.doFilter(request, response);
System.out.println("=======结束doFilter=========");
}
/**
* @see Filter#destroy()
*/
public void destroy() {
System.out.println("======销毁=========");
}
}
在web.xml中添加:
<filter>
<filter-name>FilterOne</filter-name>
<filter-class>com.jike.filter.FilterOne</filter-class>
<init-param>
<param-name>param</param-name>
<param-value>thystar</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>FilterOne</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
访问:http://localhost:8080/JSPStudy/Hello
过滤器的应用范围:
权限控制
日志记录
图像转换
数据压缩
过滤器链:
过滤器链的执行顺序根据部署描述符中的顺序。
在上个程序的基础上再添加一个FilterTwo,代码相同。配置web.xml ,在控制栏查看运行结果。
使用过滤器进行权限校验:
处理流程:
首先,建立jsp文件:
index为首页,在index.jsp中:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<a href="<%= request.getContextPath() %>/11/Hello.jsp" >Hello.jsp</a>
<% //用于根据当前用户不同的登陆状态显示连接
String flag = "";
Object obj = session.getAttribute("flag");// 获取登陆状态
if(obj != null){
flag = obj.toString();
}
if(flag.equals("login_success")){// 如果登陆
%>
<a href="<%= request.getContextPath()%>/LogoutServlet">退出</a>
<%}else{ // 如果未登录
%>
<a href="<%= request.getContextPath()%>/11/login.jsp">登陆</a>
<%
}
%>
</body>
</html>
在login.jsp中
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<!-- 使用css美化当前页面 -->
<style type="text/css">
body{
color: #000;
font-size: 14px;
margin: 20px auto;
}
</style>
<script type="text/javascript">
function check(form){
if(document.forms.loginForm.uname.value==""){
alert("请输入用户名");
document.forms.loginForm.uname.focus();
return false;
}
if(document.forms.loginForm.upwd.value==""){
alert("请输入密码");
document.forms.loginForm.upwd.focus();
return false;
}
}
</script>
<title>Insert title here</title>
</head>
<body>
<form action="<%= request.getContextPath() %>/LoginServlet11" name="loginForm">
<%if(request.getAttribute("return_uri") != null){ %>
<input type="hidden" name="return_uri" value="<%= request.getAttribute("return_uri") %>">
<%} %>
<table border="1" cellspacing="0" cellpadding="5" bordercolor="silver" align="center">
<tr>
<!-- 提示信息 -->
<td colspan="2" align="center" bgcolor="#E8E8E8">用户登陆</td>
</tr>
<tr>
<td>用户名:</td>
<td><input type="text" name="uname" /></td>
</tr>
<tr>
<td>密码:</td>
<td><input type="password" name="upwd" /></td>
</tr>
<tr>
<td colspan="2" align="center">
<input type="submit" name="submit" onclick="return check(this);"/>
<input type="reset" name="reset"/>
</td>
</tr>
</table>
</form>
</body>
</html>
在Hello.jsp中:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<%!
String str = "Hello world";
%>
<%
out.println(str);
%>
<br/>
<a href="<%= request.getContextPath() %>/11/index.jsp">index.jsp</a>
</body>
</html>
此时,jsp页面设计完成。
接下来,完成登陆和退出Servlet的编写
新建Servlet:
在LoginServlet11中,
package com.jike.servlet;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class LoginServlet11 extends HttpServlet {
public LoginServlet11() {
super();
}
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doPost(request, response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 获取用户提交的表单数据
String uname = request.getParameter("uname");
String passwd = request.getParameter("upwd");
// returnUri用户访问登陆页之前访问的页面,通过这个值,登陆成功后的用户和以重新返回登陆前的页面
String returnUri = request.getParameter("return_uri");
// 输出这三个值
System.out.println("username:" + uname);
System.out.println("password:" + passwd);
System.out.println("return_uri:" + returnUri);
RequestDispatcher rd = null;
// 非空校验
if (uname == null || passwd == null) {
request.setAttribute("msg", "用户名或密码为空");
rd = request.getRequestDispatcher("/11/login.jsp");
rd.forward(request, response);
} else {// 否则执行登陆逻辑
if (uname.equals("star") && passwd.equals("123")) {// 如果登陆成功
// 则在当前用户的session对象中保存一个key为flag,值为login_success的字符串
// 用于表面当前用户处于登陆状态
request.getSession().setAttribute("flag", "login_success");
// 接下来根据returnUri的值进行跳转
if (returnUri != null) {
rd = request.getRequestDispatcher(returnUri);
rd.forward(request, response);
} else {
rd = request.getRequestDispatcher("/11/index.jsp");// 跳转回首页
rd.forward(request, response);
}
} else {// 用户登陆失败
// 在当前用户session对象中保存一个key为flag,值为login_error的字符串
// 用于表面当前用户登陆失败
request.getSession().setAttribute("flag", "login_error");
request.setAttribute("msg", "用户名或密码错误");
rd = request.getRequestDispatcher("/11/login.jsp");
rd.forward(request, response);
}
}
}
}
用于退出的LogoutServlet
package com.jike.servlet;
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 LogoutServlet extends HttpServlet {
public LogoutServlet() {
super();
}
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doPost(request, response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 直接删除session对象,跳转回首页
request.getSession().invalidate();
response.sendRedirect(request.getContextPath() + "/11/index.jsp");
}
}
在web.xml中添加配置:
<servlet>
<description>This is the description of my J2EE component</description>
<display-name>This is the display name of my J2EE component</display-name>
<servlet-name>LoginServlet11</servlet-name>
<servlet-class>com.jike.servlet.LoginServlet11</servlet-class>
</servlet>
<servlet>
<description>This is the description of my J2EE component</description>
<display-name>This is the display name of my J2EE component</display-name>
<servlet-name>LogoutServlet</servlet-name>
<servlet-class>com.jike.servlet.LogoutServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>LoginServlet11</servlet-name>
<url-pattern>/LoginServlet11</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>LogoutServlet</servlet-name>
<url-pattern>/LogoutServlet</url-pattern>
</servlet-mapping>
myeclipse会自动生成这个配置
接下来,添加权限过滤器,只有登陆的客户才能访问Hello.jsp
新建过滤器:
package com.jike.filter;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
public class PermissionFilter implements Filter {
public PermissionFilter() {
// TODO Auto-generated constructor stub
}
public void init(FilterConfig fConfig) throws ServletException {
// TODO Auto-generated method stub
}
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
// 强制类型转换
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse resp = (HttpServletResponse) response;
// 获取请求中的ServletPath
String servletPath = req.getServletPath();
// 获取session对象
HttpSession session = req.getSession();
// 获取session对象的flag的值,强制转换为String类型
String flag = (String) session.getAttribute("flag");
// 如果用户访问的是首页,或login.jsp或者执行登陆操作
if (servletPath != null
&& (servletPath.equals("/11/login.jsp")
|| (servletPath.equals("/11/index.jsp")) || (servletPath
.equals("/LoginServlet11")))) {
chain.doFilter(request, response);// 将请求转发给下一个组件处理
} else {// 对于请求的其他的url都会进行权限校验
// 如果用户处于登陆状态,可以直接访问
if (flag != null && flag.equals("login_success")) {
chain.doFilter(request, response);
} else if (flag != null && flag.equals("login_error")) {// 如果登陆失败
req.setAttribute("msg", "登陆失败, 请重新登陆");
// 把用户访问的url保存到request对象中
req.setAttribute("return_uri", servletPath);
RequestDispatcher rd = req
.getRequestDispatcher("/11/login.jsp");
rd.forward(req, resp);
} else {// 如果没有登陆
req.setAttribute("msg", "尚未登录");
req.setAttribute("return_uri", servletPath);// 保存url
RequestDispatcher rd = req
.getRequestDispatcher("/11/login.jsp");
rd.forward(req, resp);
}
}
}
public void destroy() {
// TODO Auto-generated method stub
}
}
在web.xml中添加配置:
<filter>
<filter-name>PermissionFilter</filter-name>
<filter-class>com.jike.filter.PermissionFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>PermissionFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
访问 :http://localhost:8080/JSPStudy/index.jsp
测试