防止未登录用户操作—基于struts2 * 的简单实现
作者:逐兔郎 发布时间:2021-06-11 13:21:00
一般,我们的web应用都是只有在用户登录之后才允许操作的,也就是说我们不允许非登录认证的用户直接访问某些页面或功能菜单项。我还记得很久以前我的做法:在某个jsp页面中查看session中是否有值(当然,在用户登录逻辑中会将用户名或者用户对象存入session中),如果session中用户信息为空,那么redirect 到登录页面。然后在除了登录页面外的其它所有需要验证用户已登录的页面引入这个jsp 。
比如,我们将检查用户是否登录的代码放入一个jsp页面中,如 checkUser.jsp
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%
Object username = session.getAttribute("username");
if(null == username){
response.sendRedirect("login.jsp");
}
%>
登录页面为 login.jsp
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>登录页面</title>
</head>
<body>
<h1>用户登录</h1>
用户名:<input type="text" name="username" /><br />
密码:<input type="text" name="pwd" />
</body>
</html>
假设登录成功后跳转到菜单页面 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>菜单页</title>
</head>
<body>
<h1>菜单1</h1> <br />
<h1>菜单2</h1> <br />
<h1>菜单3</h1> <br />
<h1>菜单4</h1> <br />
</body>
</html>
在其中引入了 checkUser.jsp ,这样当用户没有经过登录而试图访问menu.jsp 页面时就会被强制转到 login.jsp 页面。
以上这种方法当然是可行的,可是太过丑陋和麻烦。后来,我学到可以把除了登录页面外的 jsp 或html 页面放到 WEB-INF 目录下, 这样用户就无法直接在浏览器中敲url 来访问页面了。可是,如果有人通过某种方式得知我们的action 名和方法名了呢?难道我们要在action的每个方法中,检查用户是否登录吗?这样子做光是想一想就觉得很蠢。好在我们有struts2 * 。
先来看看怎样实现。
我们写一个 * 类,让它继承 MethodFilterInterceptor。
/**
* @Title: LoginInterceptoe.java
* @Description: 拦截非登录用户请求
* @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; // 这里返回用户登录页面视图
}
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> 配置的过滤方法,意思是 * 对其中的方法不起作用。在我这里, goLogin 是跳转到登录页面的方法。login 是验证用户名和密码的方法,在其中会将通过验证的用户名放入session中。没错,这就是我们需要做的全部事情了,是不是很方便呢?
我在这里稍微总结下:
1、在struts2 中,所有的 * 都会继承 Interceptor 这个接口。
2、 * 写好之后要在 struts.xml 文件中配置,如果该 * 是用来拦截某个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、如果我们没有添加 * ,struts2 会为我们添加默认 * 。而如果我们指定了 * ,我们自己的 * 就会取代默认的 * ,那么我们就不能享受默认 * 提供的一些功能。所以,一般我会把默认 * 也加上。例如,在以上配置项中,action 里面再加上<interceptor-ref name="defaultStack"></interceptor-ref>
4、Interceptor 接口有三个方法:init 、 destroy、intercept 。但一般我们不关心 init 和 destroy 方法。所以struts2 为我们提供了一个简化的 * 类:AbstractInterceptor ,它实现了init 和 destroy 方法,我们只需实现 intercept 方法。
5、关于 * 栈。可以把 * 栈看成是一个“大” * ,里面由若干个 * 组成。把它当成一个 * 一样的引用。
6、方法过滤 * ,需要继承 MethodFilterInterceptor 类(也就是我们这里示例使用的 * 类的做法)。你可以指定该 * 拦截哪些方法(使用<param name="includeMethods">method1,method2</param>
),也可以指定该 * 不去拦截哪些方法(<param name="excludeMethods">method1,method2</param>)
来源:http://blog.csdn.net/zhutulang/article/details/38351629
猜你喜欢
- WPF 实现筛选下拉多选控件框架使用.NET4 至 .NET6;Visual Studio 2022;创建 MultiSelect
- 本文为大家分享了WebSocket实现Web聊天室的具体代码,供大家参考,具体内容如下一.客户端JS代码如下:/* * 这部分
- 接着上次的实现, 添加 mybatis 查询 orcale 数据库第一步: 新建几个必须的包, 结果如下第二步: 在service包下新建p
- 引言用过Spring Cloud的同学都知道在使用动态配置刷新的我们要配置一个 @RefreshScope,在类上才可以实现对象属性的的动态
- Java类之间的关系图在Java以及其他的面向对象设计模式中,类与类之间主要有6种关系,他们分别是:依赖、关联、聚合、组合、继承、实现。他们
- 概况本文主要给大家介绍了通过JDK源码学习InputStream的相关内容,JDK 给我们提供了很多实用的输入流 xxxInputStrea
- java常量池是一个经久不衰的话题,也是面试官的最爱,题目花样百出,这次好好总结一下。理论先拙劣的表达一下jvm虚拟内存分布:程序计数器是j
- 反阈值二值化反阈值二值化与阈值二值化互为逆操作。在OpenCV中该类的实现依赖于threshold() 函数。下面是该函数的声明:thres
- 1、@RequestMapping@RequestMapping 既可以用在类级别,也可以用在方法级别,当它定义在类级别的时候,标明该控制器
- 1. 增强for概述增强for循环,也叫Foreach循环,用于数组和容器(集合类)的遍历。使用foreach循环遍历数组和集合元素时,无需
- 2.4.6 BoxLayout为了简化开发,Swing 引入了 一个新的布局管理器 : BoxLayout 。 BoxLayout 可以在垂
- 嵌入式Servlet容器在Spring Boot中,默认支持的web容器有 Tomcat, Jetty, 和 Undertow1、原理分析那
- 一、饿汉式单例类public class Singleton { privat
- 本文实例讲述了C#命令模式。分享给大家供大家参考。具体实现方法如下:using System;using System.Collection
- 一:简介方法引用分为三种,方法引用通过一对双冒号:: 来表示,方法引用是一种函数式接口的另一种书写方式静态方法引用,通过类名::静态方法名,
- 双向循环链表定义相比于单链表,有两个指针,next指针指向下一个结点,prior指针指向上一个结点,最后一个结点的next指针指向头结点,头
- OverView今天在复习的时候,突然复习到我们的相机操作,但是对于相机操作,对于我来说比较复杂的是对于权限的操作。所有我们需要对我们的相机
- 定义:用于顺序访问集合对象的元素,不需要知道集合对象的底层表示。特点: 1、它支持以不同的方式遍历一个
- 本文介绍了SpringCloud +Zookeeper完成配置中心,分享给大家,具有如下:使用场景项目配置更改不需要打包,重启提供配置文件的
- 查看JDK1.8 ArrayList的源代码1、默认初始容量为10 /** * Default i