拦截效果
非法请求拦截(Ajax形式和正常跳转形式)
功能
- 拦截非登陆用户的请求操作
- 拦截非登陆用户的Ajax操作
正文
(非Ajax)我们将
未登录状态
下的请求都视为非法访问
。那我们是如何知道一个用户是否登录呢?
这里是将登录成功之后的用户信息存入session
域中,Key为user
。我们的Filter过滤器,通过requerst
对象获取session
域中的user
,如果不为 NULL就doFilter
放行。否则就请求转发到登录页面
LoginCheckFilter
package com.filter;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.IOException;
public class LoginCheckFilter implements Filter {
private String excludedPages;
private String[] excludedPageArray;
@Override
public void init(FilterConfig config) throws ServletException {
excludedPages = config.getInitParameter("excludedPages");
if (null != excludedPages && excludedPages.length() > 0) {
excludedPageArray = excludedPages.split(",");
}
return;
}
@Override
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
boolean isExcludedPage = false;
HttpSession session = ((HttpServletRequest) req).getSession();
Object user = session.getAttribute("user");
// 获取不过滤的列表
for (String page : excludedPageArray) {
if (((HttpServletRequest) req).getServletPath().equals(page)) {
isExcludedPage = true;
break;
}
}
if (isExcludedPage) { //如果有不过滤的页面,放行
chain.doFilter(req, resp);
} else {
if (user != null){
chain.doFilter(req,resp);
}else {
((HttpServletRequest)req).getRequestDispatcher("/login.jsp").forward(req,resp);
}
}
}
@Override
public void destroy() {
}
}
AjaxIllegalReqFilter
(Ajax)有关处理
Ajax请求
的非法操作,在此之前我们需要判断请求是否为Ajax
请求。这个思路就是:Ajax请求
都会携带一个标识Ajax
的请求头信息,我们借此来判断是否为Ajax请求
。
关键代码:
if (((HttpServletRequest) req).getHeader("x-requested-with")!=null && ((HttpServletRequest) req).getHeader("x-requested-with").equals("XMLHttpRequest")){
isAjaxRequest = true;
}
判断用户是否登录这一步是和
非Ajax
一样的。唯一不同的是,如果用户没有登录,这里采用的不是请求转发到登录页面
,因为Ajax请求
无法进行页面的请求转发
。我们这里采用的是通过后端返回json
字符串,前端进行页面的跳转。
相关代码:
// 拦截未登录用户添加购物车
if ("AjaxError" == data){
window.location.href="/MyProject/login.jsp";
}
package com.filter;
import com.google.gson.Gson;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
public class AjaxIllegalReqFilter implements Filter {
private String excludedPages;
private String[] excludedPageArray;
@Override
public void init(FilterConfig config) throws ServletException {
excludedPages = config.getInitParameter("excludedPages");
if (null != excludedPages && excludedPages.length() > 0) {
excludedPageArray = excludedPages.split(",");
}
return;
}
@Override
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
boolean isExcludedPage = false;
HttpServletRequest request = ((HttpServletRequest)req);
HttpServletResponse response = ((HttpServletResponse)resp);
boolean isAjaxRequest = false;
// 获取不过滤的列表
for (String page : excludedPageArray) {
if (((HttpServletRequest) req).getServletPath().equals(page)) {
isExcludedPage = true;
break;
}
}
if (isExcludedPage) { //如果有不需要过滤的页面,放行
chain.doFilter(req, resp);
} else {
// Ajax请求非法登录处理
if (((HttpServletRequest) req).getHeader("x-requested-with")!=null && ((HttpServletRequest) req).getHeader("x-requested-with").equals("XMLHttpRequest")){
isAjaxRequest = true;
}
// 如果是Ajxa请求
HttpSession session = request.getSession();
Object user = session.getAttribute("user");
if (isAjaxRequest && user==null){
response.getWriter().write(new Gson().toJson("AjaxError"));
return;
}else {
chain.doFilter(req, resp);
}
}
}
@Override
public void destroy() {
}
}
web.XMl
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<!--非法访问过滤器-->
<filter>
<filter-name>filter.LoginCheckFilter</filter-name>
<filter-class>com.filter.LoginCheckFilter</filter-class>
<!--过滤排除-->
<init-param>
<param-name>excludedPages</param-name>
<param-value>/simpleImg,/index.jsp,/login.jsp,/login_new.jsp</param-value><!-- 匹配不做拦截的请求声明-->
</init-param>
</filter>
<filter-mapping>
<filter-name>filter.LoginCheckFilter</filter-name>
<url-pattern>*.jsp</url-pattern>
</filter-mapping>
<!--Ajax过滤器-->
<filter>
<filter-name>AjaxIllegalReqFilter</filter-name>
<filter-class>com.filter.AjaxIllegalReqFilter</filter-class>
<!--过滤排除-->
<init-param>
<param-name>excludedPages</param-name>
<param-value>/checkSecurityCode,/orderProcessServlet,/userProcessServlet</param-value><!-- 匹配不做拦截的请求声明-->
</init-param>
</filter>
<filter-mapping>
<filter-name>AjaxIllegalReqFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</servlet-mapping>
过滤页面的排除(指定URL的排除)
到这里我们会发现,两个过滤器的url-pattern
都是/*
,即:拦截所有的Ajax请求
和非Ajax请求
。所以这里我们需要对有些页面,进行过滤排除(对有些页面不进行过滤)。
思路:
- 我们在过滤器里边定义两个属性
private String excludedPages; // 存储读取到的排除页面URI
private String[] excludedPageArray; // 存储需要排除页面的URI集合
- 利用
init()
方法来读取web.xml
配置文件的相关参数。将需要排除的URI都存进excludedPageArray数组
。
@Override
public void init(FilterConfig config) throws ServletException {
excludedPages = config.getInitParameter("excludedPages");
if (null != excludedPages && excludedPages.length() > 0) {
excludedPageArray = excludedPages.split(",");
}
return;
}
- 对需要排除的页面/请求进行放行。
@Override
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
boolean isExcludedPage = false;
HttpSession session = ((HttpServletRequest) req).getSession();
Object user = session.getAttribute("user");
// 获取不过滤的列表
for (String page : excludedPageArray) {
if (((HttpServletRequest) req).getServletPath().equals(page)) {
isExcludedPage = true;
break;
}
}
if (isExcludedPage) { //如果有不过滤的页面,放行
chain.doFilter(req, resp);
} else {
// 需要处理的业务逻辑代码
}
}
- 放行参数的设置
在
web.xml
文件配置Filter
的初始化参数中设置需要放行的URI
。每个URI以,
逗号间隔。
<!--过滤排除-->
<init-param>
<param-name>excludedPages</param-name>
<param-value>/simpleImg,/index.jsp,/login.jsp,/login_new.jsp</param-value><!-- 匹配不做拦截的请求声明-->
</init-param>