jeecms 前台拦截器的研究与改造
jeecms 前台拦截器的研究与改造
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);
- //用户校验开始
- String uri = getURI(request);
- // 不在验证的范围内
- if (exclude(uri)) {
- return true;
- }
- // 用户为null跳转到登陆页面
- if (user == null) {
- response.sendRedirect(getLoginUrl(request));
- return false;
- }
- //未登录用户重定向,用户校验结束
- // 用户不是管理员,提示无权限。
- 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这样的方法都是没有的,从后台拦截器文件中直接拷贝过来,简单做些修改就可以用了。
这样,我们的前台页面也跟后台一致了,都实现了登录重定向功能。
jeecms 前台拦截器的研究与改造的更多相关文章
- 为什么你写的拦截器注入不了 Java bean?
一.如何实现拦截器 在Spring Boot项目中,拦截器经常被用来做登陆验证,日志记录等操作.拦截器是Spring提供的,所以可以将拦截器注成bean,由IOC容器来管理.实现拦截器的方式很简单,主 ...
- SpringBoot 拦截器 && 拦截之后返回前台自定义格式
1.加入 阿里的 json jar包 <!--json jar相关jar包--> <dependency> <groupId>com.fasterxml.jacks ...
- SpringMVC拦截器详解[附带源码分析]
目录 前言 重要接口及类介绍 源码分析 拦截器的配置 编写自定义的拦截器 总结 总结 前言 SpringMVC是目前主流的Web MVC框架之一. 如果有同学对它不熟悉,那么请参考它的入门blog:h ...
- 我心中的核心组件(可插拔的AOP)~第二回 缓存拦截器
回到目录 AOP面向切面的编程,也称面向方面的编程,我更青睐于前面的叫法,将一个大系统切成多个独立的部分,而这个独立的部分又可以方便的插拔在其它领域的系统之中,这种编程的方式我们叫它面向切面,而这些独 ...
- springmvc(3)拦截器HandlerInterceptor源码的简单解析
其实拦截器就是我们的AOP编程.拦截器在我们的实际项目中实用性比较大的,比如:日志记录,权限过滤,身份验证,性能监控等等.下面就简单的来研究一下拦截器: public interface Handle ...
- struts2 拦截器和actioninvocation、PreResultListener
Interceptor说明 Interceptor的接口定义没有什么特别的地方,除了init和destory方法以外,intercept方法是实现整个拦截器机制的核心方法.而它所依赖的参数Act ...
- struts2 18拦截器详解(七)
ChainingInterceptor 该拦截器处于defaultStack第六的位置,其主要功能是复制值栈(ValueStack)中的所有对象的所有属性到当前正在执行的Action中,如果说Valu ...
- Struts2的运行流程以及关键拦截器介绍
Struts2的运行流程 1.ActionProxy是Action的一个代理类,也就是说Action的调用是通过ActionProxy实现的,其实就是调用了ActionProxy.execute()方 ...
- struts2-权限拦截器、日志拦截器、execAndWait(进度条)拦截器配置
1.权限拦截器 package login; import javax.servlet.http.HttpServletResponse; import org.apache.struts2.Serv ...
随机推荐
- dart中的typedef <函数别名>
typedef定义如下: typedef 给某一种特定的函数类型起了一个名字,可以认为是一个类型的别名.或者这样理解: 自己定义了一种数据类型,不过这种数据类型是函数类型,按照这种类型实例化后的对象, ...
- Seam科普
声明:这是引用的,具体引用位置在最下面. 只供个人学习,免得忘记了又要到处找,十分感谢原作作者.如果有什么问题请联系我. Seam框架开发一个HelloWrld的例子. Seam本身,而在于Seam使 ...
- hexo next主题深度优化(十),博文加密,不需要插件,极简模式,相对安全,融合pjax。
文章目录 效果: 代码: 注意: 背景: 思路: https://www.jianshu.com/p/90c0a15c6f36 http://zhailiange.com/2017/07/06/hex ...
- HDU-1852-Beijing 2008-一个神奇的公式求逆元
As we all know, the next Olympic Games will be held in Beijing in 2008. So the year 2008 seems a lit ...
- day 82 Vue学习三之vue组件
Vue学习三之vue组件 本节目录 一 什么是组件 二 v-model双向数据绑定 三 组件基础 四 父子组件传值 五 平行组件传值 六 xxx 七 xxx 八 xxx 一 什么是组件 首先给 ...
- Hibernate的Hello World!
一.创建Java工程,新建Lib文件夹,加入Hibernate和数据库(如MySql.Oracle.SqlServer等)的Jar包 二.创建 hibernate.cfg.xml 文件,并配置,配置项 ...
- Linux vi和vim编辑器(1)
1:vi和vim的三种常见模式 1.1正常模式 在正常模式下,我们可以使用快捷键: 以vim打开一个档案就直接进入一般模式了(这是默认的模式).在这个模式中,你可以使用[上下左右」按键来移动光标,你 ...
- (转)线程池 ExecutorService 详细介绍以及注意点区别
线程池 ExecutorService 相信java开发都用到,这里做个简单笔记 一 Java通过Executors提供四种线程池,分别为: newCachedThreadPool创建一个可缓存线程池 ...
- Caffe系列2——Windows10制作LMDB数据详细过程(手把手教你制作LMDB)
Windows10制作LMDB详细教程 原创不易,转载请注明出处:https://www.cnblogs.com/xiaoboge/p/10678658.html 摘要: 当我们在使用Caffe做深度 ...
- Axios的get和post请求写法
执行get请求 // 为给定 ID 的 user 创建请求 axios.get('/user?ID=12345') .then(function (response) { console.log(re ...