360SDN.COM

首页/Java/列表

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

来源:  2018-03-11 21:21:58    评论:0点击:

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

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

后台拦截器代码:



    @Override  
        public boolean preHandle(HttpServletRequest request,  
                HttpServletResponse response, Object handler) throws Exception {  
            // 获得站点  
            CmsSite site = getSite(request, response);  
            CmsUtils.setSite(request, site);  
            // Site加入线程变量  
            CmsThreadVariable.setSite(site);  
      
            // 获得用户  
            CmsUser user = null;  
            if (adminId != null) {  
                // 指定管理员(开发状态)  
                user = cmsUserMng.findById(adminId);  
                if (user == null) {  
                    throw new IllegalStateException("User ID=" + adminId  
                            + " not found!");  
                }  
            } else {  
                // 正常状态  
                Integer userId = authMng  
                        .retrieveUserIdFromSession(session, request);  
                if (userId != null) {  
                    user = cmsUserMng.findById(userId);  
                }  
            }  
            // 此时用户可以为null  
            CmsUtils.setUser(request, user);  
            // User加入线程变量  
            CmsThreadVariable.setUser(user);  
                   <span style="color:#FF6666;"> //用户校验开始</span>  
            String uri = getURI(request);  
            // 不在验证的范围内  
            if (exclude(uri)) {  
                return true;  
            }  
            // 用户为null跳转到登陆页面  
            if (user == null) {  
                response.sendRedirect(getLoginUrl(request));  
                return false;  
            }  
                   <span style="color:#FF6666;"> //未登录用户重定向,用户校验结束</span>  
                     // 用户不是管理员,提示无权限。  
            if (!user.getAdmin()) {  
                request.setAttribute(MESSAGE, MessageResolver.getMessage(request,  
                        "login.notAdmin"));  
                response.sendError(HttpServletResponse.SC_FORBIDDEN);  
                return false;  
            }  
            // 不属于该站点的管理员,提示无权限。  
            if (!user.getSites().contains(site)) {  
                request.setAttribute(MESSAGE, MessageResolver.getMessage(request,  
                        "login.notInSite"));  
                response.sendError(HttpServletResponse.SC_FORBIDDEN);  
                return false;  
            }  
            boolean viewonly = user.getViewonlyAdmin();  
            // 没有访问权限,提示无权限。  
            if (auth && !user.isSuper()  
                    && !permistionPass(uri, user.getPerms(), viewonly)) {  
                request.setAttribute(MESSAGE, MessageResolver.getMessage(request,  
                        "login.notPermission"));  
                response.sendError(HttpServletResponse.SC_FORBIDDEN);  
                return false;  
            }  
            return true;  
        }  

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

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

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

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

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



    <bean id="adminContextInterceptor" class="com.jeecms.cms.web.AdminContextInterceptor">  
            <property name="auth" value="true"/>  
            <property name="loginUrl" value="/jeeadmin/jeecms/login.do"/>  
            <property name="returnUrl" value="/jeeadmin/jeecms/index.do"/>  
            <property name="excludeUrls">  
                <list>  
                    <value>/login.do</value>  
                    <value>/logout.do</value>  
                </list>  
            </property>  
        </bean>  


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

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

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



    public boolean preHandle(HttpServletRequest request,  
                HttpServletResponse response, Object handler)  
                throws ServletException {  
            CmsSite site = null;  
            List<CmsSite> list = cmsSiteMng.getListFromCache();  
            int size = list.size();  
            if (size == 0) {  
                throw new RuntimeException("no site record in database!");  
            } else if (size == 1) {  
                site = list.get(0);  
            } else {  
                String server = request.getServerName();  
                String alias, redirect;  
                for (CmsSite s : list) {  
                    // 检查域名  
                    if (s.getDomain().equals(server)) {  
                        site = s;  
                        break;  
                    }  
                    // 检查域名别名  
                    alias = s.getDomainAlias();  
                    if (!StringUtils.isBlank(alias)) {  
                        for (String a : StringUtils.split(alias, ',')) {  
                            if (a.equals(server)) {  
                                site = s;  
                                break;  
                            }  
                        }  
                    }  
                    // 检查重定向  
                    redirect = s.getDomainRedirect();  
                    if (!StringUtils.isBlank(redirect)) {  
                        for (String r : StringUtils.split(redirect, ',')) {  
                            if (r.equals(server)) {  
                                try {  
                                    response.sendRedirect(s.getUrl());  
                                } catch (IOException e) {  
                                    throw new RuntimeException(e);  
                                }  
                                return false;  
                            }  
                        }  
                    }  
                }  
                if (site == null) {  
                    throw new SiteNotFoundException(server);  
                }  
            }  
              
            CmsUtils.setSite(request, site);  
      
            CmsUser user = null;  
            Integer userId = authMng.retrieveUserIdFromSession(session, request);  
            if (userId != null) {  
                user = cmsUserMng.findById(userId);  
            }  
              
            if (user != null) {  
                CmsUtils.setUser(request, user);  
            }  
            return true;  
        }  


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

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



    <bean id="frontContextInterceptor" class="com.jeecms.cms.web.FrontContextInterceptor">  
            <property name="loginUrl" value="/login.jspx"/>  
            <property name="returnUrl" value="/tjhq"/>  
            <property name="excludeUrls">  
                <list>  
                    <value>/login.jspx</value>  
                    <value>/logout.jspx</value>  
                </list>  
            </property>  
        </bean>  


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

最后一个if改为:



    if (user != null) {  
                CmsUtils.setUser(request, user);  
            }else{  
                String uri = getURI(request);  
                // 不在验证的范围内  
                if (exclude(uri)) {  
                    return true;  
                }  
                // 用户为null跳转到登陆页面  
                if (user == null) {  
                    try {  
                        response.sendRedirect(getLoginUrl(request));  
                    } catch (IOException e) {  
                        e.printStackTrace();  
                    }  
                    return false;  
                }  
            }  

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

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

友情链接 |九搜汽车网 |手机ok生活信息网|ok生活信息网|ok微生活
 Powered by www.360SDN.COM   京ICP备11022651号-4 © 2012-2016 版权