SSH 过滤器中URL重定向的问题(拦截action无效)

      最近开发遇到一个问题 在WEB项目中 需要对action和jsp都进行访问控制 因此使用Filter(过滤器)充当拦截器 对请求(request)中的地址过滤拦截 对拦截到的Url做返回登录页(或者首页)处理

问题一:拦截action无效

       在web.xml中配置好之后发现对jsp的访问能够过滤,但是过滤不了对action的请求。调试后发现访问action时用于请求过滤的Filter根本就没执行(将.action改成.do后,过滤器也没有执行)。

       解决办法:在web.xml中改变Filter的映射顺序,将请求过滤的Filter放到Struts2的核心过滤器之前,则可成功对action进行过滤。这里Filter的调用顺序根据web.xml中<filter-mapping>的声明顺序,而不是根据<filter>元素的声明顺序。

<filter>
    <filter-name>CheckLogin</filter-name>
    <filter-class>com.myFilter.LoginFilter</filter-class>
    <!-- <init-param>
        <param-name>noLoginPaths</param-name>
	<param-value>login.jsp;fail.jsp;LoginServlet</param-value> //在此添加不需拦截的url
    </init-param> -->
    <init-param>
        <param-name>charset</param-name> <!-- //防止中文乱码 -->
        <param-value>UTF-8</param-value>
    </init-param>
    </filter>
    <filter-mapping>
        <filter-name>CheckLogin</filter-name>
        <url-pattern>*.jsp</url-pattern>
    </filter-mapping>
    <filter-mapping>
    	<filter-name>CheckLogin</filter-name>
	<url-pattern>*.action</url-pattern>
    </filter-mapping>
    <filter-mapping>
    	<filter-name>CheckLogin</filter-name>
	<url-pattern>*.do</url-pattern>
    </filter-mapping>
    <filter-mapping>
	<filter-name>CheckLogin</filter-name>
	<url-pattern>*.html</url-pattern>
    </filter-mapping>
	
<filter>
    <filter-name>Struts2</filter-name>
    <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>Struts2</filter-name>
    <url-pattern>*.action</url-pattern>
</filter-mapping>

问题二:URL重定向

      先看LoginFilter代码:

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 com.CoreAdmin;

public class LoginFilter implements Filter {
	private FilterConfig config;
	//private IRole roleDao;

	public void init(FilterConfig config) throws ServletException {
		this.config = config;
	}

	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
		HttpServletRequest hrequest = (HttpServletRequest) request;
		String url = hrequest.getServletPath();
		CoreAdmin coreAdmin = (CoreAdmin) hrequest.getSession().getAttribute(Contains.COREADMIN);
		if (url.indexOf("login.action") != -1 || url.indexOf("login.jsp") != -1) {
			chain.doFilter(request, response);
		} else {
			if(coreAdmin == null) {
				request.getRequestDispatcher("/login.jsp").forward(request, response);
			//	response.sendRedirect(url);
			} else {
				chain.doFilter(request, response);
			}
		}
	}

	public void destroy() {
		this.config = null;
	}

}
1.response.sendRedirect(url)-----重定向到指定URL ,前后页面不是一个request
   request.getRequestDispatcher()  -------是请求转发,前后页面共享一个request

2.response.sendRedirect(url)-----是客户端跳转,地址栏中的网址将改变
   request.getRequestDispatcher(url).forward(request,response) -----是服务器端跳转,地址栏中的网址不改变


      在过滤器中用sendRedirect跳到指定的页面,一般都能正常显示,如下所示。

String contextPath = httpServletRequest.getContextPath();
httpServletResponse.sendRedirect(contextPath + "/alert.html");

       由于request.getRequestDispatcher(url).forward(request,response)的反应速度要比request.getRequestDispatcher()快 所以在程序里我们采用forward方式,如红色代码所示。但在过滤器中用forward跳到指定的页面,由于指定的页面的contextPath和当前请求的contextPath不同,导致跳到指定的页面不能加载页面需要的其它资源文件,如.css、.js、.img等资源。继续访问就会报错或者页面乱码等异常发生。

      解决方法:forward去的页面,需设置base,如下所示:

<%@ page contentType="text/html;charset=UTF-8" language="java" pageEncoding="UTF-8" isErrorPage="true"%>
<%
    request.setCharacterEncoding("utf-8");
    String path = request.getContextPath();
    String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE html>
<html lang="en">
<head>
    <base href="<%=basePath%>">
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
</head>
...

  • 22
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值