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

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值