jeecms 前台拦截器的研究与改造

2013年12月24日 15:23:35 xinfei0803 阅读数 3511
 

jeecms出发点是面向大众的,具有前台开发性,也就是说,即时是未登录(游客),也可以浏览到前台页面的内容,只是有些操作需要(增删改)注册和登录之后才可以进行。

后台当然不能随便进入了,必须登录后才可以进入后台,那么jeecms是怎么做的呢?我们看一看源码。

后台拦截器代码:

  1.  
    @Override
  2.  
    public boolean preHandle(HttpServletRequest request,
  3.  
    HttpServletResponse response, Object handler) throws Exception {
  4.  
    // 获得站点
  5.  
    CmsSite site = getSite(request, response);
  6.  
    CmsUtils.setSite(request, site);
  7.  
    // Site加入线程变量
  8.  
    CmsThreadVariable.setSite(site);
  9.  
     
  10.  
    // 获得用户
  11.  
    CmsUser user = null;
  12.  
    if (adminId != null) {
  13.  
    // 指定管理员(开发状态)
  14.  
    user = cmsUserMng.findById(adminId);
  15.  
    if (user == null) {
  16.  
    throw new IllegalStateException("User ID=" + adminId
  17.  
    + " not found!");
  18.  
    }
  19.  
    } else {
  20.  
    // 正常状态
  21.  
    Integer userId = authMng
  22.  
    .retrieveUserIdFromSession(session, request);
  23.  
    if (userId != null) {
  24.  
    user = cmsUserMng.findById(userId);
  25.  
    }
  26.  
    }
  27.  
    // 此时用户可以为null
  28.  
    CmsUtils.setUser(request, user);
  29.  
    // User加入线程变量
  30.  
    CmsThreadVariable.setUser(user);
  31.  
    //用户校验开始
  32.  
    String uri = getURI(request);
  33.  
    // 不在验证的范围内
  34.  
    if (exclude(uri)) {
  35.  
    return true;
  36.  
    }
  37.  
    // 用户为null跳转到登陆页面
  38.  
    if (user == null) {
  39.  
    response.sendRedirect(getLoginUrl(request));
  40.  
    return false;
  41.  
    }
  42.  
    //未登录用户重定向,用户校验结束
  43.  
     // 用户不是管理员,提示无权限。
  44.  
    if (!user.getAdmin()) {
  45.  
    request.setAttribute(MESSAGE, MessageResolver.getMessage(request,
  46.  
    "login.notAdmin"));
  47.  
    response.sendError(HttpServletResponse.SC_FORBIDDEN);
  48.  
    return false;
  49.  
    }
  50.  
    // 不属于该站点的管理员,提示无权限。
  51.  
    if (!user.getSites().contains(site)) {
  52.  
    request.setAttribute(MESSAGE, MessageResolver.getMessage(request,
  53.  
    "login.notInSite"));
  54.  
    response.sendError(HttpServletResponse.SC_FORBIDDEN);
  55.  
    return false;
  56.  
    }
  57.  
    boolean viewonly = user.getViewonlyAdmin();
  58.  
    // 没有访问权限,提示无权限。
  59.  
    if (auth && !user.isSuper()
  60.  
    && !permistionPass(uri, user.getPerms(), viewonly)) {
  61.  
    request.setAttribute(MESSAGE, MessageResolver.getMessage(request,
  62.  
    "login.notPermission"));
  63.  
    response.sendError(HttpServletResponse.SC_FORBIDDEN);
  64.  
    return false;
  65.  
    }
  66.  
    return true;
  67.  
    }

两行红色注释之间的代码,就是用来校验用户是否存在,用户信息是否有效的,这几句代码的功能可以分以下几个点来叙述:

1,获取请求uri并作处理,检测该uri是否符合要求,若不符合抛出异常。

2,如果当前请求的uri是例外的,放行,不做拦截,这里主要是对登录和登出的uri放行,防止死循环。

3,如果当前请求没有登录用户,则重定向到登录页。

具体的参数信息可以查看配置文件:jeecms-servlet-admin.xml

  1.  
    <bean id="adminContextInterceptor" class="com.jeecms.cms.web.AdminContextInterceptor">
  2.  
    <property name="auth" value="true"/>
  3.  
    <property name="loginUrl" value="/jeeadmin/jeecms/login.do"/>
  4.  
    <property name="returnUrl" value="/jeeadmin/jeecms/index.do"/>
  5.  
    <property name="excludeUrls">
  6.  
    <list>
  7.  
    <value>/login.do</value>
  8.  
    <value>/logout.do</value>
  9.  
    </list>
  10.  
    </property>
  11.  
    </bean>

整个重定向功能就是这样,那么我们前台也想要这种效果,不登陆用户不可以浏览任何页面,并定向到登陆页让其登录去,怎么办呢?

