案例目标
情景:系统中的某些页面只有在正常登陆后在可以访问,用户请求这些页面是,需要先检查Session中有无该用户的信息,但是在 所有必要的页面上加上对session的判断相当麻烦,因此利用filter实现对资源权限的统一管理
方案:编写一个检测使用户是否登录的过滤器,若未登录,则重定向到登录界面
要求:1.session中的键保存在配置文件中
2.如果用户未登录,则重定向到指定界面
3.未登录用户也可以访问的url列表已配置文件的方式保存
新建抽象类HttpFilter继承Filter类
package com.nupt.javaweb.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;
public abstract class HttpFilter implements Filter {
private FilterConfig filterConfig;
@Override
public void init(FilterConfig filterConfig) throws ServletException {
// TODO Auto-generated method stub
this.filterConfig = filterConfig;
init();
}
//Using the function to init Filter
protected void init() {}
public FilterConfig getFilterConfig() {
return this.filterConfig;
}
@Override
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)
throws IOException, ServletException {
// TODO Auto-generated method stub
HttpServletRequest request = (HttpServletRequest)req;
HttpServletResponse response = (HttpServletResponse)resp;
doFilter( request ,response,chain);
}
public abstract void doFilter(HttpServletRequest request,HttpServletResponse response,FilterChain chain) throws IOException, ServletException;
@Override
public void destroy() {
// TODO Auto-generated method stub
}
}
新建a.jsp,b.jsp,c.jsp,d.jsp,e.jsp,list.jsp作为要访问的资源
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h4>AAA</h4>
<br/>
<a href="<%= request.getContextPath() %>/login/list.jsp">Return......</a>
</body>
</html>
list.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<a href="<%= request.getContextPath()%>/login/a.jsp">AAA</a>
<br/>
<a href="<%= request.getContextPath()%>/login/b.jsp">BBB</a>
<br/>
<a href="<%= request.getContextPath()%>/login/c.jsp">CCC</a>
<br/>
<a href="<%= request.getContextPath()%>/login/d.jsp">DDD</a>
<br/>
<a href="<%= request.getContextPath()%>/login/e.jsp">EEE</a>
</body>
</html>
新建login.jsp与doLogin.jsp分别用于用户登录,与中间件servlet
login.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<form action="doLogin.jsp" method="post">
用户名:<input type="text" name="username"/>
<br/>
<input type="submit" value="登录" />
</form>
</body>
</html>
doLogin.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
String userSessionKey = application.getInitParameter("userSessionKey");
String username = request.getParameter("username");
if( username != null && !username.trim().equals("")){
session.setAttribute(userSessionKey, username);
response.sendRedirect(request.getContextPath()+"/login/list.jsp");
}
%>
</body>
修改配置文件web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
id="WebApp_ID" version="3.0">
<!-- 用户信息放入到Session中的键的名字 -->
<context-param>
<param-name>userSessionKey</param-name>
<param-value>USERSESSIONKEY</param-value>
</context-param>
<!-- 若未登录需要重定向的页面 -->
<context-param>
<param-name>redirectPage</param-name>
<param-value>/login/login.jsp</param-value>
</context-param>
<!-- 不需要检查或者拦截的URL列表 -->
<context-param>
<param-name>unCheckedUrls</param-name>
<param-value>/login/a.jsp,/login/list.jsp,/login/login.jsp,/login/doLogin.jsp</param-value>
</context-param>
<filter>
<filter-name>loginFilter</filter-name>
<filter-class>com.nupt.javaweb.login.LoginFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>loginFilter</filter-name>
<url-pattern>/login/*</url-pattern>
</filter-mapping>
</web-app>
新建LoginFilter类实现HttpFilter类
package com.nupt.javaweb.login;
import java.io.IOException;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import com.nupt.javaweb.filter.HttpFilter;
public class LoginFilter extends HttpFilter {
FilterConfig filterConfig;
ServletContext servletContext;
String userSessionKey;
String redirectPage;
String unCheckedUrls;
protected void init() {
// 获取用户信息放入到Session中的键值
filterConfig = this.getFilterConfig();
servletContext = filterConfig.getServletContext();
userSessionKey = servletContext.getInitParameter("userSessionKey");
// 获取若用户未登录重定向的页面
redirectPage = servletContext.getInitParameter("redirectPage");
// 获取无需拦截的url资源
unCheckedUrls = servletContext.getInitParameter("unCheckedUrls");
}
@Override
public void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
// TODO Auto-generated method stub
System.out.println("Hello Filter");
// 1.获取servletpath
String servletPath = request.getServletPath();
// 2判断用户请求的资源是否可以不用登陆就可以访问
if( this.unCheckedUrls.contains(servletPath)) {
//System.out.println("servletPath.contains(unCheckedUrls)==true");
chain.doFilter(request, response);
return;
}else{
// 判断HttpSession对象中有没有用户登录的属性信息
HttpSession httpSession = request.getSession();
String username = (String) httpSession.getAttribute(this.userSessionKey);
if( username != null ) {
chain.doFilter(request, response);
return;
}else
try {
response.sendRedirect(request.getContextPath()+this.redirectPage);
return;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}