zoukankan      html  css  js  c++  java
  • jeecms 前台拦截器的研究与改造

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

    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这样的方法都是没有的,从后台拦截器文件中直接拷贝过来,简单做些修改就可以用了。

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

  • 相关阅读:
    android 访问SD卡的方法
    android 用Achartengine 作图
    hello
    IIS 7.0 "确认文件是否存在"功能
    test
    收藏:如何在Web页面上直接打开、编辑、创建Office文档
    JavaScript面向对象技术
    正则表达式30分钟入门教程
    JWT有状态登陆与无状态登陆
    20条JavaScript代码简洁的写法
  • 原文地址:https://www.cnblogs.com/Jeely/p/11214656.html
Copyright © 2011-2022 走看看