`

jeecms的自定义的伪静态的实现分析

阅读更多

          jeecms是一个ssh+freemarker的优秀的cms系统,最近下载了一个版本装了一下,很不错,但是除了那一些自定义的freemarker标签外,还有些头大的事,就是很难查清楚它的自定义的伪静态的实现, htm是怎样对映到action上去的,最近花了几天看了一下,有点发现,记录下来.

       

          如下图, 点击一个article的标题,会弹出一个像是静态的url, 这个显然是要提交到一个action上的,但是怎么实现的呢?

        

http://localhost:8080/JEECMS/movie/38.htm

 

 

    查了一下每个aticle的静态页面,它的url都是有一定规则的,channel名加上article的id号,如果要分页还要加上一些附加的_*之类的url.

 

以下分析一下其大体的实现流程:

    首先看一下它的struts2的全局配置:

struts.action.extension=do,htm,jspa,jspx,php,asp,aspx
struts.objectFactory=spring
struts.enable.DynamicMethodInvocation=false
struts.devMode=true
struts.locale=zh_CN
struts.i18n.encoding=GBK
struts.ui.theme=simple
#struts.custom.i18n.resources=i18n
struts.ui.templateDir=/WEB-INF/template

#struts.multipart.saveDir=temp/
struts.multipart.maxSize=8388608
struts.enable.SlashesInActionNames=true

 第一个配置说明surfix 以do, html, jspa,jspx,php,asp,aspx结尾的url都被视为struts2的action处理,那么显然这个

htm结尾的是要当做action处理的了。

 

下面看一下这个url是如何对应到一个action的.

在com.jeecms.cms的下面有一个struts-core-front.xml的配置文件,定义如下:

这个<action name="**" class="core.dynamicSystemAct">很明显会载到namespace 为"/"的所有action.

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
	"-//Apache Software Foundation//DTD Struts Configuration 2.1//EN"
	"http://struts.apache.org/dtds/struts-2.1.dtd">
<struts>
	<!--动态系统-->
	<package name="core.front.dynamic" namespace="" extends="empty-default">
		<action name="**" class="core.dynamicSystemAct">
			<result type="chain">
				<param name="namespace">${namespace}</param>
				<param name="actionName">${actionName}</param>
			</result>
			<interceptor-ref name="startTime"/>
			<interceptor-ref name="exception"/>
			<interceptor-ref name="domain"/>
			<interceptor-ref name="cookieIdentity"/>
			<interceptor-ref name="url"/>
		</action>		
	</package>
	
	<package name="front.attachment" namespace="/front/attachment" extends="inde-default">
		<action name="Com_*" method="{1}" class="core.attachmentAct">
			<result name="edit">/WEB-INF/bbs_sys/topic/img.html</result>
		</action>
	</package>
</struts>

 

  由于是用的别名,在查到这个action后发现这个类实现了urlAware,如下, 这样它还会被一个UrlInterceptor的拦截器拦截,这个拦截器被设成struts2的default拦截器了, 在拦截器上打出了这个url请求的namespace 与action,确实附合动态系统action的条件, 通过UrlAware这个接口定义的方法,拦截器将一些url上的参数信息传给了action以进行动态处理,同时我也打出了DynamicSystemAct中生成的一些动态信息,如namespace与action.

package com.jeecms.common.struts2.interceptor;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.math.NumberUtils;
import org.apache.struts2.StrutsStatics;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.MethodFilterInterceptor;

/**
 * URL地址拦截器
 * 
 * 针对页面伪静态地址,需要传入多个参数
 * 
 * @author liufang
 * 
 */
public class UrlInterceptor extends MethodFilterInterceptor {
	private static final long serialVersionUID = 1L;

	@Override
	protected String doIntercept(ActionInvocation invocation) throws Exception {
		Object action = invocation.getAction();
		//check the name space.
		String namespace = invocation.getProxy().getNamespace(); 
		String actionname =invocation.getProxy().getActionName();
		if (!StringUtils.isBlank(namespace)) { 
            if ("/".equals(namespace.trim())) { 
               
            } else { 
                namespace += "/"; 
            } 
        } 
		System.out.println("namespace is "+namespace+"\n actionname is"+actionname);
		//=============
		
		ActionContext ctx = invocation.getInvocationContext();
		HttpServletRequest req = (HttpServletRequest) ctx
				.get(StrutsStatics.HTTP_REQUEST);
		if (action instanceof UrlAware) {
			
			System.out.println("UrlInterceptor active..");
			UrlAware aware = (UrlAware) action;
			String url = req.getRequestURL().toString();
			System.out.println("request url is:"+url);
			int pointIndex = url.indexOf('.', url.lastIndexOf('/'));
			if (pointIndex == -1) {
				url += "index.do";
				pointIndex = url.indexOf('.', url.lastIndexOf('/'));
			}
			String paramStr = req.getQueryString();
			if (paramStr != null && !paramStr.trim().equals("")) {
				url += "?" + paramStr;
			}
			aware.setWholeUrl(url);
			
			int lineIndex = url.indexOf('_', url.lastIndexOf('/'));
			int mlineIndex = url.indexOf('-', url.lastIndexOf('/'));
			// 前路径结束点
			int preIndex = 0;
			if (lineIndex != -1) {
				// 有下划线(有分页)
				preIndex = lineIndex;
			} else if (mlineIndex != -1) {
				// 有中划线(有定制参数)
				preIndex = mlineIndex;
			} else {
				// 什么都没有
				preIndex = pointIndex;
			}
			aware.setPageLink(url.substring(0, preIndex));
			// 后路径开始点
			int suffixIndex = 0;
			if (mlineIndex != -1) {
				// 有中划线
				suffixIndex = mlineIndex;
			} else {
				suffixIndex = pointIndex;
			}
			aware.setPageSuffix(url.substring(suffixIndex));
			// 取页数和附加参数
			if (preIndex == suffixIndex) {
				// 没有分页,为第一页。
				aware.setPageNo(1);
			} else {
				// 去掉下划线"_"。
				String page = url.substring(preIndex + 1, suffixIndex);
				aware.setPageNo(NumberUtils.toInt(page, 1));
			}
			// 路径参数
			String pathParm = ctx.getName();
			lineIndex = pathParm.indexOf("_");
			mlineIndex = pathParm.indexOf("-");
			if (lineIndex != -1) {
				pathParm = pathParm.substring(0, lineIndex);
			} else if (mlineIndex != -1) {
				pathParm = pathParm.substring(0, mlineIndex);
			}
			aware.setPathParams(pathParm.split("/"));
			// 附加参数
			if (mlineIndex != -1) {
				String otherParam = ctx.getName().substring(mlineIndex + 1);
				aware.setOtherParams(otherParam.split("-"));
			}
			//System.out.println(TypeUtil.typeToString("UrlAware--:\n",aware));
		}
		//----------test the url interceptor------//
		else
		{
			System.out.println("UrlInterceptor ignored..");
			
		}
		return invocation.invoke();
	}
}

 

 

  

 

 

package com.jeecms.cms.action;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;

import com.jeecms.common.struts2.interceptor.DomainNameAware;
import com.jeecms.common.struts2.interceptor.UrlAware;
import com.jeecms.core.Constants;
import com.jeecms.core.entity.Website;
import com.jeecms.core.manager.WebsiteMng;
import com.opensymphony.xwork2.Action;

@Scope("prototype")
@Controller("core.dynamicSystemAct")
public class DynamicSystemAct implements Action, DomainNameAware, UrlAware {
	public String execute() {
		System.out.println("comming into DynamicSystemAct");
		Website web = websiteMng.getWebsite(domainName);
		if (web == null) {
			// 检查别名
			web = websiteMng.getByAlias(domainName);
			if (web != null) {
				redirectUrl = web.getWebUrl();
				return Constants.REDIRECT;
			} else {
				return Constants.WEBSITE_NOT_FOUND;
			}
		}
		String sys = web.getCurrentSystem();
		namespace = "/jeedynamic/" + sys;
		actionName = "Page";
		System.out.println("DynamicSystemAct namespace is "+namespace+"\n actionname is"+actionName);
		return SUCCESS;
	}

	private String namespace;
	private String actionName;
	private String pageName;
	private String pathName;
	private String domainName;

	private String[] pathParams;
	private String[] otherParams;
	private String wholeUrl;
	private String pageLink;
	private String pageSuffix;
	private int pageNo = 1;

	private String redirectUrl;
	@Autowired
	private WebsiteMng websiteMng;

	public void setDomainName(String domainName) {
		this.domainName = domainName;
	}

	public void setPathParams(String[] pathParams) {
		this.pathParams = pathParams;
	}

	public void setPageNo(int pageNo) {
		this.pageNo = pageNo;
	}

	public void setPageLink(String pageLink) {
		this.pageLink = pageLink;
	}

	public void setPageSuffix(String pageSuffix) {
		this.pageSuffix = pageSuffix;
	}

	public void setWholeUrl(String wholeUrl) {
		this.wholeUrl = wholeUrl;
	}

	public String getNamespace() {
		return namespace;
	}

	public void setNamespace(String namespace) {
		this.namespace = namespace;
	}

	public String getActionName() {
		return actionName;
	}

	public void setActionName(String actionName) {
		this.actionName = actionName;
	}

	public String getPageName() {
		return pageName;
	}

	public void setPageName(String pageName) {
		this.pageName = pageName;
	}

	public String getPathName() {
		return pathName;
	}

	public void setPathName(String pathName) {
		this.pathName = pathName;
	}

	public String getDomainName() {
		return domainName;
	}

	public String[] getPathParams() {
		return pathParams;
	}

	public String getWholeUrl() {
		return wholeUrl;
	}

	public String getPageLink() {
		return pageLink;
	}

	public String getPageSuffix() {
		return pageSuffix;
	}

	public int getPageNo() {
		return pageNo;
	}

	public String getRedirectUrl() {
		return redirectUrl;
	}

	public void setRedirectUrl(String redirectUrl) {
		this.redirectUrl = redirectUrl;
	}

	public String[] getOtherParams() {
		return otherParams;
	}

	public void setOtherParams(String[] otherParams) {
		this.otherParams = otherParams;
	}
}

 
综合上面的信息,再查page这个action,在发现com.jeecms.cms.struts-font.xml中发现了它的定义.

 

<package name="cms.front.page" namespace="/jeedynamic/jeecms" extends="empty-default">		
		<action name="Page" class="cms.cmsPageAct">
			<result>${tplPath}</result>
			<result name="pageCache" type="pageCache">${tplPath}</result>
			<interceptor-ref name="exception"/>
			<interceptor-ref name="chain"/>
		</action>
	</package>

  由此最终指向了一个模板.真是山路十八弯啊.

 

 

  • 大小: 43.4 KB
  • 大小: 9.4 KB
分享到:
评论
3 楼 wkcgy 2011-04-17  
楼主辛苦了!!
2 楼 a123456603 2011-03-02  
有没有qq的联系一下
1 楼 ningzhisheng 2010-07-26  
最近也在学习jeecms,谢谢分享!

相关推荐

    jeecms3.0.4

    在设计上自身预先做了搜索引擎优化,增强对搜索引擎的友好性 ,采用伪静态页面技术,可自定义路径结构,无需urlrewrite ,轻松建设大规模网站,可通过次级域名建立子站群,各子站后台管理权限分离,全站实现单点登录。

    jeecms开发指南v1.0.pdf

    Jeecms的一个重要特点是其模板机制,它允许用户无需深入理解Java或JSP,仅通过掌握HTML和Jeecms自定义标签就能进行页面设计。系统提供了两种风格的标签:一种封装了常见显示样式,便于快速生成动态效果,如文章列表...

    jeecms-2.4.2(源码+安装包)

    JEECMS是国内Java版开源网站内容管理系统(java cms、jsp ...· 采用伪静态页面技术,可自定义路径结构,无需urlrewrite · 轻松建设大规模网站,可通过次级域名建立子站群,各子站后台管理权限分离,全站实现单点登录

    jeecms开发指南

    此外,Jeecms 自然支持伪静态页面技术,优化了SEO,可自定义页面后缀,满足不同需求。 综上所述,Jeecms 以其开源、灵活、高效和易用性,成为了JavaEE领域内一个强大的内容管理系统。无论是小型网站还是大型的站群...

    JEECMS v2.2 beta 贺岁版

    采用伪静态页面技术,可自定义路径结构,无需urlrewrite 轻松建设大规模网站,可通过次级域名建立子站群,各子站后台管理权限分离,全站实现单点登录 JEECMS v2.2 beta版对以下方面进行了更新: ·降低运行环境...

    jeecms-src.rar_com.jeec_freemarker_freemarker struts2_单点登录

    JEECMS是JavaEE版网站管理系统(Java Enterprise Edition Content...采用伪静态页面技术,可自定义路径结构,无需urlrewrite 轻松建设大规模网站,可通过次级域名建立子站群,各子站后台管理权限分离,全站实现单点登录

    JEEcms目前国内的cms领跑者

    JEECSM是JavaEE版网站管理系统(Java Enterprise Edition ...·采用伪静态页面技术,可自定义路径结构,无需urlrewrite ·轻松建设大规模网站,可通过次级域名建立子站群,各子站后台管理权限分离,全站实现单点登陆!

    JEECMS 2.3.1 Beta 系统程序

    采用伪静态页面技术,可自定义路径结构,无需urlrewrite 轻松建设大规模网站,可通过次级域名建立子站群,各子站后台管理权限分离,全站实现单点登录 JEECMS v2.3.1版于2009年3月23日发布,这是JEECMS自发布以来...

    JEECMS v2.3.2 正式版用源码

    JEECMS是JavaEE版网站管理系统(Java Enterprise Edition Content...采用伪静态页面技术,可自定义路径结构,无需urlrewrite 轻松建设大规模网站,可通过次级域名建立子站群,各子站后台管理权限分离,全站实现单点登录

    JEECMS3.0.4使用教程

    JEECMS的设计注重SEO(搜索引擎优化),通过伪静态页面技术和自定义路径结构,增强了对搜索引擎的友好性,有助于提升网站在搜索结果中的排名。 **一、JEECMS3.x 安装** 1.1 安装、配置运行环境准备 在开始安装...

    jeecms开发指南v1.0.docx

    为了提升搜索引擎优化(SEO),Jeecms内置了伪静态页面技术,URL以.htm为后缀,路径结构扁平且可自定义。同时,系统支持站群设计,通过次级域名创建子站群,实现权限分离和单点登录,适应大规模网站的构建需求。 ...

    JEECMS2012系统使用手册2012-07美化版(pdf格式)

    6. **伪静态页面缓存**:通过伪静态技术实现缓存,提升访问速度的同时保持良好的用户体验。 7. **扩展性强**:支持通过次级域名建立多个子站点,并且这些子站点可以拥有独立的后台管理权限。 #### 二、环境搭建 ...

    jeecmsv2.3.2 内容管理系统 (hibernate3+struts2+spring2+freemarker)

    JEECMS是JavaEE版网站管理系统(Java Enterprise ...· 采用伪静态结合页面缓存技术,可自定义路径结构,无需urlrewrite · 轻松建设大规模网站,可通过次级域名建立子站群,各子站后台管理权限分离,全站实现单点登录

    jee cms学习文档

    · 采用伪静态页面缓存技术,管理方便,速度可与静态页面相媲美,用户自定义路径结构,无需urlrewrite · 轻松建设大规模网站,可通过次级域名建立子站群,各子站后台管理权限分离,全站实现单点登录

    hibernate3+struts2+spring2+freemarker 主流技术架构 实例

    包括: +----doc +-----jeecms基础概念.txt ...• 采用伪静态结合页面缓存技术,可自定义路径结构,无需urlrewrite • 轻松建设大规模网站,可通过次级域名建立子站群,各子站后台管理权限分离,全站实现单点登录

    内容管理系统CMS20091214.doc

    JEECMS 设计时考虑了搜索引擎优化,采用了伪静态页面技术,支持子站点的建立,实现了全站单点登录。其最新版本 v1.1 beta 增加了诸如文章评论、文章导航等功能,提升了用户体验。 dotCMS 是另一个基于 Java 的 CMS ...

Global site tag (gtag.js) - Google Analytics