您的位置:首页 > 编程语言 > Java开发

SpringMVC使用过滤器处理登陆跳转问题

2017-04-26 14:58 531 查看
问题描述:

        如果一个页面的功能需要登陆后才能使用,比如用户的个人中心,此时,点到个人中心,系统判断用户是否登陆,如果没有登陆,则跳转到登陆页面,登陆完后自动跳转到个人中心,如果用户已经登陆了,则直接跳转到个人中心。

思路:

      使用过滤器对请求进行过滤,判断session中是否有用户,如果有用户则直接放行,如果session中没有用户,判断请求是否是需要过滤的请求,如果是不是需要过滤的请求则放行,如果是需要过滤的请求,则进行过滤。在请求中把目标url作为变量放在请求中,在第二次请求中即可跳转到该页面。

实现:

       本人表达能力有限,如果看不懂描述的话可以看代码,首先是在web.xml中进行配置过滤器

<!-- Session 过滤器 -->
<!-- 检查用户是否登录了系统的过滤器配置  开始 -->
<filter>
<filter-name>SessionFilter</filter-name>
<filter-class>cn.xaut.filter.SessionFilter</filter-class>
<init-param>
<description>将当前登录的用户的信息保存在 session 中时使用的key,如果没有配置此参数,则该过滤器不起作用</description>
<param-name>sessionKey</param-name>
<param-value>user</param-value>
</init-param>
<init-param>
<description>
如果用户未登录(即在 session 中 key 为 sessionKey 的属性不存在或为空),则将请求重定向到该 url。
该 url 不包含web应用的 ContextPath。
如果不配置此参数,则在用户未登录系统的情况下,直接重定向到web应用的根路径(/)
</description>
<param-name>forwardUrl</param-name>
<param-value>/toLogin</param-value>
</init-param>
<init-param>
<description>
不需要进行拦截的 url 的正则表达式,即:如果当前请求的 url 的 servletPath 能匹配该正则表达式,则直接放行(即使未登录系统)。
此参数的值一般为 loginServlet 和 registServlet 等。
另外,参数 redirectUrl 的值不用包含在该正则表达式中,因为 redirectUrl 对应的 url 会被自动放行。
还有一点需要说明的是,该参数的值不包含web应用的 ContextPath。
不拦截 /servlets/loginServlet 和 /servlets/registServlet
</description>
<param-name>excepUrlRegex</param-name>
<param-value>toLogin|toRegist</param-value>
</init-param>
<init-param>
<description>首页地址</description>
<param-name>indexPage</param-name>
<param-value>userActioin_goPortals.do</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>SessionFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

接下来新建一个SessionFilter.java类,该类实现Filter接口,所以要重写init(),doFilter(),destroy()三个方法

package cn.xaut.filter;

import java.io.IOException;
import java.net.URLEncoder;
import java.util.Enumeration;
import java.util.regex.Pattern;
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 org.apache.commons.lang.StringUtils;

