JavaWeb-未登录时的页面拦截

前言:对于普遍的web项目,当用户登录后才能具体进行想要进行的操作,当用户未登录时,是不能让用户进入具体操作页面进行数据操作的,因此,应该对用户访问的页面进行过滤,当是登录页面时,可以进行登录操作,当用户未登录想要访问具体数据操作页面时,应该让其跳转到登录页面进行登录.下面将简单实现该功能.

 

1.分析:

首先,我们需要清楚用什么进行过滤,什么时候应该过滤.

(1)如何进行过滤

用户访问时,项目的每个页面都有可能被用户无意或有意访问,如果用户在登录过后,这样的操作无可厚非,但当用户未登录时,这样的操作可能会引起严重的后果,因此,当用户想要访问项目时,应该对用户的访问路径进行过滤,对项目的每个页面都进行保护.这是,可以想到过滤器就是为过滤而生的,我们可以用过滤器对每个页面进行保护.因此我们就需要过滤器来实现.

(2)什么时候应该过滤

知道了使用什么完成过滤,既然每个页面都有被访问的危险,那么我们所有的页面都应该保护,因此我们应该在过滤器配置时应该将url-pattern设置为/*,也就是任何时候都需要过滤

2.功能具体实现

知道了大概思路,我们就应该一步一步将功能实现

(1)过滤器配置

我们知道应该使用过滤器Filter进行过滤,那么我们首先将过滤器创建出来,创建出filter一定要进行配置.配置如下:

<filter>
    <filter-name>loginFilter</filter-name>
    <filter-class>sanmu.filter.LoginFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>loginFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

这里我们需要注意:filter-class一定要配置准确,否则filter不会生效,检查是否正确的方法是:如果使用的IDE是eclipse,按住Ctrl键,鼠标指向配置的路径时路径变为蓝色并有下划线即为配置正确.还需要注意的一点是url-pattern需要配置为/*,意义为:为每个请求过滤.

(2)具体实现

首先也先来搞清楚思路,过滤器过滤时我们应该根据用户的请求进行判断是否让用户访问,因为我们还需要让用户可以在login页面正常登录,那么我们如何知道用户的访问页面呢?仔细一想,我们发现请求对象有一个方法getRequestURI()可以获取用户请求路径,也就是说浏览器的地址栏的内容,正好满足需求.

String url = req.getRequestURI();
/*这里需要着重注意的是,用户登录页面的填写用户名和密码的表单在此处是获取不到的
获取不到导致的结果就是我们无法让用户正常登录,因为我们在拦截之后,每次取出的路径只要页面部分(如http://xxx/xxx/login.jsp 页面部分为login.jsp)不是登录页面,就会重新定位到登录页面,我们就无法将表单数据传输到后台进行用户的登陆逻辑,如果不明白可以将路径输出一下,仔细过一遍代码

解决方案在后面部分可见
*/

下一步,在得到用户的访问路径时,我们需要进一步知道用户想要访问的是哪个页面,所以接下来我们需要对路径进行切割得到具体的页面,代码如下

//例如访问路径为:http://xxx/xxx/login.jsp,取出的就是login.jsp
String path = url.substring(url.lastIndexOf("/") + 1);
//表单中隐藏表单项的值(后面会说明什么意思)
String action = req.getParameter("action");
/*获取最后页面的后缀,取出后缀的原因是因为我们页面可能不光是页面,其中包含的一些静态资源也需要向服务器请求,如js/css/image等,如果这些都过滤,那么页面样式将无法使用
*/
String suffix = path.substring(path.lastIndexOf(".") + 1);

下面,获得判断条件之后,我们就应该进行具体的判断了,当页面是login.jsp或静态资源时,我们应该放行,当访问页面是其他页面时,我们应该判断用户是否登录过,如果登陆过就放行,否则重定位到login.jsp,代码如下:

// 如果是登录页面就或者js/jpg/png/css放行,如果不是就拦截并重定向到登录页面
if ("login.jsp".equals(path) || suffix.equals("js") || suffix.equals("jpg") || suffix.equals("png")|| suffix.equals("css")||"login".equals(action)) {
    chain.doFilter(req, resp);
} else {
// 获取session中的用户值,如果登录过就应该存在
/*
这里获取的user是在后台进行存储的,如果用户处于正常登录的状态,就会将用户信息放在
session域中,如果未登录,信息就会为空,当不为空时,应当放行,否则定位到login.jsp页面进行登录
*/
    User user = (User) req.getSession().getAttribute("user");
    if (user != null) {
	chain.doFilter(req, resp);
    } else {
	resp.sendRedirect("login.jsp");
    }
}

到这里为止,过滤器具体逻辑已经简单实现了.

下面说一下登录的jsp页面需要注意的方面.

首先,当用户通过页面填写好用户名和密码之后,点击登录,就会进入到过滤器中进行过滤,就会执行过滤器的代码,例如登录表单访问的是后台servlet页面,此时过滤器中获取的页面的名称就是servlet设置的名称,不符合我们if中的条件,那么就会进入到else中,此时用户处于未登录状态,所以用户信息为空,又会重新定位到login.jsp.这样就无法让用户登录,这就是问题所在.

我试过在表单的action属性中在访问的页面后面拼接上一个参数,在过滤器中通过判断这个参数来决定是否放行,但是发现通过请求方法获取的路径是不包含拼接的参数的,所以这个方法不可行.而这个问题的解决办法就是需要在表单中增加一个表单项,设置一下它的值,当进入过滤器时,可以使用请求对象的getParameter()方法进行获取表单项的值,为了不影响页面样式,将该表单项设置为隐藏.页面代码如下:

<section class="loginCont">
    <form class="loginForm" action="userServlet">
	<div style="display: none">
            	<input type="text" name="action" value="login">
        </div>
	<div class="inputbox">
		<label for="user">用户名:</label> 
                <input id="user" type="text" name="username" placeholder="请输入用户名" required />
	</div>
	<div class="inputbox">
		<label for="mima">密码:</label> 
                <input id="mima" type="password"name="password" placeholder="请输入密码" required /> 
                <span style="color: red;" id="msg">${msg}</span>
	</div>
	<div class="subBtn">
		<input type="submit" value="登录" /> <input type="reset" value="重置" />
	</div>

</form>
		</section>

这样,功能就简单实现了.

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值