防止未登錄用戶(hù)操作—基于struts2攔截器的簡(jiǎn)單實(shí)現(xiàn)
一般,我們的web應(yīng)用都是只有在用戶(hù)登錄之后才允許操作的,也就是說(shuō)我們不允許非登錄認(rèn)證的用戶(hù)直接訪(fǎng)問(wèn)某些頁(yè)面或功能菜單項(xiàng)。我還記得很久以前我的做法:在某個(gè)jsp頁(yè)面中查看session中是否有值(當(dāng)然,在用戶(hù)登錄邏輯中會(huì)將用戶(hù)名或者用戶(hù)對(duì)象存入session中),如果session中用戶(hù)信息為空,那么redirect 到登錄頁(yè)面。然后在除了登錄頁(yè)面外的其它所有需要驗(yàn)證用戶(hù)已登錄的頁(yè)面引入這個(gè)jsp 。
比如,我們將檢查用戶(hù)是否登錄的代碼放入一個(gè)jsp頁(yè)面中,如 checkUser.jsp
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%
Object username = session.getAttribute("username");
if(null == username){
response.sendRedirect("login.jsp");
}
%>
登錄頁(yè)面為 login.jsp
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>登錄頁(yè)面</title>
</head>
<body>
<h1>用戶(hù)登錄</h1>
用戶(hù)名:<input type="text" name="username" /><br />
密碼:<input type="text" name="pwd" />
</body>
</html>
假設(shè)登錄成功后跳轉(zhuǎn)到菜單頁(yè)面 menu.jsp
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <%@ include file="checkUser.jsp" %> <title>菜單頁(yè)</title> </head> <body> <h1>菜單1</h1> <br /> <h1>菜單2</h1> <br /> <h1>菜單3</h1> <br /> <h1>菜單4</h1> <br /> </body> </html>
在其中引入了 checkUser.jsp ,這樣當(dāng)用戶(hù)沒(méi)有經(jīng)過(guò)登錄而試圖訪(fǎng)問(wèn)menu.jsp 頁(yè)面時(shí)就會(huì)被強(qiáng)制轉(zhuǎn)到 login.jsp 頁(yè)面。
以上這種方法當(dāng)然是可行的,可是太過(guò)丑陋和麻煩。后來(lái),我學(xué)到可以把除了登錄頁(yè)面外的 jsp 或html 頁(yè)面放到 WEB-INF 目錄下, 這樣用戶(hù)就無(wú)法直接在瀏覽器中敲url 來(lái)訪(fǎng)問(wèn)頁(yè)面了??墒?,如果有人通過(guò)某種方式得知我們的action 名和方法名了呢?難道我們要在action的每個(gè)方法中,檢查用戶(hù)是否登錄嗎?這樣子做光是想一想就覺(jué)得很蠢。好在我們有struts2 攔截器。
先來(lái)看看怎樣實(shí)現(xiàn)。
我們寫(xiě)一個(gè)攔截器類(lèi),讓它繼承 MethodFilterInterceptor。
/**
* @Title: LoginInterceptoe.java
* @Description: 攔截非登錄用戶(hù)請(qǐng)求
* @author ThinkPad
* @version 1.0
* @date 2014年8月2日
*/
package com.exam.interceptor;
import com.exam.utils.Constants;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.MethodFilterInterceptor;
/**
* @author ThinkPad
*
*/
public class LoginInterceptor extends MethodFilterInterceptor{
/**
*
*/
private static final long serialVersionUID = -4409507846064552966L;
/* (non-Javadoc)
* @see com.opensymphony.xwork2.interceptor.MethodFilterInterceptor#doIntercept(com.opensymphony.xwork2.ActionInvocation)
*/
@Override
protected String doIntercept(ActionInvocation invoker) throws Exception {
// TODO Auto-generated method stub
Object loginUserName = ActionContext.getContext().getSession().get(Constants.USERNAME);
if(null == loginUserName){
return Constants.VIEW_LOGIN; // 這里返回用戶(hù)登錄頁(yè)面視圖
}
return invoker.invoke();
}
}
在struts.xml 文件中 填入:
<interceptors> <interceptor name="loginInteceptor" class="com.exam.interceptor.LoginInterceptor" /> <interceptor-stack name="loginStack"> <interceptor-ref name="loginInteceptor"> <param name="excludeMethods">goLogin,login</param> </interceptor-ref> <interceptor-ref name="defaultStack"></interceptor-ref> </interceptor-stack> </interceptors> <default-interceptor-ref name="loginStack" />
其中,<param name="excludeMethods">goLogin,login</param> 配置的過(guò)濾方法,意思是攔截器對(duì)其中的方法不起作用。在我這里, goLogin 是跳轉(zhuǎn)到登錄頁(yè)面的方法。login 是驗(yàn)證用戶(hù)名和密碼的方法,在其中會(huì)將通過(guò)驗(yàn)證的用戶(hù)名放入session中。沒(méi)錯(cuò),這就是我們需要做的全部事情了,是不是很方便呢?
我在這里稍微總結(jié)下:
1、在struts2 中,所有的攔截器都會(huì)繼承 Interceptor 這個(gè)接口。
2、攔截器寫(xiě)好之后要在 struts.xml 文件中配置,如果該攔截器是用來(lái)攔截某個(gè)action的,那么,就在該action 的result 后面放入該攔截器。
<struts> <package name="struts2" extends="struts-default"> <interceptors> <interceptor name="myinterceptor" class="com.interceptor.MyInterceptor"> <param name="hello">world</param> </interceptor> </interceptors> <action name="register" class="com.test.action.RegisterAction" > <result name="input">/register.jsp</result> <result name="success">/success.jsp</result> <interceptor-ref name="myinterceptor"></interceptor-ref> </action> </package> <struts>
3、如果我們沒(méi)有添加攔截器,struts2 會(huì)為我們添加默認(rèn)攔截器。而如果我們指定了攔截器,我們自己的攔截器就會(huì)取代默認(rèn)的攔截器,那么我們就不能享受默認(rèn)攔截器提供的一些功能。所以,一般我會(huì)把默認(rèn)攔截器也加上。例如,在以上配置項(xiàng)中,action 里面再加上<interceptor-ref name="defaultStack"></interceptor-ref>
4、Interceptor 接口有三個(gè)方法:init 、 destroy、intercept 。但一般我們不關(guān)心 init 和 destroy 方法。所以struts2 為我們提供了一個(gè)簡(jiǎn)化的攔截器類(lèi):AbstractInterceptor ,它實(shí)現(xiàn)了init 和 destroy 方法,我們只需實(shí)現(xiàn) intercept 方法。
5、關(guān)于攔截器棧??梢园褦r截器??闯墒且粋€(gè)“大”攔截器,里面由若干個(gè)攔截器組成。把它當(dāng)成一個(gè)攔截器一樣的引用。
6、方法過(guò)濾攔截器,需要繼承 MethodFilterInterceptor 類(lèi)(也就是我們這里示例使用的攔截器類(lèi)的做法)。你可以指定該攔截器攔截哪些方法(使用<param name="includeMethods">method1,method2</param>
),也可以指定該攔截器不去攔截哪些方法(<param name="excludeMethods">method1,method2</param>)
以上這篇防止未登錄用戶(hù)操作—基于struts2攔截器的簡(jiǎn)單實(shí)現(xiàn)就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
SpringBoot?整合?ShardingSphere4.1.1實(shí)現(xiàn)分庫(kù)分表功能
ShardingSphere是一套開(kāi)源的分布式數(shù)據(jù)庫(kù)中間件解決方案組成的生態(tài)圈,它由Sharding-JDBC、Sharding-Proxy和Sharding-Sidecar(計(jì)劃中)這3款相互獨(dú)立的產(chǎn)品組成,本文給大家介紹SpringBoot?整合?ShardingSphere4.1.1實(shí)現(xiàn)分庫(kù)分表,感興趣的朋友一起看看吧2023-12-12
Java基于drools做規(guī)則校驗(yàn)的實(shí)現(xiàn)
工作中需要開(kāi)發(fā)一個(gè)規(guī)則服務(wù),提供各種規(guī)則,本文主要介紹了Java基于drools做規(guī)則校驗(yàn)的實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的可以了解一下2024-03-03
java 各種數(shù)據(jù)類(lèi)型的互相轉(zhuǎn)換實(shí)例代碼
這篇文章主要介紹了java 各種數(shù)據(jù)類(lèi)型的互相轉(zhuǎn)換實(shí)例代碼,需要的朋友可以參考下2020-10-10
RabbitMQ冪等性與優(yōu)先級(jí)及惰性詳細(xì)全面講解
關(guān)于MQ消費(fèi)者的冪等性問(wèn)題,在于MQ的重試機(jī)制,因?yàn)榫W(wǎng)絡(luò)原因或客戶(hù)端延遲消費(fèi)導(dǎo)致重復(fù)消費(fèi)。使用MQ重試機(jī)制需要注意的事項(xiàng)以及如何解決消費(fèi)者冪等性與優(yōu)先級(jí)及惰性問(wèn)題以下將逐一講解2022-11-11
學(xué)生視角帶你了解Java內(nèi)部類(lèi)
說(shuō)起內(nèi)部類(lèi)這個(gè)詞,想必很多人都不陌生,但是又會(huì)覺(jué)得不熟悉。原因是平時(shí)編寫(xiě)代碼時(shí)可能用到的場(chǎng)景不多,用得最多的是在有事件監(jiān)聽(tīng)的情況下,并且即使用到也很少去總結(jié)內(nèi)部類(lèi)的用法。今天我們就來(lái)一探究竟2022-03-03