public class SessionFilter implements Filter {
/**
* 用于检查用户是否登录了系统的过滤器<br>
* @author wft
*/

//自定义Session超时状态为 timeout
public static final String Session_Time_Out = "timeout";
/** 自定义response状态值**/
public static final int ReponseState = 911;

/** 要检查的 session 的名称 */
private String sessionKey;

/** 需要排除(不拦截)的URL的正则表达式 */
private Pattern excepUrlPattern;

/** 检查不通过时,转发的URL */
private String forwardUr
b0c1
l;

/** 网站首页地址 */
private String indexPage;

@Override
public void init(FilterConfig cfg) throws ServletException {
sessionKey = cfg.getInitParameter("sessionKey");
indexPage = cfg.getInitParameter("indexPage");

String excepUrlRegex = cfg.getInitParameter("excepUrlRegex");

if (!StringUtils.isBlank(excepUrlRegex)) {
excepUrlPattern = Pattern.compile(excepUrlRegex);
}

forwardUrl = cfg.getInitParameter("forwardUrl");
}

@Override
public void doFilter(ServletRequest req, ServletResponse res,
FilterChain chain) throws IOException, ServletException {

// 如果 sessionKey 为空,则直接放行
if (StringUtils.isBlank(sessionKey)) {
chain.doFilter(req, res);
return;
}

HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;

// 要请求的地址
String servletPath = request.getServletPath();
// 工程项目地址
String contextPath = request.getContextPath();

Object sessionObj = request.getSession().getAttribute(sessionKey);

if(sessionObj == null && servletPath.equals("/")){
chain.doFilter(req, res);
return;
}
//对静态资源进行处理
if (servletPath.endsWith(".css") || servletPath.endsWith(".js")
|| servletPath.endsWith(".png") || servletPath.endsWith(".jpg")||servletPath.endsWith(".jpeg")
|| servletPath.endsWith(".gif") || servletPath.endsWith(".jsp")||servletPath.endsWith("/GoSport/")
|| servletPath.endsWith(".html")) {
chain.doFilter(req, res);
return;
}
// 如果请求的路径与forwardUrl相同,或请求的路径是排除的URL时,则直接放行
if (sessionObj !=null || servletPath.equals(forwardUrl)|| excepUrlPattern.matcher(servletPath).matches()) {
chain.doFilter(req, res);
return;
}

// 如果Session为空,则跳转到指定页面
if (sessionObj == null) {

System.out.println("Session Filter Catched");
System.out.println("ServletPath -> " + servletPath);

//登录后返回的页面
String redirect = "";

//判断发起请求的类型 : http 或者 ajax
String type = request.getHeader("X-Requested-With");

if ("XMLHttpRequest".equalsIgnoreCase(type)) {
System.out.println("Ajax 请求");
redirect = request.getHeader("referer");
if(redirect == null)
redirect = contextPath + indexPage;
//获取到的url进行截取,等号后面的内容为目标url
                if(redirect.indexOf("=")!=-1){
                      String url[] = redirect.split("=");
                    String goUrl = url[1];
                    request.getSession().setAttribute("goUrl",goUrl);
                }
chain.doFilter(req, res);
return;
} else {
// NORMAL REQUEST PROCESS
System.out.println("Http 请求");
redirect = getHttpGoUrl(request);
}

System.out.println("redirect --> " + redirect);

// 抓住后要前往的地址
String forword = StringUtils.defaultIfEmpty(forwardUrl, "/");

// 编码重定向地址
redirect = URLEncoder.encode(redirect,"UTF-8");
request.getSession().setAttribute("goUrl",redirect);

System.out.println("跳回登录页");
response.sendRedirect(contextPath + forword+ "?redirect=" +redirect);
/*response.sendRedirect(contextPath + forword);*/
}
}

/**
* http请求action,直接跳去这个action
* */
private String getHttpGoUrl(HttpServletRequest request){

StringBuffer buffer = new StringBuffer();
String url = request.getServletPath();
buffer.append(url);

String param = request.getQueryString();//获取get的请求参数
Enumeration<String> emParams = request.getParameterNames();//获取post的请求参数
if (param != null) {
buffer.append("?");
buffer.append(param);
}
else
{
//post提交参数
boolean first = true;
do {
if (!emParams.hasMoreElements()) {
break;
}
String sParam = (String) emParams.nextElement();
String[] sValues = request.getParameterValues(sParam);

String sValue = "";
for (int i = 0; i < sValues.length; i++) {
sValue = sValues[i];
//if (sValue != null && sValue.trim().length() != 0 && first == true)
if (sValue != null && first == true) {
// 第一个参数
first = false;
buffer.append("?");
buffer.append(sParam).append("=").append(sValue);

//} else if (sValue != null && sValue.trim().length() != 0 && first == false) {
} else if (sValue != null && first == false) {
buffer.append("&").append(sParam).append("=").append(sValue);
}
}
} while (true);
}
return buffer.toString();

}

@Override
public void destroy() {
}
}


过滤器添加完了之后还需要在LoginController中添加重定向的代码

if (session.getAttribute("goUrl") != null)
//如果需要重定向
{
goUrl = URLDecoder.decode(session.getAttribute("goUrl").toString(),"UTF-8");
session.removeAttribute("goUrl");// 这里移除掉,免得又跳转
errorInfo = goUrl;
}


因为我的登陆是用ajax方式提交的,所以在ajax的代码中也需要添加跳转的代码

success : function(json) {
if(json.result == 'error'){
alert('用户名或密码错误!');
return;
}else if(json.result == 'validateFalse'){
alert('验证码错误!');
return;
}else if(json.result == 'success'){
window.location.href=getRootPath();
return;
}else{
//跳转到目标url
window.location.href= getRootPath()+json.result;
return;
}
},


至此登陆过滤器就算完成了,要过滤的action只需要在web.xml中的excepUrlRegex中添加即可
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: