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. AutoMapper Profile用法

    using System; using System.Collections.Generic; using System.Linq; using System.Web; using AutoMappe ...

  2. “fixed+relative≈≈absolute”——对BFC的再次思考

    好久没写博客了,刚好今天跨年夜没约到什么妹子,在家宅着不如写点东西好了. 需求 昨天晚上,给公司年会做一个移动端的投票页面,遇到一个UI优化的问题: · 正文内容少于一屏时,投票提交按钮固定显示在页面 ...

  3. Integer 类和 int 基本数据类型的区别

    public static void main(String[] args) { Integer i = 10; Integer j = 10; System.out.println(i == j); ...

  4. 网络安全系列 之 SQL注入学习总结

    目录 1. sql注入概述 2. sql注入测试工具 3. sql注入防御方法 3.1 问题来源 3.2 防御方法 4. SQL注入防御举例 4.1 使用JDBC时,SQL语句进行了拼接 4.2 使用 ...

  5. 学SpringBoot一篇就够了

    1.SpringBoot概述 Spring 框架对于很多 Java 开发人员来说都不陌生.自从 2002 年发布以来,Spring 框架已经成为企业应用开发领域非常流行的基础框架.有大量的企业应用基于 ...

  6. python函数基础(函数的定义和调用)

    函数的定义 python定义函数使用def关键字 return[表达式]语句用于退出函数,选择性的向调用方返回一个表达式,不带参数值的return语句返回none def 函数名(参数列表): 函数体 ...

  7. R语言进行广州租房可视化

    又到了一年一度的换租房的季节,在广州,想要找到一处好一点的租房真心不容易,不是采光不好,就是价格太贵,怎么才能找到合适自己的房子呢?于是我利用“造数”这个虫工具爬取了安居客网的广州租房的数据,通过分析 ...

  8. Keywords Search HDU2222 AC自动机模板题

    ac自动机说起来很复杂,其实和kmp是一样的思路,都是寻找相同前后缀,减少跳的次数.只要理解了kmp是怎么求next数组的,ac自动机bfs甚至比knp还好写. 这里大致说一下kmp求next数组的方 ...

  9. 网站时间显示——基于Date

    网站时间显示 代码实现如下: =============css样式=================== <style> #show{ width: 460px; height: 100p ...

  10. loj2494 [hnoi2018]寻宝游戏

    题意:给你n个元素的数组a.你可以在每个元素之前添加and和or的符号.每次询问最后变成r有多少种添号情况. n<=1000,m<=5000,q<=1000. 标程: #includ ...