zoukankan      html  css  js  c++  java
  • 纳税服务系统【登陆、权限拦截、页面嵌套】

    前言

    到目前为止,我们已经写了用户模块和角色模块了。也已经把系统的首页和子系统的首页配置好了。我们的系统是需要登陆后才能访问的

    这里写图片描述

    因此,本博文主要讲解登陆模块、权限拦截


    登陆模块

    编写Action与配置文件

    引入对应的JSP页面

    这里写图片描述

    编写Action处理请求和对应的配置文件:

    这里写图片描述

    效果:

    这里写图片描述

    Action处理

    在常量类中保存着一个Session的标识:

    
        /***********保存Session域的常量***********/
        public static String USER = "SYS_USER";

    Action

    package zhongfucheng.login;
    
    import com.opensymphony.xwork2.ActionContext;
    import org.apache.commons.logging.Log;
    import org.apache.commons.logging.LogFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import zhongfucheng.core.action.BaseAction;
    import zhongfucheng.core.constant.Constant;
    import zhongfucheng.user.entity.User;
    import zhongfucheng.user.service.UserService;
    
    import java.util.List;
    
    /**
     * Created by ozc on 2017/6/2.
     */
    public class LoginAction extends BaseAction {
    
        /***************封装数据**********************/
        private User user;
        public User getUser() {
            return user;
        }
        public void setUser(User user) {
            this.user = user;
        }
        /****************调用userService****************************/
        @Autowired
        private UserService userServiceImpl;
    
        public String loginUI() {
            return "loginUI";
        }
    
        /****************记载着登陆状态信息*********************/
        private String loginResult;
    
        public String getLoginResult() {
            return loginResult;
        }
    
        public void setLoginResult(String loginResult) {
            this.loginResult = loginResult;
        }
    
        /*****************业务方法******************/
    
        public String login() {
    
            if (user != null) {
                List<User> list = userServiceImpl.findUserByAccountAndPassword(user.getAccount(), user.getPassword());
    
                //如果查到有值,那么就证明有该用户的,给他登陆
                if (list != null && list.size() > 0) {
    
                    //保存到Session域中,为了更方便用,我们使用常量保存。
                    ActionContext.getContext().getSession().put(Constant.USER, list.get(0));
    
                    //保存到日志文件中Log
                    Log log = LogFactory.getLog(getClass());
                    log.info("用户名称为" + list.get(0).getName() + "登陆了系统!");
    
                    //重定向到首页
                    return "home";
                } else {
                    //登陆失败,记载登陆信息
                    loginResult = "登陆失败了,用户名或密码错误了";
                }
            }
            //只要不成功的,都回到登陆页面
            return loginUI();
        }
    }
    
    

    在dao层中实现根据账户和密码查询数据:

    
        @Override
        public List<User> findUserByAccountAndPassword(String account, String password) {
    
            //通过账户和密码查找对象
            String sql = "FROM User WHERE account=? AND password=?";
            return getSession().createQuery(sql).setParameter(0, account).setParameter(1,password).list();
    
    
        }

    我们还在Action中定义了一个String来记载着Login的状态,如果出错了。我们就返回loginUI界面,然后在那里回显Login出错的信息。

    • 效果:

    这里写图片描述

    同时登录完在系统主页上回显数据:

    
        <a><b></b><font color="red">欢迎您,<s:property value="%{#session.SYS_USER.account}"/> &nbsp;</font></a>

    这里写图片描述


    注销功能

    在主页上的退出上绑定超链接

    
        <td align="left" valign="middle" ><a href="${ctx}/sys/login_logout.action">退出</a></td>
    

    Action处理:

    
        public String logout() {
    
            //销毁session的值
            ActionContext.getContext().getSession().remove(Constant.USER);
    
            return loginUI();
        }

    处理首页

    当用户访问首页的时候,我们重定向到登陆页面:

    
    <%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
    <%
      String path = request.getContextPath();
      String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
      response.sendRedirect(basePath + "sys/login_loginUI.action");
    %>
    

    过滤器模块

    进入系统拦截

    我们讲道理是要用户登陆后,才能访问我们的总系统。但是现在假如用户知道了我们的首页地址,他可以直接访问我们的首页地址而不用登陆。这是不合适的。

    这里写图片描述

    因此,我们写一个过滤器进行拦截,如果用户不是想要登陆,而访问我们其他的页面。都拦截他,让他登陆后才能访问。

    这里写图片描述

    过滤器:

    
    package zhongfucheng.core.filter;
    
    import zhongfucheng.user.entity.User;
    
    import javax.servlet.*;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    
    /**
     * Created by ozc on 2017/6/4.
     */
    
    public class LoginFilter implements Filter {
    
        public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
            HttpServletRequest request = (HttpServletRequest) req;
            HttpServletResponse response = (HttpServletResponse) resp;
    
            //得到用户访问的路径
            String uri = request.getRequestURI();
    
            //登陆路径
            String loginPath = request.getContextPath() + "/sys/login_login.action";
    
            //判断用户访问的是哪里
            if (!uri.contains("login_")) {//如果不是访问我们的登陆模块
    
                //判断该用户是否登陆了。
                User user = (User) request.getSession().getAttribute("SYS_USER");
    
                if (user == null) {//如果在session找不到,那么就是没有登陆
                    //没有登陆,跳转到登陆页面
                    response.sendRedirect(loginPath);
                    return;
    
                } else {//有用户信息,就是登陆了。
    
                    //放行
                    chain.doFilter(request, response);
                }
    
            } else {//如果是访问我们的登陆模块,放行
                chain.doFilter(request, response);
            }
        }
    
        public void init(FilterConfig config) throws ServletException {
    
        }
    
        public void destroy() {
        }
    }
    

    配置过滤器,需要在struts过滤器之前配置:

    
        <filter>
            <filter-name>LoginFilter</filter-name>
            <filter-class>zhongfucheng.core.filter.LoginFilter</filter-class>
        </filter>
        <filter-mapping>
            <filter-name>LoginFilter</filter-name>
            <url-pattern>*.action</url-pattern>
        </filter-mapping>
    

    效果:

    这里写图片描述


    权限过滤

    我们的纳税服务子系统并不是任何人都可以进去操作的,我们有可以对角色的管理,对用户的管理。。一般的用户是没有权限去操作这些东西的。因此,我们要对其进行权限控制。

    当该用户有权限才能够访问纳税服务系统的内容,没有权限就不给该用户看。

    权限过滤的前提条件:

    • 用户已经登陆了
    • 知道用户访问的是什么子系统

    由于我们在LoginFilter中已经可以得到这两个条件了,于是我们在LoginFilter中接着写就行了。又因为权限过滤是一个比较单独的模块,我们可以将其抽出。这样一来,LoginFilter又不会显得太大,职责又分工了。

    这里写图片描述

    过滤器全部代码:WebApplicationContextUtils得到IOC中的对象

    
    package zhongfucheng.core.filter;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.context.WebApplicationContext;
    import org.springframework.web.context.support.WebApplicationContextUtils;
    import zhongfucheng.core.utils.PermissionCheck;
    import zhongfucheng.user.entity.User;
    import zhongfucheng.user.service.UserService;
    
    import javax.servlet.*;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    
    /**
     * Created by ozc on 2017/6/4.
     */
    
    public class LoginFilter implements Filter {
    
        //注入userService
        @Autowired
        private UserService userServiceImpl;
    
        public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
            HttpServletRequest request = (HttpServletRequest) req;
            HttpServletResponse response = (HttpServletResponse) resp;
    
            //得到用户访问的路径
            String uri = request.getRequestURI();
    
            //登陆路径
            String loginPath = request.getContextPath() + "/sys/login_login.action";
    
            //提示页面
            String warningPath = request.getContextPath() + "/sys/login_noPermissionUI.action";
    
            //定义User变量
            User user;
            //判断用户访问的是哪里
            if (!uri.contains("login_")) {//如果不是访问我们的登陆模块
    
                //判断该用户是否登陆了。
                 user = (User) request.getSession().getAttribute("SYS_USER");
                if (user == null) {//如果在session找不到,那么就是没有登陆
                    //没有登陆,跳转到登陆页面
                    response.sendRedirect(loginPath);
                    return;
    
                } else {//有用户信息,就是登陆了。
    
                    if (uri.contains("nsfw")) {//如果访问纳税服务系统,就要有对应的权限
    
                        //用户已经登陆了,判断用户有没有权限访问子系统
    
                        //得到IOC容器中的对象
                        WebApplicationContext applicationContext = WebApplicationContextUtils.getWebApplicationContext(request.getSession().getServletContext());
                        PermissionCheck permissionCheck = (PermissionCheck)applicationContext.getBean("permissionCheck");
    
                        if (permissionCheck.check(user, "nsfw")) {//有权限
                            //放行
                            chain.doFilter(request, response);
                        } else {//没有权限
    
                            //返回到提示页面
                            response.sendRedirect(warningPath);
                        }
    
                    } else {//可以不用权限,直接放行
                        //放行
                        chain.doFilter(request, response);
                    }
                }
    
            } else {//如果是访问我们的登陆模块,放行
                chain.doFilter(request, response);
            }
        }
    
        public void init(FilterConfig config) throws ServletException {
    
        }
    
        public void destroy() {
        }
    
    
    }
    

    在登陆完之后,就查询出用户拥有的所有角色,并设置到该用户中:

    
        public String login() {
    
            if (user != null) {
                List<User> list = userServiceImpl.findUserByAccountAndPassword(user.getAccount(), user.getPassword());
    
                //如果查到有值,那么就证明有该用户的,给他登陆
                if (list != null && list.size() > 0) {
    
                    //查出用户所有的权限,设置到User中
                    User user = list.get(0);
                    List<UserRole> roles = userServiceImpl.findRoleById(user.getId());
                    user.setUserRoles(roles);
    
                    //保存到Session域中,为了更方便用,我们使用常量保存。
                    ActionContext.getContext().getSession().put(Constant.USER, user);
    
    
                    //保存到日志文件中Log
                    Log log = LogFactory.getLog(getClass());
                    log.info("用户名称为" + list.get(0).getName() + "登陆了系统!");
    
                    //重定向到首页
                    return "home";
                } else {
                    //登陆失败,记载登陆信息
                    loginResult = "登陆失败了,用户名或密码错误了";
                }
            }
            //只要不成功的,都回到登陆页面
            return loginUI();
        }

    在User.java中加入一个List集合,存储着用户所拥有的角色

    
        //得到用户所有的角色
        private List<UserRole> userRoles;
        public List<UserRole> getUserRoles() {
            return userRoles;
        }
        public void setUserRoles(List<UserRole> userRoles) {
            this.userRoles = userRoles;
        }
    

    到这里,有同学可能会疑问,为啥现在我要修改User的结构呢??明明在编写User和Role的时候说好不修改User类的。我们在验证的时候需要得到用户所有的角色,从而得到权限。如果在检查的时候做的话,我们用的是过滤器检查,每请求一次都要去访问数据库。

    这样的话就非常耗费我们的性能,于是我们就修改User类,但这次的修改没有影响到我们其他地方的操作。这样一来,我们在检查的时候就可以通过对象来得到用户对应的权限了,不用查询数据库。


    页面嵌套问题

    现在我打开了两个首页,是同一个会话的。如果用户太久没有操作我们的页面,那么Session就会被摧毁。

    这里写图片描述

    等用户再操作的时候,Session已经被Tomcat摧毁了。讲道理用户操作页面的时候,是会回到登陆页面的。我们看看发生了什么:

    这里写图片描述

    登陆页面嵌套在我们右边的显示页面了。为啥出现这种情况??

    • 当用户的Session没有了,用户操作时,过滤器就会将页面跳转到登陆页面
    • 而我们点击了左边的菜单栏,默认在右边显示

    所以,到目前为止,我们的逻辑是没毛病的。但怎么解决上面遇到的情况呢??* 我们不需要使用监听器Session,监听Session被摧毁了,然后刷新页面*。。我们用更好地一种解决办法:

    • 判断自身页面是否为顶级窗口,如果不是就自动刷新父窗口的地址,跳转到顶级窗口中。
    
        /*如果该页面不是顶级窗口,那么就自动刷新一下到父窗口中*/
        if(window!=window.parent) {
            window.parent.location.reload(true);
        }
    

  • 相关阅读:
    shell编程基础(六): 透彻解析查找命令find
    shell编程基础(五): 正则表达式及其使用
    shell编程基础(三): 位置参数与shell脚本的输入输出
    shell编程基础(二): shell脚本语法之分支语句和循环语句
    shell编程基础(一): 基本变量和基本符号
    SpringCloud学习(一):微服务简介
    ubuntu 安装bazel
    numpy reshape resize用法
    L0、L1及L2范数
    linux常用的搜索命令
  • 原文地址:https://www.cnblogs.com/zhong-fucheng/p/7202915.html
Copyright © 2011-2022 走看看