很简单了,比葫芦画瓢就是了。

首先我们找到前台url的拦截器:FrontContextInterceptor.java

  1.  
    public boolean preHandle(HttpServletRequest request,
  2.  
    HttpServletResponse response, Object handler)
  3.  
    throws ServletException {
  4.  
    CmsSite site = null;
  5.  
    List<CmsSite> list = cmsSiteMng.getListFromCache();
  6.  
    int size = list.size();
  7.  
    if (size == 0) {
  8.  
    throw new RuntimeException("no site record in database!");
  9.  
    } else if (size == 1) {
  10.  
    site = list.get(0);
  11.  
    } else {
  12.  
    String server = request.getServerName();
  13.  
    String alias, redirect;
  14.  
    for (CmsSite s : list) {
  15.  
    // 检查域名
  16.  
    if (s.getDomain().equals(server)) {
  17.  
    site = s;
  18.  
    break;
  19.  
    }
  20.  
    // 检查域名别名
  21.  
    alias = s.getDomainAlias();
  22.  
    if (!StringUtils.isBlank(alias)) {
  23.  
    for (String a : StringUtils.split(alias, ',')) {
  24.  
    if (a.equals(server)) {
  25.  
    site = s;
  26.  
    break;
  27.  
    }
  28.  
    }
  29.  
    }
  30.  
    // 检查重定向
  31.  
    redirect = s.getDomainRedirect();
  32.  
    if (!StringUtils.isBlank(redirect)) {
  33.  
    for (String r : StringUtils.split(redirect, ',')) {
  34.  
    if (r.equals(server)) {
  35.  
    try {
  36.  
    response.sendRedirect(s.getUrl());
  37.  
    } catch (IOException e) {
  38.  
    throw new RuntimeException(e);
  39.  
    }
  40.  
    return false;
  41.  
    }
  42.  
    }
  43.  
    }
  44.  
    }
  45.  
    if (site == null) {
  46.  
    throw new SiteNotFoundException(server);
  47.  
    }
  48.  
    }
  49.  
     
  50.  
    CmsUtils.setSite(request, site);
  51.  
     
  52.  
    CmsUser user = null;
  53.  
    Integer userId = authMng.retrieveUserIdFromSession(session, request);
  54.  
    if (userId != null) {
  55.  
    user = cmsUserMng.findById(userId);
  56.  
    }
  57.  
     
  58.  
    if (user != null) {
  59.  
    CmsUtils.setUser(request, user);
  60.  
    }
  61.  
    return true;
  62.  
    }

拦截器很简单,并没有在检测到用户无效后做任何措施,不管怎样都是放行的,那么我们就在最后一个if路面添加else,也就是说if(user==null)我们就做些事情:

其配置文件jeecms-servlet-front.xml并没有对该拦截器配置参数,那么我们就自己来配置,当然要仿照后台的拦截器来配:

  1.  
    <bean id="frontContextInterceptor" class="com.jeecms.cms.web.FrontContextInterceptor">
  2.  
    <property name="loginUrl" value="/login.jspx"/>
  3.  
    <property name="returnUrl" value="/tjhq"/>
  4.  
    <property name="excludeUrls">
  5.  
    <list>
  6.  
    <value>/login.jspx</value>
  7.  
    <value>/logout.jspx</value>
  8.  
    </list>
  9.  
    </property>
  10.  
    </bean>

loginUrl是登录页的url,returnUrl指的是登陆后进入的url,而excludeUrls是例外情况,也就是说碰到这两个url都放行。

最后一个if改为:

  1.  
    if (user != null) {
  2.  
    CmsUtils.setUser(request, user);
  3.  
    }else{
  4.  
    String uri = getURI(request);
  5.  
    // 不在验证的范围内
  6.  
    if (exclude(uri)) {
  7.  
    return true;
  8.  
    }
  9.  
    // 用户为null跳转到登陆页面
  10.  
    if (user == null) {
  11.  
    try {
  12.  
    response.sendRedirect(getLoginUrl(request));
  13.  
    } catch (IOException e) {
  14.  
    e.printStackTrace();
  15.  
    }
  16.  
    return false;
  17.  
    }
  18.  
    }

当然了,getURI,exclude,getLoginUrl这样的方法都是没有的,从后台拦截器文件中直接拷贝过来,简单做些修改就可以用了。

这样,我们的前台页面也跟后台一致了,都实现了登录重定向功能。

