JavaWeb过滤器案例
- 案例分析
- JSP的编写
- Servlet的编写
- Filter的编写
- 演示截图
- 分析与总结
案例分析
粗粒度权限控制(拦截是否登录、拦截用户名admin权限)
说明:给出三个页面:welcom.jsp(没有限制)、user.jsp(只有登录用户才能访问)、admin.jsp(只有管理员才能访问)。
分析:
首先需要一个登录页面(login.jsp)用于传递登录的用户名和密码。
然后创建一个Servlet,当用户登录成功后,进行判断权限级别,并把用户名保存到session域中。
最后创建LoginFilter,两种过滤方式:UserFilter、AdminFilter。
JSP的编写
创建四个JSP文件,分别为:welcom.jsp、login.jsp、user文件夹下的user.jsp以及admin文件夹下的admin.jsp。
welcom.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>Welcome</title>
</head>
<body>
<h1>游客界面</h1>
当前用户:<%=session.getAttribute("username")%><br/>
<a href="<c:url value="/welcom.jsp"/>">游客入口</a><br>
<a href="<c:url value="/user/user.jsp"/>">用户入口</a><br>
<a href="<c:url value="/admin/admin.jsp"/>">管理员入口</a><br>
</body>
</html>
login.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>Login</title>
</head>
<body>
<h1>登录</h1>
<font color="red"> ${msg} </font><br/>
当前用户:<%=session.getAttribute("username")%><br/>
<form action="<c:url value="/Login"/>" method="post">
<table>
<tr>
<td>用户名:</td>
<td><input type="text" name="username"/></td>
</tr>
<tr>
<td>密码:</td>
<td><input type="password" name="password"/></td>
</tr>
<tr>
<td colspan="2"><input type="submit" value="登录"/></td>
</tr>
</table>
</form>
</body>
</html>
user.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>Welcome</title>
</head>
<body>
<h1>用户界面</h1>
当前用户:<%=session.getAttribute("username")%><br/>
<a href="<c:url value="/welcom.jsp"/>">游客入口</a><br>
<a href="<c:url value="/user/user.jsp"/>">用户入口</a><br>
<a href="<c:url value="/admin/admin.jsp"/>">管理员入口</a><br>
</body>
</html>
admin.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>Welcome</title>
</head>
<body>
<h1>管理员界面</h1>
<%
String name= (String) session.getAttribute("admin");
session.setAttribute("username",name);
%>
当前用户:<%=session.getAttribute("username")%><br/>
<a href="<c:url value="/welcom.jsp"/>">游客入口</a><br>
<a href="<c:url value="/user/user.jsp"/>">用户入口</a><br>
<a href="<c:url value="/admin/admin.jsp"/>">管理员入口</a><br>
</body>
</html>
Servlet的编写
写完JSP后,输入与输出数据的页面已经有了,接下来就是创建LoginServlet,用于处理请求。
LoginServlet
@WebServlet(name = "LoginServlet")
public class LoginServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("UTF-8"); //处理中文问题
/*1.获取用户名,获取密码
* 2.判断用户名中和密码是否为“”,
* 3.如果不为空,且包含特定字符,就是管理员
* 4.如果不包含,就是普通用户
* 5.否则就是游客
* 6.把登录的用户名称保存到session中
* 7.转发到welcome.jsp*/
String name=request.getParameter("username");
String password=request.getParameter("password");
if (name!="" && password!=""){
if (name.contains("chen") && password.equals("123456")){
request.getSession().setAttribute("admin",name);
//name是login.jsp中提交的值,一个键值对:username:chen
//setAttribute,创建一个新的session域对象,名称为andmin,值为name的值
}else {
request.getSession().setAttribute("username",name);
}
}else {
request.getSession().setAttribute("tourist",name);
}
request.getRequestDispatcher("/UserDemo/welcom.jsp").forward(request,response);
System.out.println("已经转发");
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
}
因为在login.jsp中,我们已经定义了页面跳转的方向,所以这里我们手动进行JavaWeb项目的web.xml配置。
web.xml
<servlet>
<servlet-name>Login</servlet-name>
<servlet-class>servlet.LoginServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Login</servlet-name>
<url-pattern>/Login</url-pattern>
</servlet-mapping>
至此,Servlet与JSP完成,此时访问页面,可以在三个页面中畅通无阻。而为了实现我们的粗粒度权限管理,我们还需要编写两个过滤器,以达到权限管理的目的。
Filter的编写
UserFilter
public class UserFilter implements Filter {
public void destroy() {
}
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
/*1.得到session
* 2.判断session域中是否存在admin,如果存在放行
* 3.判断session域中是否存在username,如果存在放行
* 4.否则打回login.jsp*/
HttpServletRequest request= (HttpServletRequest) req; //强转,用它才能使用getSession()方法
String name = (String) request.getSession().getAttribute("admin");
if (name!=null){
/*获取admin,如果不为空,就是管理员*/
chain.doFilter(req, resp);
return;
}
name=(String)request.getSession().getAttribute("username"); //获取用户
if (name!=null){
chain.doFilter(req,resp);
}else {
request.setAttribute("msg","游客请登录"); //保存错误信息到request域中,再转发
request.getRequestDispatcher("/UserDemo/login.jsp").forward(req,resp);
System.out.println("UserFilter拦截");
}
}
public void init(FilterConfig config) throws ServletException {
}
}
AdminFilter
public class AdminFilter implements Filter {
public void destroy() {
}
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
HttpServletRequest request= (HttpServletRequest) req;
String name= (String) request.getSession().getAttribute("admin");
if (name!=null){
/*获取admin,如果不为空,就是管理员*/
chain.doFilter(req, resp);
return;
}else {
request.setAttribute("msg","没有管理员权限"); //保存错误信息到request域中,再转发
request.getRequestDispatcher("/UserDemo/login.jsp").forward(req,resp);
System.out.println("AdminFilter拦截");
}
}
public void init(FilterConfig config) throws ServletException {
}
}
同样的,在web.xml中进行Filter的配置。
web.xml
<filter>
<filter-name>UserFilter</filter-name>
<filter-class>filter.UserFilter</filter-class>
</filter>
<filter>
<filter-name>AdminFilter</filter-name>
<filter-class>filter.AdminFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>UserFilter</filter-name>
<url-pattern>/UserDemo/user/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>AdminFilter</filter-name>
<url-pattern>/UserDemo/admin/*</url-pattern>
</filter-mapping>
关于Filter的filter-mapping标签,引入一个知识点:
多个过滤器拦截同一个目标资源,过滤器的执行顺序是由web.xml文件中的 filter-mapping标签的部署顺序决定的。
一定要注意的是,那个Filter的执行顺序和Filter在web.xml文件中的位置先后无关,只和mapping的顺序有关,谁的mapping在前,就先执行谁,然后执行的顺序是,接着执行下一个Filter,直到所有的过滤器执行结束,然后才是访问目标资源。
演示截图
分析与总结
login.jsp提交信息到LoginServlet。
LoginServlet判断提交信息中是否包含指定数据,如果包含管理员数据则在session域中创建名为admin的数据,并将提交信息中的username的值作为新值传递给admin;若满足用户判读条件,则仿照上面的创建一个名为username的键值对。最后将其转发到welcom.jsp。
welcom.jsp中定义三个超链接,指向welcom.jsp和user文件夹下的user.jsp以及admin文件夹下的admin.jsp。
在welcom.jsp中,UserFilter和AdminFilter的作用就显示出来了。
UserFilter和AdminFilter通过session域中是否存在username和admin的数据,判断是否放行。