website使用组件(页面片段)进行编程,提供组件复用性。website前端提供页面布局、主题内容展示、页面片段加载,后端负责页面渲染。website同时提供缓存机制,支持Redis或Memcached等。
website的前端主要基于三种组件:Layout、Screen、Widget
每个页面对应一个页面处理类,必须实现ViewHandler接口。页面处理类必须实现execute方法。如果页面没有对应的页面处理类,则直接渲染页面。
form表单处理
页面代码reg.jsp
<form action="${fn:getLink('reg.jsp') }" method="post">
<input type="hidden" name="action" value="register"/>
<input type="submit" value="提交" />
</form>
页面处理类代码Reg.java
public void actRegister() {
System.out.println("注册");
}
form中的隐藏字段定义页面处理类对应的处理方法。
ajax请求处理
页面reg.jsp
$.ajaxLoad({
//请求的url为xxx.do,后面带一个method的参数
url:"${fn:getLink('reg.do?method=getData')}",
callback:function(data) {
alert(data.data);
},
dataType:"json",
type:"post"
});
页面处理类reg.java
public void doGetData() {
HttpServletResponse response = ContextHolder.getResponse();
response.getWriter()
.write("{data:\"收到getData请求\"}");
}
Website配置
frame.properties
#自定义错误信息
global.ERRCSRF=非法操作,提交数据不安全或者重复提交
global.ERRNOSC=请求地址对应的资源文件不存在$1
global.ERRNFSC=内部跳转地址对应的资源文件不存在$1
global.ERRELLP=内部地址跳转存在闭合的死循环$1
global.ERR0501=请求路径或参数中存在非法字符
global.ERR0502=尚未登录或登录已失效
global.ERR0503=非法操作归属性资源
global.ERR0504=登录失败!未获取到有效的SAML数据信息
#用以防止重复提交表单的参数设置
global.CRSFTokenName = __hash__
global.CRSFSignName = __hashsign__
#需要过滤的特殊字符-securityFilter
global.xss = (((%3D)|(\=))[^\n]*((%27)|(')|(--)|(%3B)|(\:)|(%23)|(\#)))|(\\w*((%27)|('))((%6F)|o|(%4F))((%72)|r|(%52)))|(exec((\\s)|(%20))+(s|x)p\\w+)|((<|%3c)/?(script|iframe|frame|body|img))|(set-cookie)|(src\=('|")javascript\:)|(Content-\\w+\:)
#哪些不需要经过安全过滤器securityFilter
security.whiteList=
#默认主题设置,为空则为默认(default)主题
frame.theme=
#运行时设置主题的参数名
frame.theme.paramKey=_THEME_
#---URL重写设置---#
#如
#http://127.0.0.1:80/uc/index.htm?_PATH_=sn/100720
#重写后为
#http://127.0.0.1:80/uc/sn/100720/htm/index.htm
#设置是否开启URL重写,如不需要可设为off或0
frame.rewrite=off
#设置URL重写上下文和原页面上下文之间的间隔符
frame.rewrite.spacemark=htm
#设置重写path的参数名称
frame.rewrite.pathmark=_PATH_
#模板文件配置。配置方式为文件的后缀名(以英文逗号间隔),配置顺序即模板优先查找顺序
frame.template=ftl,jsp
#freemarker模板下自定义标签,配置方式为[前缀]:[实现类]
#多个自定义标签之间以分号相隔
#如ifn:org.loushang.internet.util.el.Function
frame.ftltags=
modules.properties
#模块的访问上下文
home.context=
#模块的处理类的包路径
home.package=org.website.pages
#模块的页面路径(通常定义为当前模块名即可)
home.viewPath=home
#模块下页面是否允许缓存
home.allowCache=false
Website主题
项目根目录下定义themes目录,用于存放主题。themes目录必须包含default目录。
页面处理类对应的目录结构
website项目依赖
internet-core.jar:WebSite框架的核心jar包
rtf.jar:告诉服务框架所需要的jar,依赖netty-3.2.7.Final.jar等外部包
spring-2.5.6.SEC02.jar:Srping框架所需的jar,Website框架是在Spring框架基础上进行开发的,其中对于XML文件读取、对iBatis的支持等都基于Spring框架
memcached.jar:缓存框架Memcached所需的jar
zookeeper-3.3.2.jar和iopzookeeper.jar:为方便项目在正式环境上发布时统一配置
jackson-all-1.9.6.jar:json所需的jar
Website项目部署
配置web.xml
定义页面监听器
<listener>
<listener-class>
com.inspur.hsf.config.ContextLoaderListener
</listener-class>
</listener>
定义请求分发过滤器
<filter>
<filter-name>webDispatcher</filter-name>
<filter-class>
org.loushang.internet.servlet.WebDispatcherFilter
</filter-class>
<init-param>
<param-name>excludes</param-name>
<param-value></param-value>
</init-param>
<init-param>
<param-name>encode</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>fromEncode</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>webDispatcher</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>INCLUDE</dispatcher>
</filter-mapping>
自定义标签库
<jsp-config>
<taglib>
<taglib-uri>/tags/website</taglib-uri>
<taglib-location>/WEB-INF/classes/website.tld</taglib-location>
</taglib>
<taglib>
<taglib-uri>/tags/website-function</taglib-uri>
<taglib-location>/WEB-INF/classes/function.tld</taglib-location>
</taglib>
</jsp-config>
配置modules.properties
#zookeeper要求的配置
app.conf=website/modules
#配置模块
home.context=
home.viewPath=home
home.package=com.xsm.home
home.allowCache=false
安全配置
定义安全过滤器
<filter>
<filter-name>securityFilter</filter-name>
<filter-class>org.loushang.internet.filter.SecurityFilter</filter-class>
<init-param>
<param-name>encode</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>fromEncode</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>securityFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
定义安全过滤规则
#需要过滤的特殊字符-securityFilter
global.xss = (((%3D)|(\=))[^\n]*((%27)|(')|(--)|(%3B)|(\:)|(%23)|(\#)))|(\\w*((%27)|('))((%6F)|o|(%4F))((%72)|r|(%52)))|(exec((\\s)|(%20))+(s|x)p\\w+)|((<|%3c)/?(script|iframe|frame|body|img))|(set-cookie)|(src\=('|")javascript\:)|(Content-\\w+\:)
#哪些不需要经过安全过滤器securityFilter
#配置规则参考login.properties中的 whiteList
security.whiteList=
定义登录过滤器
<filter>
<filter-name>loginFilter</filter-name>
<filter-class>org.loushang.internet.filter.LoginFilter</filter-class>
<init-param>
<!-- 需要被“排除”的URL路径,以逗号分隔,如/static, *.jpg。适合于映射静态页面、图片。 -->
<param-name>excludes</param-name>
<param-value>*.jpg,*.jsp,*.ico,*.css,*.html,*.png,*.js,*.gif,*.swf</param-value>
</init-param>
<init-param>
<param-name>encode</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>fromEncode</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>loginFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>INCLUDE</dispatcher>
</filter-mapping>
定义登录配置
#黑白名单的配置方式依赖于简单的正则语法
login.blackList=trade/*,govc/*,comment/bsfwComment,open/AppAdminAction.*
login.whiteList=trade/*
#单点登录获取用户信息的对应的bean login.User
login.userImpl = login.User
#单点登录判断是否登录对应的bean login.Passport.Cookie/login.Passport.Saml
login.passportImpl = login.Passport.Saml
#登录跳转地址
#cookie方式的登录跳转地址
global.sso.loginUrl = http://uc.iop.com/login/login.htm
#saml方式的登录跳转地址
#global.sso.loginUrl = http://uc.iop.com/login/login.do?method=samlsso
#注销地址
global.sso.logoutUrl = http://uc.iop.com/index/index.do?method=logoutAll
#注册地址
global.sso.regUrl = http://uc.iop.com/index/signup.htm
#共享cookie单点登录key名称,可选值 uc_uid(适配旧加密算法),和 sso_token(适配新加密算法)
cookie_sso_key=uc_uid
配置loginfilter.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean id="login.User"
class="org.loushang.internet.filter.login.User">
</bean>
<bean id="login.Passport.Cookie"
class="org.loushang.internet.filter.login.PassportCookie">
</bean>
<bean id="login.Passport.Saml"
class="org.loushang.internet.filter.login.PassportSaml">
</bean>
</beans>
SAML登录配置
在module.properties定义新的模块filter
filter.context=filter
filter.package=org.loushang.internet.filter.pages
filter.viewPath=filter
主题过滤器
<filter>
<filter-name>themeBindingFilter</filter-name>
<filter-class>
org.loushang.internet.filter.ThemeBindingFilter
</filter-class>
<init-param>
<param-name>excludes</param-name>
<param-value>
*.jpg,*.css,*.html,*.jsp,*.png,*.js,*.gif,*.swf,*.ico
</param-value>
</init-param>
<init-param>
<param-name>encode</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>fromEncode</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>themeBindingFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>INCLUDE</dispatcher>
</filter-mapping>
过滤器顺序
<filter-mapping>
<filter-name>securityFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 登录过滤器 mapping -->
<filter-mapping>
<filter-name>loginFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>INCLUDE</dispatcher>
</filter-mapping>
<!-- 主题设置过滤器 mapping -->
<filter-mapping>
<filter-name>themeBindingFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>INCLUDE</dispatcher>
</filter-mapping>
<!-- 请求分发过滤器 mapping -->
<filter-mapping>
<filter-name>webDispatcher</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>INCLUDE</dispatcher>
</filter-mapping>