jeecms 前台拦截器的研究与改造的更多相关文章

  1. 为什么你写的拦截器注入不了 Java bean?

    一.如何实现拦截器 在Spring Boot项目中,拦截器经常被用来做登陆验证,日志记录等操作.拦截器是Spring提供的,所以可以将拦截器注成bean,由IOC容器来管理.实现拦截器的方式很简单,主 ...

  2. SpringBoot 拦截器 && 拦截之后返回前台自定义格式

    1.加入 阿里的 json jar包 <!--json jar相关jar包--> <dependency> <groupId>com.fasterxml.jacks ...

  3. SpringMVC拦截器详解[附带源码分析]

    目录 前言 重要接口及类介绍 源码分析 拦截器的配置 编写自定义的拦截器 总结 总结 前言 SpringMVC是目前主流的Web MVC框架之一. 如果有同学对它不熟悉,那么请参考它的入门blog:h ...

  4. 我心中的核心组件(可插拔的AOP)~第二回 缓存拦截器

    回到目录 AOP面向切面的编程,也称面向方面的编程,我更青睐于前面的叫法,将一个大系统切成多个独立的部分,而这个独立的部分又可以方便的插拔在其它领域的系统之中,这种编程的方式我们叫它面向切面,而这些独 ...

  5. springmvc(3)拦截器HandlerInterceptor源码的简单解析

    其实拦截器就是我们的AOP编程.拦截器在我们的实际项目中实用性比较大的,比如:日志记录,权限过滤,身份验证,性能监控等等.下面就简单的来研究一下拦截器: public interface Handle ...

  6. struts2 拦截器和actioninvocation、PreResultListener

       Interceptor说明 Interceptor的接口定义没有什么特别的地方,除了init和destory方法以外,intercept方法是实现整个拦截器机制的核心方法.而它所依赖的参数Act ...

  7. struts2 18拦截器详解(七)

    ChainingInterceptor 该拦截器处于defaultStack第六的位置,其主要功能是复制值栈(ValueStack)中的所有对象的所有属性到当前正在执行的Action中,如果说Valu ...

  8. Struts2的运行流程以及关键拦截器介绍

    Struts2的运行流程 1.ActionProxy是Action的一个代理类,也就是说Action的调用是通过ActionProxy实现的,其实就是调用了ActionProxy.execute()方 ...

  9. struts2-权限拦截器、日志拦截器、execAndWait(进度条)拦截器配置

    1.权限拦截器 package login; import javax.servlet.http.HttpServletResponse; import org.apache.struts2.Serv ...

随机推荐

  1. LUOGU P3161 [CQOI2012]模拟工厂 (贪心)

    传送门 解题思路 贪心,首先因为\(n\)比较小,可以\(2^n\)枚举子集.然后判断的时候就每次看后面的如果用最大生产力生产能不能达成目标,解一个二次函数. 代码 #include<iostr ...

  2. day18_文件处理_迭代器_生成器

    #!/usr/bin/env python # -*- coding:utf-8 -*- # ********************day18_文件处理_迭代器_生成器 ************** ...

  3. 通过apiservice反向代理访问service

    第一种:NodePort类型 type: NodePort ports: - port: 80 targetPort: 80 nodePort: 30008 ​ 第二种:ClusterIP类型 typ ...

  4. USACO 2006 November Gold Corn Fields /// 状压 oj23941

    题目大意: 输入n m 接下来n行m列 0表示不能种玉米 1表示能 要求种玉米位置的上下左右四连通区域不能种玉米 输出方案数 Sample Input 2 31 1 10 1 0 Sample Out ...

  5. 海量可视化日志分析平台之ELK搭建

    ELK是什么? E=ElasticSearch ,一款基于的Lucene的分布式搜索引擎,我们熟悉的github,就是由ElastiSearch提供的搜索,据传已经有10TB+的数据量. L=LogS ...

  6. C++ 系列:typedef 和 #define 的区别

    总结一下typedef和#define的区别 1.概念 #define 它在编译预处理时进行简单的替换,不作正确性检查.它是预处理指令. typedef 它在自己的作用域内给一个已经存在的类型一个别名 ...

  7. half adder vs. full adder

    1, half adder 2-input, 2-output input: A, B; output out, carry; 2, full adder 3-input, 2-output inpu ...

  8. resful风格

    package com.atguigu.springboot.controller; import com.atguigu.springboot.dao.DepartmentDao; import c ...

  9. 19-10-29-Night-X

    布谷. 欢迎大家来不耻下问. 这里是正解不会,暴力写跪,乱搞鸡肋的某虻 . 好想放假啊!!!! 话说猫厂现在产量低迷…… ZJ一下: T1,三维偏序,只码了$\Theta(N^2)$暴力 T2,暴力愉 ...

  10. Linux 启动出现 busybox vx.x.xx built-in shell 的问题

    可能是磁盘检测错误,尤其出现在未安全关机或者磁盘损坏之后. 解决办法: 1.在选择启动项目时,选中第一项,如: ubuntu 8.04kernl.2.6.22-16-generic 2.按E 进入编辑 ...