JDAPP开发指南:遵循信息化建设的内在规律,提倡循序渐进学习方法,先易后难的实现过程方式;确保项目按时完成的上线目标,先把容易的功能开发实现,遇到技术难点放置后面实现。
JDAPP设计理念:学习门槛低,开发效率高,开发周期短,简单易管理;代码可重用性极高,可积累性,可复用性,可移植性高;架构高可用性,投产后可持续集成,风险可控性,运行稳定。
JDAPP设计原则:可拆分可合并原则,模块化原则,集中管理原则,团队分层组合原则,同一项目异地城市组合团队开发原则,适用于千人开发团队并行开发。
JDAPP框架概要:整体设计划分为三层:WEB展示层/JAVA逻辑层/数据层;高可用架构,SESSION共享,集群后缓存数据持久,内置站群功能,强大的SEO优化设计思想,资源文件分布式存取,在eclipse零秒完成启动。
| 
 | 
JDAPP是一套基于Java Servlet API的通用Web框架,是一套专业为电商平台后端服务器支撑系统而设计的JAVA应用框架。
运行在标准Servlet引擎,搭建JDAPP开发出来的应用可以运行在标准的Java2EE应用服务器:Jetty、Tomcat、Resin、Weblogic、JBoss、GlassFish、IBM Websphere、Sun Application Server 。。。框架编写的代码兼容在jdk1.5或以上版本的硬件设备。
JDAPP是基于经典MVC设计模式的WEB框架,并且在MVC的基础上进行升级为多种控制器(multi controller),多种模型(multi model),多种视图(multi view)的设计模式,称为多模型、视图、控制器:Multi model view controller ,简称MMVC设计模式。
JDAPP框架重构Servlet的HttpServletRequest类之后,框架提供千万个域名维护管理功能,并且可以指定域名站点选择不同的模板和风格。任意一个域名可以指定使用不同的java应用模型和web应用目录,而且应用模板语言和应用扩展名可以定制选择。
2008年想找一套能够解决大型Web项目的开发框架,要求框架设计的简单易用。JDAPP在综合Xwork、Webwork2、Spring、Struts、Tapestry等等框架和开源JAVA论坛jforum系统设计思想后而设计的一套框架。
2010年命名为简单应用的jdapp框架跟随电子商务平台BYOOU搜索引擎一起完善实现。
2014年使用JDAPP框架在XenServer云计算IAAS基础设施即服务稳定运行至今,提供PAAS平台服务应用开发及SAAS网络软件应用开发,并把JDAPP框架落户在云基地 www.yunjd.net 的平台上,重命名为:基地应用框架,英文名:JDAPP Framework。
JDAPP框架里并没有太多的技术术语,设计上初衷于让学者用JAVA语言做WEB服务应用开发的学习门槛降到最低。
如果你从事过ASP工程师或PHP工程师,可以轻松学会使用,框架是运行在强大的JAVA技术平台上。 如果你完全是一名新学员,有兴趣,哪怕你只有初中毕业水平,数学和英文课程毕业考试过70分花费一周时间都可以入门。
框架有多个已上线运营的大型电商项目,项目测试案例实践证明框架已运行在可持续集成之“自动化部署”,LVS+Keepalived高性能高可用负载均衡服务,tomcat应用服务器接入分布式缓存memcache实现session共享,JBossCache缓存技术集群系统的等等应用服务。
JDAPP框架针对电子商务平台设计,框架在运行时就有依赖于数据库,启动时就会加载相关的数据表,并非单纯的xml配置文件。
框架除了包括基本的功能模块:日志输出、数据缓存、jdbc数据连接等等,设计思想上具有以下功能特性:
1、缓存集群:缓存接口兼容复制式事务处理缓存JBossCache,解决了应用服务器在集群环境中的数据不一致的问题,使框架具备高可用性、准确性、可扩展性、可移植性及系统整体性能的提升。
2、统一数据类型:在JDBC数据库连接统一设计了一套数据类型转换工厂,连接MySql、ORACLE、SQLServer、Informix等等不同的数据库,不同的版本在存取数据变得更简单。
3、简化开发:在HttpServletRequest请求结束时ActionContext也会自动把当前会话中数据工厂上的所有数据连接释放掉,在框架存取数据变得更简便,有效减少开发代码量。
4、日志管理:提供日志接口,支持Log4日志输出,默认日志功组件在eclipse开发时日志会打印在控制面板Console窗口下面,点击打印出来的Java类名可以直接连接定位到Java文件内容中的日志输出方法指标。
5、缓存存储:框架把模型,视图,控制器的实例内容编码和实现类都存储在数据库,并在系统启动时加载到缓存容器里,设计思路上实现统一控制台系统进行轻松管理不同子系统的功能。
6、应用模型:模型编码的结构组成是根据:(一级目录.二级目录.目录层数:国家代码.机构简码-团队简码)完成设计,目的是为了通过查看模型编码即可以了解到它的用途。
7、应用模板:默认使用freemaker模板引擎,支持服务器端包含SSI(Server Side Include)网页技术处理,具备良好的扩展性,例如支持通过quercus实现PHP语言模板,支持扩展velocity模板引擎,其它语言的CGI应用模板引擎等等,但默认不支持JSP。
8、控制器:框架上的模型属性可以配置为任意选择不同的控制器,控制器不仅实现了功能模块和显示模块的分离,同时还提高了应用的可复用性、通用性、可扩展性、易用性。
9、规范处理:对框架的异常抛出做了命名规范输出处理,并可以指定java异常类型编号,输出的异常工程师都可以通过日志找出异常原因所在位置。
10、会话封装:SessionHandler重构HttpSession后,框架对用户访问的Session进行重新加工和规范,使得访问用户变得更易于管理。
11、站群的支持:RequestHandler重构HttpServletRequestWrapper后,框架可以根据用户访问的路径载入缓存中的域名实例,设计上实现了多域名multisite功能。
12、上传资源处理:规范公共的上传资源接后,工程师可以简单配置模型和编写表单网页即可实现单个或多个资源文件上传。
13、SEO优化:由于模型的设计是绑定在用户访问的路径上,并且可以指定路径符号是由反斜杠(/)或差号(-)实现,使得路径的目录层数变得更简短和应用网页的扩展名可任意定义的特性,从而达到SEO优化效果。
14、DNS解释组件:框架整合xbill的dns作为组件功能,用户修改网络连接设置首DNS服务器为127.0.0.1,即可以访问用户定义在框架上存储在数据库的域名。
16、FTP组件:框架整合apache的fptserver作为组件james,用户在后台增加一条相关账号和域名关联的FTP连接记录即可实现指定的账号访问的域名空间。
17、安全指标:框架带有MD5加密和SHA加密方式,配置文件的数据库连接密码使用SHA加密,使框架上的应用具备很好的安全性支持。
18、健壮体系:框架运行于Java EE应用服务器上,使用的是JAVA语言开发,JDK具备良好的稳定性、准确性、安全性、可维护性、兼容性、可重用性、易用性等等技术指标。
19、简易配置:抛开了类似spring或struts2繁琐的配置设计,只保留了一个基本的设置文件jdapp.xml,应用服务器的加载的web.xml只有简单的几配置好可以,JDAPP需要加载数据库表相关设置才能完成启动。
20、持续集成:在同一应用服务器上的每个网站都可以划分前台应用和后台应用划分,在五套工作环境:开发环境、集成测试环境、用户验收环境、生产环境、办公环境可以完美设计为可持续集成之“自动化部署”。
现在有太多Java的Web框架,不但免费还是开源的。开源中国社区就有几百款WEB框架介绍,例如,
Spring MVC - http://spring.io/
Webwork - http://www.opensymphony.com/webwork/
Struts - http://struts.apache.org/
Tapestry - http://tapestry.apache.org/
Webx - http://www.openwebx.org/
⋯⋯
以上框架都是非常优秀,每一种框架采用不同的设计,必然会有各自的优势,最大的区别是JDAPP有针对站群功能做了独特的设计。
以上框架一般是适用于做普通的应用系统,JDAPP是针对大型的电商平台而设计的框架,适用于千人开发团队并行开发。
JDAPP框架的WEB应用提交到版本库即可以在测试环境显示效果,JAVA应用可以实现动态加载类。
JDAPP框架的服务器与微软的IIS最大的区别在于:IIS可以维护管理几十个网站,但如果有千百个网站IIS就无法管理,主要是没有网站分页管理和占用内存。
框架不众同之处:基于数据库管理域名,应用模型,模板;平台级的架构,可管理百万个域名,具有RewriteRule模式的模块设计,带SEO和ALEAX优化设计。
框架除了要求个人的技术能力强之外,更加强调团队合作能力与作战能力。JDAPP框架为标准IT企业技术部门角色人员协同工作而设计了一套与军团角色做对比的技术岗位。
军团 IT企业技术部门
司令 总经理 军长 技术总监 师长 首席架构师 旅长 项目经理 技术经理 团长 项目开发A组(Teams A) 产品测试B组(Teams B) 营长 架构师 技术专家 资深开发工程师 JAVA工程师 DBA工程师 功能测试工程师 连长 产品经理 WEB工程师 前端开发工程师 互动设计师 数据分析师 性能测试工程师 排长 技术培训讲师 技术支持 系统集成工程师 运维工程师 技术行政助理 安全测试工程师 工兵 一般职级划分: 见习工程师 初级工程师 中级工程师 高级工程师
以上技术岗位角色列表中,你希望是从事那个岗位,加入技术团队后,人事部门会对你的职位职能职责做个初步评定,并列出KPI考核案提交到你的上师。
本框架在任职资格的工程师划分为程序开发能力:PG1-9、设计能力:DS1-9、架构能力:AD1-9、系统分析能力:AS1-9
JDAPP框架提供学习环境项目jdapp-study-1.0.0.zip搭建、开发环境项目jdapp-dev-1.0.0.zip搭建、测试环境项目jdapp-test-1.0.0.zip搭建、生产环境项目jdapp-pro-1.0.0.zip搭建、办公环境项目jdapp-office-1.0.0.zip搭建
现在可以登录网址http://jdapp.yunjd.net/下载最新版本,也可以点击下载链接直接下载学习版本:jdapp-study-1.0.0.zip
注:目前框架项目只提供部分源代码下载
把下载回来的jdapp-study-1.0.0.zip压缩包解压到任意目录,最好路径不要带中文。打开eclipse应用程序,点击菜单File->Import,
      在Import对话框里双击General菜单下的Exitsting Project into Workspace
       
            
运行应用程序:
      右击RunServer.java->Run As->Java Application
      
      
      在eclipst的控制窗口可以看到启动后的日志输出:
   
      
打开域名回送地址(127.0.0.1)默认存储目录:WebContent\WEB-INF\domains\frontend\store\127.0.0.1\webapp
实例1、增加一个freemarker模板引擎WEB应用文件取名为:first.htm
      WEB应用代码内容如下:
      
<h1>${_html.request.getParameter("q")?default("Not Found")}</h1> 
      
      实例2、增加一个PHP应用程序文件取名为:first.php
      PHP代码内容如下:
      
<?php phpinfo(); ?>
 
      
      【注】web应用指的是不需要编译应用源代码,java应用指的是需要把java应用文件编译为class文件后才可以运行的。
JDAPP框架【简单开发学习版】默认目录结构如下:
JDAPP-study
│  .classpath
│  .project
│  MIT-LICENSE.txt
├─.settings
│      org.eclipse.core.resources.prefs 
├─lib------------------------------------------------------------------- jetty应用服务器加载的相关JAR包
│  ├─jetty
│  │      jetty-6.1.26.jar
│  │      jetty-sslengine.jar
│  │      jetty-util-6.1.26.jar
│  │      slf4j-api-1.5.8.jar
│  │      slf4j-log4j12-1.5.8.jar
│  ├─logs
│  │      commons-logging-api.jar
│  │      commons-logging.jar
│  ├─cluster
│  │      bsf-2.4.0.jar
│  │      c3p0-0.9.1.jar
│  │      cglib-2.1.jar
│  │      commons-beanutils.jar
│  │      commons-codec-1.6.jar
│  │      commons-collections-3.0.jar
│  │      commons-httpclient-3.0.1.jar
│  │      commons-lang-2.0.jar
│  │      dom4j-1.6.1.jar
│  │      jaxen.jar
│  │      jboss-common-core.jar
│  │      jboss-logging-spi.jar
│  │      jboss-transaction-api.jar
│  │      jbosscache-core.jar
│  │      jbossjta.jar
│  │      jdom.jar
│  │      jgroups.jar
│  │      mail-1.4.1.jar
│  │      mina-core-2.0.4.jar
│  │      mysql-connector-java-5.0.4-bin.jar
│  │      slf4j-api-1.4.3.jar
│  │      slf4j-log4j12-1.4.3.jar
│  │      transactions-essentials-all.jar
│  └─servlet
│          servlet-api.jar
├─src------------------------------------------------------------------- 项目源代码目录
│      commons-logging.properties
│      log4j.properties
│      log4jserver.properties
└─WebContent------------------------------------------------------------ JAVA应用默认目录
    ├─WEB-INF
    │  │  web.xml
    │  ├─classes
    │  │      commons-logging.properties
    │  │      log4j.properties
    │  │      log4jserver.properties 
    │  ├─conf
    │  │      jdapp.xml ------------------------------------------------ JDAPP加载的配置文件
    │  ├─var
    │  │  └─h2-db------------------------------------------------------- H2数据存储目录
    │  │     		 jdapp.mv.db
    │  │     		 jdapp.trace.db
    │  ├─domains-------------------------------------------------------- 应用服务器域名存储目录
    │  │  ├─backend----------------------------------------------------- 管理后台存储目录
    │  │  └─frontend---------------------------------------------------- 域名默认是加载前台存储目录
    │  │      └─store--------------------------------------------------- 默认的域名内容存储柜
    │  │          └─127.0.0.1------------------------------------------- 访问http://127.0.0.1/ 网址时会加载该域名的相关数据
    │  │              └─webapp------------------------------------------ 域名127.0.0.1的WEB应用目录
    │  │                      index.htm
    │  ├─lib------------------------------------------------------------ JAR包目录
    │  │      freemarker-2.3.10.jar
    │  │      jdapp-core-0.3.0.jar-------------------------------------- JDAPP类的核心包
    │  │      log4j-1.2.12.jar
    │  │      h2-1.4.182.jar 
    │  ├─logs----------------------------------------------------------- 默认分四级日志为:Debug,Info,Warn,Error;log4j还包括Fatal
    │  │      debug.log------------------------------------------------- 调度日志
    │  │      info.log-------------------------------------------------- 普通日志
    │  │      warn.log-------------------------------------------------- 警告日志
    │  │      error.log------------------------------------------------- 错误日志
    │  └─paas----------------------------------------------------------- 平台下通用的模板存储位置
    ├─apptpl------------------------------------------------------------ 域名localhost后台数据存储目录
    └─webapp------------------------------------------------------------ 可以通过http://localhost/ 网址访问目录下相应的应用文件
            index.htm--------------------------------------------------- 网站默认页
                
      JDAPP默认使用Freemarker作为WEB应用引擎,Freemarker版本为2.3.10;其次PHP应用引擎为quercus组件,版本为4.0.39。
每个域名都拥有属于自己的站点存储空间,通过修改数据表DOMAIN的EXTENSIONS字段值设定不同模板引擎解释权限。也可以通过后台修改网站的WEB应用语言支持。
目前框架支持SSI,Freemarker,PHP三类语言,默认为Freemarker。

域名修改处有一个支持扩展名(后辍)下有:A.(静态) B.(动态) C.(html) D.[htm] E.[php] F.(C+D) G.(C+D+E),A静态代表不作任何语言解释,B动态表示有缓存情况,C选项支持SSI,D支持freemarker引擎,E支持PHP引擎。
在Freemarker引擎会加载一个变量名为:_html,并把ActionContext接口APage设定为_html的值。编写Freemarker的工程师即可以通过_html取得ActionContext里的所有内容,包括request,response,session等等。
除了_html还有__to和out两个变量,_out变量使用的是 jdapp.mmvc.page.help.OutHelp类,而_to变量使用的是jdapp.mmvc.page.help.VariantHelper类,_out和_to可以直接使用对应类的方法。
而且使用Freemarker模板引擎的WEB可以通过Static方法直接调用JAVA静态类。
      
下面写个Freemarker应用测试,取名为:test.htm
      编写的test.htm代码内容如下:
      
当前整个路径:${_html.request.thisPath}<br/>
虚拟根路径:${_html.request.uri}<br/>
网址路径:${_html.request.url}<br/>
模型URI:${_html.request.coreModelUri}<br/>
路径信息:${_html.request.pathInfo}<br/>
参数:${_html.request.query}<br/>
后辍:${_html.request.mime}<br/>
页面输出字符:${_html.request.characterEncoding}<br/>
域名:${_html.request.domain.dns}<br/>
会话账号:${_html.session.account}<br/>
<!-- 调用java类Log.java静态方法--><br/>
在控制台打印当前整个路径
<#assign Log=Static["jdapp.log.Log"]/>
<#assign thisPath=_html.request.thisPath /><br/>
${thisPath}
${Log.debug(thisPath)}
<br/>
<!-- 调用java类UuidUtils.java相关静态方法--><br/>
输出几种UUID值<br/>
<#assign UuidUtils=Static["jdapp.util.UuidUtils"]/>
UUID32位《${UuidUtils.getRandomGUID()}》<br/>
UUID符号《${UuidUtils.getSerialNumber().replaceAll('-','')}》<br/>
UUID串号《${UuidUtils.getSerialNumber()}》<br/>
Jetty会话《${UuidUtils.getSessionId()}》<br/>
定单编号《${UuidUtils.getTableId()}》<br/>

下面写个PHP应用测试:
      创建一个PHP应用文件取名为:test.php
      内容编码为:
<!-- 加载 hello.php 文件 -->
<?php
define('ROOT_PATH',dirname(__FILE__));
include ROOT_PATH.'/hello.php';
?><br/>
<!-- 输出 UuidUtils 的一个值  -->
<?php  
import jdapp.util.UuidUtils;  
$f = new UuidUtils();  
var_dump($f->getRandomGUID());  
?>  
<br/>
<?php  
echo $f->getRandomGUID();
?>  
      
      再创建一个SSI应用文件取名为:hello.php<?php echo "Quercusr Hello World!"; ?>在浏览器地址输入:http://127.0.0.1/test.php

下面写个SSI应用测试:
      创建一个SSI应用文件取名为:ssi.html
      内容编码为:
<!--#include virtual="./header.html" -->再创建一个SSI应用文件取名为:header.html
This is ssi application!在浏览器地址输入:http://127.0.0.1/ssi.html
 
      
      【注】WEB应用文件默认代码格式为utf-8,如果页面呈现出乱码,保存时需要注意一下了。推荐使用EmEditor或Dreamweaver做WEB应用开发编写代码。
通过JDAPP DOC学习文档索引JDAPP相关的JAVA包/类/方法,并可以了解相关联的包/类/方法信息。

打开jdapp_0.3.0.chm学习文档默认可以看到框架所有类的目录。

下面写个mysql查询测试:
      创建一个WEB应用文件取名为:mysql.htm
      内容编码为:
<#comment>查询表</#comment>
<#assign db=_html.getDB(null)/>
<#assign SQLString = "SELECT * FROM DOMAIN WHERE RDNS='byoou.com' AND DEPTID LIKE '%CN.BYOOU-%'"/>
<#assign dataList = db.query(SQLString)?default(null)/>
<#assign dbList = dataList.getList()/>
<#assign s = dbList.size()/>
查询DOMAIN表:<br/>
<table border=1 cellspacing=1 cellpadding=1>
  <tr class="title">
    <td>二级域名</td>
    <td>一级域名</td>
    <td>域名编号</td>
    <td>开发部门编号</td>
    <td>标题</td>
    <td>风格</td>
    <td>区域</td>
    <td>编码</td>
    <td>默认网页</td>
  </tr>
  <#if dbList.size()!=0>
  <#list dbList as d>
  <tr>
    <td>${d.dns?default("")}</td>
    <td>${d.rdns?default("")}</td>
    <td>${d.dnsid?default("")}</td>
    <td>${d.deptid?default("")}</td>
    <td>${d.title?default("")}</td>
    <td>${d.style?default("")}</td>
    <td>${d.locale?default("")}</td>
    <td>${d.encoding?default("")}</td>
    <td>${d.welcomefile?default("")}</td>
  </tr>
  </#list>
  </#if>
</table>
<style>
	tr.title td{padding: 5px 20px; text-align:center; font-weight:bold;}
</style>
在浏览器地址输入:http://127.0.0.1/mysql.htm 
 下面写个mysql更新信息测试:
<#comment>更新DOMAIN表</#comment>
<#assign db=_html.getDB(null)/>
<#assign sqlString = "UPDATE DOMAIN SET TITLE=? WHERE DNS=? "/>
<#assign vessel = _new.vessel()/>
<#assign null = vessel.addChar("外贸网址大全") />
<#assign null = vessel.addChar("abc.byoou.com") />
<#assign num = db.execute(sqlString,vessel) />
更新结果:${num}
 下面写个mysql删除信息测试:
<#comment>删除DOMAIN表信息</#comment>
<#assign db=_html.getDB(null)/>
<#assign sqlString = "DELETE FROM DOMAIN WHERE DNS=? "/>
<#assign vessel = _new.vessel()/>
<#assign null = vessel.addChar("abc.byoou.com") />
<#assign num = db.execute(sqlString,vessel) />
删除结果:<#if num!=0>成功<#else>失败</#if>
 下面写个mysql新增一条域名信息测试:
<#comment>在DOMAIN表新增一条记录</#comment>
<#assign db=_html.getDB(null)/>
<#assign sqlString = "INSERT INTO DOMAIN (BEROOT, CREATETIME, DEPTID, DNS, DNSID, DNUM, ENCODING, EXPIRED, EXTENSIONS, FLAG, IP, LOCALE"/>
<#assign sqlString = sqlString + ", RDATA, RDNS, RDTYPE, ROOT, STATUS, STYLE, TITLE, TTL, TYPE, WELCOMEFILE ) VALUES "/>
<#assign sqlString = sqlString + "(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? ) "/>
<#comment>取DOMAIN表最大编号值</#comment>
<#assign DAODriver=Static["jdapp.dao.DAODriver"]/>
<#assign dnsid=DAODriver.getSuper().getMaxId("DBJD:MMVC.DOMAIN", "dnsid")/>
<#assign vessel = _new.vessel()/>
<#assign null = vessel.addChar("test.byoou.com") />
<#assign null = vessel.addLong(_html.request.initTime) />
<#assign null = vessel.addChar("CN.HOLD-TA") />
<#assign null = vessel.addChar("test.byoou.com") />
<#assign null = vessel.addChar(dnsid) />
<#assign null = vessel.addInt(1000) />
<#assign null = vessel.addChar("gb2312") />
<#assign null = vessel.addLong(-1) />
<#assign null = vessel.addInt(-1) />
<#assign null = vessel.addInt(0) />
<#assign null = vessel.addChar("16908554") />
<#assign null = vessel.addChar("en_US") />
<#assign null = vessel.addChar("@ 127.0.0.1") />
<#assign null = vessel.addChar("byoou.com") />
<#assign null = vessel.addInt(1) />
<#assign null = vessel.addChar("test.byoou.com") />
<#assign null = vessel.addInt(1) />
<#assign null = vessel.addChar("default") />
<#assign null = vessel.addChar("测试域名") />
<#assign null = vessel.addInt(86400) />
<#assign null = vessel.addInt(0) />
<#assign null = vessel.addChar("index.htm") />
<#assign num = db.execute(sqlString,vessel) />
新增结果:<#if num!=0>成功<#else>失败</#if>
 WEB应用处理数据非常简单,无需做预处理try {}catch (Exception e){}finally{}和Commit提交,请求线程完成后会自动执行Commit。
数据连接池信息保存在MMVC数据的JDBCPOOLS表里面,
 
      
用户可以通过修改_html.getDB访求参数值指定使用数据库连接池,例如:<#assign db=_html.getDB("ACCLOG")/>
框架支持以下多种数据库类型连接
jdbc:mysql://127.0.0.1:3306/ACCLOG?useunicode=true&characterEncoding=utf8 jdbc:h2:tcp://db.byoou.com:9092/~/.mystore/conf/embedded-db/dbjd jdbc:h2:/byoou/projects/JavaDev/jdapp/server/resources/conf/embedded-db/dbip jdbc:derby:/byoou/projects/JavaDev/jdapp/server/resources/conf/embedded-db/javadbip;create=true jdbc:oracle:thin:@db.byoou.com:1521:yzkf jdbc:informix-sqli://db.byoou.com:8888/dbdms:INFORMIXSERVER=oncongou;NEWCODESET=GBK,GB18030-2000,5488 jdbc:mysql-embedded/MMVC jdbc:sqlite:J:/notes/2010-04-06_08-16-02 jdbc:h2:/byoou/projects/JavaDev/jdapp/server/resources/conf/embedded-db/pfdb jdbc:h2:#dirs#data/bydba/eics;SCHEMA=EICP;LOG=0;CACHE_SIZE=0;LOCK_MODE=0;UNDO_LOG=0;FILE_LOCK=NO jdbc:h2:/byoou/bydc/backend/#dirs#data/bydba/eics;LOG=0;CACHE_SIZE=0;LOCK_MODE=0;UNDO_LOG=0;FILE_LOCK=NO
JDAPP框架提供详细的异常信息输出,除了默认的日志输出还可以通过Log4j方式输出日志。
其中WEB应用异常信息可以通过网页展示/网页源代码/Eclipse控制台/错误日志文件四种方式查看到异常信息输出。
以下图片为用户访问网页时展示出来的异常报错信息:
 
      以下图片为用户访问网页时查看网页源代码显示出来的异常报错信息:
 
      以下图片为Eclipse控制台打印出来的异常报错信息:
 
      以下图片为错误日志文件输出来的异常报错信息:
 
      异常信息分析:
      ==> assignment: db=_html.getDB() [on line 3, column 1 in mysql.htm]
      指的是mysql.htm文件的第三行代码引发异常信息:
      其中的异常信息:
      Caused by: java.lang.IllegalArgumentException: wrong number of arguments
      指的是错误参数的意思
       freemarker.template.TemplateModelException: Method public jdapp.db.DB jdapp.mmvc.context.ActionPage.getDB(java.lang.String) 
      而上面信息了解ActionPage类的方法getDB(java.lang.String) 是需要字符参数的,可以确认此异常为getDB方法缺少字符参数
      
以下图片JAVA应用抛出的异常信息:

以下图片为Eclipse控制台打印出来的异常报错信息:

异常信息分析:
dapp.exceptions.NoSuchMethod: JDA-10002: Method: "doIndex()" is not defined in Object: jdapp.mmvc.support.ActionBase 
      意思非常清晰:
      加载的java类 jdapp.mmvc.support.ActionBase缺少 doIndex()方法
      解决方法:只需要在ActionBase创建一个doIndex()方法或修改应用模型指定已写好的JAVA方法即可
      
      
异常信息分析:
jdapp.exceptions.ActionException: 未找到模板:D:/JDAPP-Product/jiashun/installed/jdapp/WebContent/WEB-INF/domains/frontend/store/www.byoou.com/apptpl/html/index.htm not found. 
      意思非常清晰:
      未找到模板,解决方法只需要根据指定的路径目录创建一个index.htm文件即可,当然也可以修改应用模型或模板模型来指定模板文件名或路径
      
注:在Freemarker模板引擎中,如果编写代码缺少模板标签会有可能导致整张页面没有任何内容输出,而且Eclipse控制台上也没有日志异常打印出来,需要开发工程师通过排除编码方法来查找模板引擎所缺少的标签。
1、jdapp.xml
JDAPP框架配置文件,默认存储在WebContent/WEB-INF/conf/jdapp.xml,当然是可以在启动JVM时指定加载配置文件所在位置:
-DconfigFile=/yunjd/installed/tomcat/conf/jdapp.xml
<?xml version="1.0" encoding="UTF-8"?> <jdapp> <database> <connection> <driver>com.mysql.jdbc.Driver</driver> <driverx>com.mysql.jdbc.jdbc2.optional.MysqlXADataSource</driverx> <string><![CDATA[jdbc:mysql://127.0.0.1:3306/MMVC?useunicode=true&characterEncoding=utf8]]></string> <user>6697b0c06385e9b5569068552d75c721887c9e9c0ece6912</user> <password>f52c8251a6faabaae38b2df2f2f42e788587db48c4c0dbf2305d63cb03196a02</password> <converter>jdapp.db.converter.MysqlConverter</converter> <dbobject>jdapp.db.type.Mysql</dbobject> <pfdbobject>jdapp.plugin.pageframes.db.type.Mysql</pfdbobject> </connection> </database> </jdapp>
2、web.xml
标准Servlet引擎应用必需加载的配置文件:
<web-app> <display-name>JDAPP</display-name> <description>JD APPLICATION(简单应用|基地应用框架)</description> <servlet> <description>MVC SERVLET</description> <servlet-name>page</servlet-name> <servlet-class>jdapp.mmvc.PageServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>page</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping> <session-config> <session-timeout>30</session-timeout> </session-config> </web-app>
3、log4j.properties
JDAPP框架默认不加载Log4J的log4j.properties的配置文件,但可以通过修改web.xml配置文件进行加载。
<context-param> <param-name>un.log4j</param-name> <param-value>false</param-value> </context-param>
4、log4j-debug.xml
Log4j-debug.xml为Log4J的XML格式配置文件,可以通过修改web.xml配置文件进行加载。
<context-param> <param-name>un.log4j</param-name> <param-value>false</param-value> </context-param> <context-param> <param-name>un.log4j.conf</param-name> <param-value>false</param-value> </context-param>
5、jboss-cache-32-cluster.xml
JDAPP框架默认不会加载jboss-cache-32-cluster.xml集群缓存配置文件,可以通过修改数据表PROXY_OBJECT和REPOSITORY启动jbosscache缓存引擎即可加载配置文件。
<?xml version="1.0" encoding="UTF-8"?>
<jbosscache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="urn:jboss:jbosscache-core:config:3.2"> 
   <transaction transactionManagerLookupClass="jdapp.cache.base.MyTransactionManagerLookup"/>
   <clustering  clusterName="MMVC-Cluster">
      <sync />
      <jgroupsConfig>
            <UDP discard_incompatible_packets="true" enable_bundling="false" enable_diagnostics="false" ip_ttl="2"
                 loopback="false" max_bundle_size="64000" max_bundle_timeout="30" mcast_addr="228.10.10.10"
                 mcast_port="45588" mcast_recv_buf_size="25000000" mcast_send_buf_size="640000"
                 oob_thread_pool.enabled="true" oob_thread_pool.keep_alive_time="10000" oob_thread_pool.max_threads="4"
                 oob_thread_pool.min_threads="1" oob_thread_pool.queue_enabled="true"
                 oob_thread_pool.queue_max_size="10"
                 oob_thread_pool.rejection_policy="Run" thread_naming_pattern="pl" thread_pool.enabled="true"
                 thread_pool.keep_alive_time="30000" thread_pool.max_threads="25" thread_pool.min_threads="1"
                 thread_pool.queue_enabled="true" thread_pool.queue_max_size="10" thread_pool.rejection_policy="Run"
                 tos="8" ucast_recv_buf_size="20000000" ucast_send_buf_size="640000" use_concurrent_stack="true"
                 use_incoming_packet_handler="true"/>
            <PING num_initial_members="3" timeout="2000"/>
            <MERGE2 max_interval="30000" min_interval="10000"/>
            <FD_SOCK/>
            <FD max_tries="5" shun="true" timeout="10000"/>
            <VERIFY_SUSPECT timeout="1500"/>
            <pbcast.NAKACK discard_delivered_msgs="true" gc_lag="0" retransmit_timeout="300,600,1200,2400,4800"
                           use_mcast_xmit="false"/>
            <UNICAST timeout="300,600,1200,2400,3600"/>
            <pbcast.STABLE desired_avg_gossip="50000" max_bytes="400000" stability_delay="1000"/>
            <pbcast.GMS join_timeout="5000" print_local_addr="true" shun="false" view_ack_collection_timeout="5000"
                        view_bundling="true"/>
            <FRAG2 frag_size="60000"/>
            <pbcast.STREAMING_STATE_TRANSFER/>
            <pbcast.FLUSH timeout="0"/>
        </jgroupsConfig>
   </clustering>
</jbosscache>
      6、freemarker.properties
JDAPP框架默认不会加载freemarker.properties存配置文件,当第一次访问Freemarker应用会加载配置文件。
default_encoding=UTF-8 number_format=#.## date_format=yyyy-MM-dd time_format=HH:mm:ss datetime_format=yyyy-MM-dd HH:mm:ss localized_lookup=false url_escaping_charset=UTF-8 cache_storage=strong:500,soft:1000 template_update_delay=0
7、php.ini
JDAPP框架默认不会加载PHP配置文件,当第一次访问PHP应用会加载配置文件。
[PHP] engine = On short_open_tag = Off asp_tags = Off precision = 14 output_buffering = 4096 zlib.output_compression = Off implicit_flush = Off unserialize_callback_func = serialize_precision = 17 disable_functions = disable_classes = zend.enable_gc = On expose_php = On max_execution_time = 30 max_input_time = 60 memory_limit = 128M error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT display_errors = Off display_startup_errors = Off log_errors = On log_errors_max_len = 1024 ignore_repeated_errors = Off ignore_repeated_source = Off report_memleaks = On track_errors = Off html_errors = On variables_order = "GPCS" request_order = "GP" register_argc_argv = Off auto_globals_jit = On post_max_size = 8M auto_prepend_file = auto_append_file = default_mimetype = "text/html" doc_root = user_dir = enable_dl = Off file_uploads = On upload_max_filesize = 2M max_file_uploads = 20 allow_url_fopen = On allow_url_include = Off default_socket_timeout = 60
做WEB开发推荐的开发工具有Eclipse、Dreamweave、Emeditor,几种工具都有32位和64位系统之分。
除了以上开发编码的工具还包括调试工具有Firefox的扩展工具Firebug和IE的扩展工具HttpWatch,在开发过程推荐使用Google Chrome做测试检查。
如果使用的是MySQL建议选择Navicat Premium和phpMyAdmin做数据库管理,运行的JDK建议使用1.7.0_45或以上版本。
如果需要用Ftp即建议使用FileZilla FTP客户端,运行在Linux推荐使用Centos系统并使用SecureCRT作为管理工具。
 
      以上图片为eclipse编辑器对freemarker引擎模板进行编辑。
html上的标签按页面内容描述编写,主次分明,常用的标签有:div,p,dl,dt,dd,ul,ol,li,img,h1,h2,h3,h4,h5,h6,strong,a,b,u,i,q,s,em。
css文件存放head标签内,javascript文件尽量放在body结束标签上。
sql语句内容统一使用大写编码,在Emeditor编辑工具对语句内容可以使用快捷键:Ctrl+Shift+U 实现变大写,捷键:Ctrl+U实现变小写快。
静态html和css引用文件使用相对路径编写,应用编码建议统一使用utf-8保存。
编码需要做到简洁,可读性强,展示页面速度快,用最小的css代码来完成整站的样式展示。用最精简的代码将功能实现,常用功能的代码要做到全局调整。
Dreamweave工具可以对HTML/CSS/Javascript代码通过【应用源格式】对代码进行格式化,格式化后的代码会美观一些。
 
      Eclipse工具可以对java代码进行格式化,格式化后的代码会很美观,也可以通过快捷键:Ctrl+Shift+F执行。
 
      当然还有一些其它工具可以对代码进行更美观的格式化,如有发现可以推荐给我们。
第一步:先确认JAVA应用使用的网址路径,例如:http://127.0.0.1/first/sample.do
第二步:检查域名127.0.0.1使用应用开发部门编号为多少,例如:CN.SYSTEM-TA
第三步:根据应用路径URI:/first/sample.do,创建一个对应的应用模型,例如:first.sample.0:CN.SYSTEM-TA
第四步:截图里的模型指定的Action类是:jdapp.mmvc.page.RPCService,Action方法为:doTest;即需要创建一个继承jdapp.mmvc.interfaces.Action接口的类和doTest方法的类,代码内容如下:
package jdapp.mmvc.page;
import jdapp.mmvc.support.ActionBase;
/**
 * 
 * @author wushaoen
 *
 */
public class RPCService extends ActionBase {
	/**
	 * RPC服务
	 */
	private static final long serialVersionUID = 1L;
	/**
	 * 测试实例
	 */
	public void doTest(){
		
		//通过firstSample参数把值为Hello World传送给应用模板
		$page.put("firstSample","Hello World");
		
	}
}
第五步:在对应的目录创建一个JAVA应用模板,如:127.0.0.1/apptpl/do/first/sample.htm,代码内容如下:
${_html.get("firstSample")?default("")}
到最后访问网址:http://127.0.0.1/first/sample.do ,即可以看到以下结果内容:
注意:JAVA应用使用的模板存储在apptpl目录下,WEB应用文件是存储在webapp目录下;还有模板编号命名为:first.sample.0:PORTAL。
框架基于MMVC设计模式中文命名为:多模式-模型-视图-控制器(Multi-Model-View-Controller(MMVC)),相对普通的MVC设计模式不同之处在于多了一个M字(Multi)意为:多模型多视图多控制器。

从设计图可以看出,在处理过程会从根据路径在缓存取出域名和模型的实现出来。
框架中的JAVA应用优先于WEB应用;JAVA应用=JAVA逻辑+WEB应用
用户在【浏览器】输入网址:http://www.yunjd.net/member/personal.do
JDAPP应用服务器对网址路径换算为【应用模型ID】并向模型缓存引擎检索(模型实例)也称为(JAVA应用模型);
【模型实例】检索成功:JDAPP则执行应用模型JAVA类的对应方法,并由方法传递参数到应用模板;
【模型实例】检索失败:JDAPP则返回文件柜模型【store.file.00:CN.SYSTEM-TA】实例,文件柜模型读取域名所支持的WEB应用及网址访问的文件名进行匹配;
【WEB应用】匹配成功:JDAPP则调用相应的WEB应用解释器对网址访问的WEB应用文件进行解释并返回用户浏览器。
【WEB应用】匹配失败:JDAPP则直接返回网址访问的文件内容给用户浏览器,如果文件找不到则返回404错误页面。
            
            
            
                  网址换算为模型的方法
http://域名:端口/模型.后辍
域名:一级域名,二级域名,三级域名
模型:主(零)模型,一级模型,二级模型,三级模型。
路径:根路径/,默认使用index.index.0的模型;
	一级路径,使用路径名.index.0的模型;
	二级路径,使用一级路径名.二级路径名.0的模型或一级路径.文件名.0的模型;
	三级路径,,使用一级路径名.二级路径名.1;四级/五级/六级路径在目录层数相应加一。
            
            
            
            模型的定义规则
开发机构	机构码=国家代码(.)公司简码							
开发团队	部门码=机构简码(-)团队简码							
应用模型	模型码=路径映射码(@)部门码		路径映射码=一级目录(.)二级目录(.)目录层数
应用模板	模板码=模型(:)模板简码(@)部门码
            
            
            
      JDAPP框架【简单开发学习版】启动时控制台打印的信息
************* Start Display Current Environment *********** app.name = JdApp Developer Edition Release V0.1.0 app.build = SVNTag=JdApp_0_1_0 date=201302280106 app.server = jetty/6.1.26 servlet.version = 2.5 run.mode = Development config.issetup = false config.local = en_US user.language = zh user.country = CN file.encoding = UTF-8 os.arch = x86 user.timezone = current.time = 2014-11-11 15:21:16 os.name = Windows 8 jdapp.home = D:/JDAPP-Project webapp.root = D:/JDAPP-Project/WebContent store.path = D:/JDAPP-Project/WebContent/WEB-INF user.home = C:\Users\wushaoen java.home = D:\jdapp\installed\applications\jdk1.7.0_45\jre java.io.tmpdir = C:\Users\wushaoen\AppData\Local\Temp\ configFile = D:/JDAPP-Project/WebContent/WEB-INF/conf/jdapp.xml jvm = Oracle Corporation Java HotSpot(TM) Client VM 24.45-b08 ************* End Display Current Environment ************* 15:21:16,403 DEBUG [main] (DBFactory.java:99) - Create DB 15:21:16,595 DEBUG [main] (DB.java:340) - [DBJD]: SELECT * FROM MMVC.PROXY_OBJECT WHERE STATUS!=0 AND FLAG=10 ORDER BY ORDERBY 15:21:16,613 DEBUG [main] (DB.java:193) - [DBJD]: SELECT * FROM MMVC.REPOSITORY WHERE PLUGIN = ? AND STATUS != 0 ORDER BY ORDERBY; --[0:MMVC@CN.SYSTEM-TA] 15:21:16,618 DEBUG [main] (DB.java:340) - [DBJD]: SELECT * FROM MMVC.PROXY_OBJECT WHERE STATUS!=0 ORDER BY ORDERBY 15:21:16,621 DEBUG [main] (DB.java:193) - [DBJD]: SELECT NAME, VALUE FROM MMVC.CONF_SET WHERE PLUGIN=? AND STATUS!=0; --[0:MMVC@CN.SYSTEM-TA] 15:21:16,624 DEBUG [main] (DB.java:193) - [DBJD]: SELECT NAME, VALUE FROM MMVC.CONF_SQL WHERE PLUGIN=? AND STATUS!=0; --[0:MMVC@CN.SYSTEM-TA] 15:21:16,626 DEBUG [main] (DB.java:340) - [DBJD]: SELECT * FROM MMVC.USERS WHERE STATUS!=0 AND FLAG=10 ORDER BY LENGTH(ID),ID 15:21:16,628 DEBUG [main] (DB.java:193) - [DBJD]: SELECT NAME, VALUE FROM MMVC.I18N_LANGUAGE WHERE PLUGIN =? AND STATUS!=0; --[0:MMVC@CN.SYSTEM-TA] 15:21:16,629 DEBUG [main] (DB.java:193) - [DBJD]: SELECT NAME, VALUE FROM MMVC.I18N_ZH_CN where PLUGIN=? AND STATUS!=0; --[0:MMVC@CN.SYSTEM-TA] 15:21:16,630 DEBUG [main] (DB.java:340) - [DBJD]: SELECT * FROM MMVC.ORG WHERE FLAG=10 AND STATUS!=0 15:21:16,632 DEBUG [main] (DB.java:340) - [DBJD]: SELECT * FROM MMVC.ORG_DEPT WHERE FLAG=10 AND STATUS!=0 15:21:16,637 DEBUG [main] (DB.java:340) - [DBJD]: SELECT * FROM MMVC.DOMAIN WHERE STATUS!=404 AND RDTYPE=1 15:21:16,648 DEBUG [main] (DB.java:340) - [DBJD]: SELECT * FROM MMVC.TEMPLATE WHERE STATUS!=0 15:21:16,665 DEBUG [main] (DB.java:340) - [DBJD]: SELECT * FROM MMVC.APPMODEL WHERE STATUS!=404 ORDER BY MODELID 15:21:16,702 DEBUG [main] (DB.java:340) - [DBJD]: SELECT * FROM MMVC.EXTENSION ORDER BY ID 15:21:16,704 DEBUG [main] (DB.java:340) - [DBJD]: SELECT BIP FROM MMVC.BLACKIP WHERE STATUS!=0 15:21:16,706 DEBUG [main] (DB.java:340) - [DBJD]: SELECT * FROM MMVC.ADS WHERE STATUS!=0 15:21:16,707 DEBUG [main] (DB.java:340) - [DBJD]: SELECT DIRECT, REDIRECT FROM MMVC.HTTP301 WHERE STATUS!=0 15:21:16,707 DEBUG [main] (DB.java:340) - [DBJD]: SELECT * FROM MMVC.KEYWORDS WHERE STATUS!=0 15:21:16,708 DEBUG [main] (AppInitializer.java:310) - Inited object: jdapp.cache.DefaultEngine (use time:98 ms) 15:21:16,709 DEBUG [main] (AppInitializer.java:310) - Inited object: jdapp.mmvc.controller.DefaultController (use time:1 ms) 15:21:16,711 DEBUG [main] (AppInitializer.java:310) - Inited object: jdapp.mmvc.controller.StoreFile (use time:2 ms) 15:21:16,713 DEBUG [main] (AppInitializer.java:310) - Inited object: jdapp.mmvc.controller.StoreCache (use time:2 ms) 15:21:16,713 DEBUG [main] (AppInitializer.java:310) - Inited object: jdapp.mmvc.view.servlet.PortalServlet (use time:0 ms) 15:21:16,714 DEBUG [main] (AppInitializer.java:310) - Inited object: jdapp.mmvc.view.servlet.ClazzView (use time:0 ms) 15:21:16,714 DEBUG [main] (AppInitializer.java:310) - Inited object: jdapp.mmvc.page.tools.CategoryProxy (use time:0 ms) 15:21:16,721 DEBUG [main] (DB.java:193) - [DBJD]: SELECT * FROM MMVC.DOMAIN WHERE RDTYPE=? AND STATUS!=404; --[0:6] 15:21:16,753 DEBUG [main] (Named.java:209) - huajie.hua168.com not found. 15:21:16,758 DEBUG [main] (DB.java:340) - [DBJD]: SELECT * FROM MMVC.DOMAIN WHERE RDTYPE NOT IN(6,1) AND STATUS!=404 15:21:16,761 DEBUG [main] (Named.java:116) - Named listening on 127.0.0.1#53 15:21:16,762 DEBUG [main] (AppInitializer.java:310) - Inited object: jdapp.component.name.Named (use time:47 ms) 15:21:16,763 DEBUG [main] (AppInitializer.java:310) - Inited object: jdapp.util.file.ListenForChange (use time:1 ms) 15:21:16,765 DEBUG [main] (AppInitializer.java:310) - Inited object: jdapp.component.ftpserver.FtpServerD (use time:1 ms) 15:21:16,765 DEBUG [main] (DBFactory.java:116) - Commit DB Inited time use:0.417 Second org.mortbay.log: Started SelectChannelConnector@0.0.0.0:80
了解框架在整理个启动过程中会运行的文件包括:
startup.bat jdapp.bat jdapp.server.run.ProMode org.mortbay.jetty.Server jdapp.mmvc.PageServlet jdapp.mmvc.MultiFramework jdapp.mmvc.context.AppInitializer jdapp.util.preferences.AppSettings,此类加载的配件文件包括:1、System.getProperties(系统属性)2、constants.properties(系统常量属性)3、web.xml(Servlet配置变量)4、jdapp.xml(配置变量)5、conf_set.sql(数据设置集) org.mortbay.log: Started SelectChannelConnector@0.0.0.0:80
了解框架MMVC设计模式动作过程:
写出前端展示内容response->OutputStreamWriter 执行展示代理器ViewProxy->FastView 执行业务逻辑Action->ActionRun 创建藕合代理器InvokeProxy->ActionInvocationHandler 载入控制代理器ControllerProxy->DefaultController 缓存载入appmodel 缓存载入domain 重构response->ResponseHandler 重构session->SessionHandler 重构request->RequestHandler
 
      APPMODEL为模型数据表
DOMAIN为域名数据表
TEMPLATE为应用模型模板数据表
ORG为开发机构数据表
ORG_DEPT为开发机构部门数据表
REPOSITORY为缓存存储柜数据表
PROXY_OBJECT为代理对象数据表
EXTENSION为扩展名数据表
Action,JRequest,JResponse,JSession,APage为框架常用接口,了解几个接口有利于调整接口获得相关数据。
Action接口代码:jdapp.mmvc.interfaces.Action
package jdapp.mmvc.interfaces;
/**
 * All actions <b>may</b> implement this interface, which exposes the <code>execute()</code> method.
  * @author wushaoen
 */
public interface Action {
    public static final String SUCCESS = "success";
    public static final String NONE = "none";
    public static final String ERROR = "error";
    public static final String INPUT = "input";
    public static final String LOGIN = "login";
    
    public String execute(APage page) throws Exception;
}
	JRequest接口代码:jdapp.mmvc.interfaces.JRequest
package jdapp.mmvc.interfaces;
       
import java.util.Collection;
import java.util.Properties;
import javax.servlet.http.HttpServletRequest;
import jdapp.entry.Domain;
import jdapp.entry.AppModel;
import jdapp.entry.Extension;
import jdapp.entry.UsersTDomain;
import jdapp.util.MapImpl;
/**
 * 重构request接口
 * @author wushaoen
 *
 */
public interface JRequest extends HttpServletRequest {	
	public final static String USER_AGENT = "User-Agent";
	public final static String CONTENT_TYPE = "Content-Type";
	public final static String ACCEPT_LANGUAGE = "Accept-Language";
	public final static String REFERER = "Referer";	
	
	/**
	 * 返回页面初始化时间
	 * @return
	 */
	public long getInitTime();	
	
	/**
	 * 返回当前页面字符
	 */
	public String getCharacterEncoding();
	
	/**
	 * 返回客户访问机的IP地址
	 */
	public String getRemoteAddr() ;
	
	/**
	 * 返回后辍
	 * @return
	 */
	public Extension getExtension() ;	
	
	/**
	 * 判断是否为浏览器访问
	 * @return
	 */
	public boolean isBrowers();
	
	/**
	 * 判断是否为网络机器人
	 * @return
	 */
	public boolean isRobot();
	
	/**
	 * 判断是否支持wap格式
	 * @return
	 */
	public boolean isWap();
	
	/**
	 * 判断是否为后台控制域名
	 * @return
	 */
	public boolean isBackEnd();
	
	/**
	 * 取访问域名的实例
	 * @return
	 */
	public Domain getDomain();
	
	/**
	 * 取域名格式
	 * @return
	 */
	public int getDomainType();
	
	/**
	 * 返回路径 
	 * @return
	 */
	public String getUri();
	
	/**
	 * 返回网址
	 * @return
	 */
	public String getUrl();
	
	/**
	 * 返回模型路径
	 * @return
	 */
	public String getCoreModelUri();
	
	/**
	 * 返回用户代理
	 * @return
	 */
	public String getUserAgent();
	
	/**
	 * 返回用户语言
	 * @return
	 */
	public String getUserLanguage();
	
	/**
	 * 返回带协议的域名
	 */
	public String getPathInfo();
	
	/**
	 * 返回带参数的网址
	 * @return
	 */
	public String getThisPath();
	
	/**
	 * 返回前一个页面
	 * @return
	 */
	public String getRefere();
	
	/**
	 * 继承HttpServletRequestWrapper
	 */
	public String getContextPath();
	
	/**
	 * 路径参数
	 * @param key
	 * @return
	 */
	public String getParamUrl(String key);
	
	/**
	 * 返回全部的路径参数
	 * @return
	 */
	public Properties getParamUrls();
	
	/**
	 * 返回消息内容
	 * @return
	 */
	public Collection<String> getMessages();
	
	/**
	 * 返回全部参数
	 */
	public MapImpl<String, Object> getParameterMap();
	
	/**
	 * 返回会话内容
	 */
	public JSession getSession();
	
	/**
	 * 返回路径模型值
	 * @param url
	 * @return
	 */
	public String urlModel(String url);
	
	/**
	 * 返回应用后辍
	 */
	public String getMime();
	
	/**
	 * 返回消息
	 * @param key
	 * @return
	 */
	public String getMessage(String key);
	
	/**
	 * 返回后辍参数
	 * @param key
	 * @param params
	 * @return
	 */
	public String getMessage(String key, Object params[]);
	
	/**
	 * 返回参数内容
	 * @return
	 */
	public String getQuery();
	
	/**
	 * 返回参数并做安全检测
	 * @param isSecurity
	 * @return
	 */
	public String getQuery(boolean isSecurity);
	
	/**
	 * 模型是否为缓存
	 * @return
	 */
	public int getCached();
	
	/**
	 * 设置模型为缓存
	 * @param cached
	 */
	public void setCached(int cached);	
	
	/**
	 * 返回模型实例
	 * @return
	 */
	public AppModel getModel();	
	
	/**
	 * 设置模型实例
	 * @param action
	 */
	public void setModel(AppModel action);
	
	/**
	 * 返回要跳转的模型
	 * @return
	 */
	public AppModel getForward();
	
	/**
	 * 设置要跳转的模型
	 * @param model
	 */
	public void setForward(AppModel model);
	
	/**
	 * 设置已跳转的次数
	 * @param forwardNum
	 */
	public void setForwardNum(int forwardNum);
	
	/**
	 * 个性化域名部门的设置
	 * @return
	 */
	public boolean setSystemError();
	
	/**
	 * 添加消息
	 * @param message
	 * @return
	 */
	public AppModel addMessage(String[] message);
	
	/**
	 * 完成request做一次处理
	 */
	public void finish();
	
	/**
	 * 返回根据IP计算出来的域名dirs
	 * @return
	 */
	public String getDirs();
	
	/**
	 * 返回当前会话控制的域名
	 * @return
	 */
	public UsersTDomain getUtd();
}
       
	JResponse接口代码:jdapp.mmvc.interfaces.JResponse
package jdapp.mmvc.interfaces;
       
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.ServletOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
public interface JResponse  extends HttpServletResponse{
	public void setContentLength(int len);
	public boolean containsHeader(String name);
	public void setHeader(String name, String value);
	public void addCookie(Cookie cookie);
	public String encodeRedirectURL(String url);
	public String getCharacterEncoding();
	public void sendRedirect(String location) throws IOException;
	
	public ServletOutputStream getOutputStream() throws IOException;
	public PrintWriter getWriter() throws IOException;
	public void setContentType(String type);
	public String encodeURL(String url);
	public void addHeader(String name, String value);
	
	public void setDateHeader(String name, long date);
	
	public void sendError(int sc) throws IOException;
}
	JSession接口代码:jdapp.mmvc.interfaces.JSession
package jdapp.mmvc.interfaces;
import java.util.Map;
import javax.servlet.http.HttpSession;
public interface JSession extends HttpSession{
	public static final String USKEY = "$user.session.key";
	public static final String US_PREFIX = "$user.session.";
	
	public static final String USID = "$user.session.id";//标识
	public static final String USEMAIL = "$user.session.email";//邮箱
	public static final String USACCOUNT = "$user.session.account";//账号
	public static final String USNICKNAME = "$user.session.nickname";//昵称
	
	public static final String USLOCALE = "$user.session.locale";//时区
	public static final String USONENEWS = "$user.session.onenews";//消息数
	public static final String USSTYLE = "$user.session.style";//风格
	
	public static final String USRIGHTS = "$user.session.rights";//权限
	public static final String USRIGHTSP = "$user.session.rightsp";//平台权限
	
	public static final String USPARENT = "$user.session.parentid";//用户判断主账号和子账号的关系(通常用于商城账号表设计)
	public static final String USROUTER = "$user.session.router";//用户路由表,方便用户登录后跳转位置
	
	public static final String CONSOLEDNS = "$user.session.cdns";//控制域名
	
	public static final String PARAMHL = "hl";
	public static final String TB_TOKEN = "_tb_token";
	public static final String TB_TOKEN_NEW = "_tb_token_new";
	public static final String IMG_CAPTCHA = "_img_captcha";
	public static final String IS_VALID_TOKEN = "_is_valid_token";
	public static final String COOKIEID = "_user.cookie.id";
	public static final String COOKIENEWID = "_user.cookie.isnew";
	
	public void setAttribute(Map<String, Object> attribute);
	/**************
	 * 用户编号容器
	 */
	public String getUid();
	
	/**************
	 * 邮箱容器
	 */
	public String getEmail();
	
	/**************
	 * 账号容器
	 */
	public String getAccount();
	
	/**************
	 * 昵称容器
	 */	
	public String getNickname();
	
	/**************
	 * 时区容器
	 */	
	public String getLocale();
	
	/**************
	 * 个人消息容器
	 */	
	public int getOnenews();
	
	/**************
	 * 用户风格容器
	 */
	public String getStyle();
	/**
	 * 返回会话权限
	 * @return
	 */
	public int getRights();
	
	public int getRightsp();
	
	public String getCDns(String dns);
	
	/**
	 * 判断是否已登录用户
	 * @return
	 */
	public boolean isLoginedUser();	
	
	/**
	 * 加载自动语言
	 */
	public void loadAutoLanguage();
	
	/**
	 * http会话
	 * @return
	 */
	public HttpSession getHttpSession();
}
       
       
       
       
	APage接口代码:jdapp.mmvc.interfaces.APage
package jdapp.mmvc.interfaces;
import java.io.Serializable;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Collection;
import java.util.Map;
import java.util.Properties;
import javax.servlet.http.Cookie;
import jdapp.db.DB;
import jdapp.entry.TplFrame;
import jdapp.mmvc.context.ActionContext;
import jdapp.mmvc.support.ActionReport;
import jdapp.util.MapImpl;
/**
 * @author wushaoen
 *
 */
public interface APage extends Serializable{
	
	/**
	 * @return 获得ActionContext对象
	 */
	public ActionContext getContext();
		
	/**
	 * 获得Http请求对象
	 * @return  HttpServletRequest
	 */
	public JRequest getRequest();
  
	/**
	 * @return 获得HttpServletReponse对象
	 */
	public JResponse getResponse();
	
	
	public MapImpl<String, Connection> getDBPool();
	
	/**
	 * @return HttpServletRequest.Attribute对应的AttributeMap对象
	 */
	public MapImpl<String, Object> getActinBodyMap();
	
	/**
	 * 在HttpServletRequest.Attribute中建立Key和Value之间的关联
	 * @param key  给定的Key值
	 * @param value  给定的value值
	 */
	public void put(String key, Object value);
	public void put(MapImpl<String, Object> map);
	
	/**
	 * 获得给定的Key在HttpServletRequest.Attribute对象中的值,如果Key不在HttpServletRequest.Attribute中存在,则返回null对象
	 * @param key  String 给定的Key
	 * @return Object 给定Key对应的值,如果Key不存在,则返回null
	 */
	public Object get(Object key);
	
	/**
	 * 获取用户会话
	 * @return UserSession
	 */
	public JSession getSession();
	/**
	 * 在HttpServletRequest.Session中建立键值之间的关联,如果该键存在,则原先的值会被覆盖。
	 * @param key  String 给定的键
	 * @param value Object 给定的值
	 */
	public void setSession(String key, Object value);
	/**
	 * 获得给定的Key在HttpServletRequest.Session对象中的值,如果Key不在HttpServletRequest.Session中存在,则返回null对象
	 * @param key  String 给定的Key
	 * @return Object 给定Key对应的值,如果Key不存在,则返回null
	 */
	public Object getSession(String key);
	/**
	 * 删除HttpServletRequest.Session中的指定Key的键值
	 * @param key 给定的Key值
	 */
	public void removeSession(String key);
		
	
	/**
	 * 将给定的Map对象中的键值拷贝给HttpServletRequest.Session对象
	 * @param session  给定的Map对象
	 */
	public void setSession(Map<String, Object> session);
	
	/**
	 * 获得给定的Key在HttpServletRequest.Session对象中的值
	 * 如果Key不在HttpServletRequest.Session中存在或值为null,则返回缺省值
	 * @param name  String 给定的Key
	 * @param def  Object 缺省值
	 * @return  Object 给定Key对应的值,如果Key不存在或者返回的值为null,则返回null
	 */
	public Object getSession(String name, Object def);
	
	/**
	 * 获得给定的Key在HttpServletRequest.Session对象中的值
	 * 如果Key不在HttpServletRequest.Session中存在或值为null,则返回缺省值
	 * @param name  String 给定的Key
	 * @param def  String 缺省值
	 * @return  String 给定Key对应的值,如果Key不存在或者返回的值为null,则返回null
	 */
	public String getSessionString(String name, String def);
	/**
	 * 获得给定的Key在HttpServletRequest.Session对象中的值
	 * 如果Key不在HttpServletRequest.Session中存在或值为null,则返回缺省值
	 * 如果有值,将该值转化成Integer,则返回缺省值
	 * @param name  String 给定的Key
	 * @param def  Integer 缺省值
	 * @return  Integer 给定Key对应的值,如果Key不存在或者返回的值为null,则返回def
	 */
	public Integer getSessionInteger(String name, Integer def);
	/**
	 * 获得给定的Key在HttpServletRequest.Session对象中的值
	 * 如果Key不在HttpServletRequest.Session中存在或值为null,则返回缺省值
	 * 如果有值,将该值转化成int,则返回缺省值
	 * @param name  String 给定的Key
	 * @param def  int 缺省值
	 * @return  int 给定Key对应的值,如果Key不存在或者返回的值为null,则返回def
	 */
	public int getSessionInt(String name, int def);
	
	
	/**
	 * 获得给定Key值的Cookie对象
	 * @param name 给定的Cookie名称
	 * @return  Cookie 获得相应的Cookie,如果不存在,怎么返回null
	 */
	public Cookie getCookie(String name);
	public Cookie getCookie(String name, String domain) ;
	/**
	 * 创建Cookie对象,并添加到HttpServletResponse中
	 * @param name  Cookie名称
	 * @param value  Cookie值
	 * @param maxAge  失效时间
	 * @param path  Cookie放置位置
	 * @param domain  Cookie域 为null或""不设置
	 * @return  Cookie
	 */
	public Cookie setCookie(String name, String value, int maxAge, String path, String domain);
	
	/**
	 * 创建Cookie对象,并添加到HttpServletResponse中
	 * @param name  Cookie名称
	 * @param value  Cookie值
	 * @param maxAge  失效时间
	 * @param path  Cookie放置位置
	 * @return  Cookie
	 */
	public Cookie setCookie(String name, String value, int maxAge, String path);
	
	/**
	 * 设置Cookie对象
	 * @param name  Cookie名称
	 * @param value  Cookie值
	 * @param maxAge  失效时间
	 * @return
	 */
	public Cookie setCookie(String name, String value, int maxAge);
	
	/**
	 * 得到给定的Cookie名称的值
	 * @param name  Cookie名称
	 * @return  Cookie值,如果值不存在,则返回null
	 */
	public String getCookieValue(String name);
	
	public String getCookieValue(String name, String domain);
	
	public Properties getParamUrls();
	
	public String getParamUrl(int name);	
	
	public Integer getParamUrlInteger(int name,Integer def);
	
	/**
	 * @return HttpServletRequest.Parameter对应的Map对象
	 */
	public MapImpl<String, Object> getParameterMap();
	
	/**
	 * 获得HttpServletRequest.Parameter中参数名称以prefix为前缀的Map,
	 * 并且将键值Key去掉相应的前缀
	 * @param prefix 前缀值
	 * @return  有prefix前缀的所有数据Map
	 */
	public MapImpl<String, Object> getParameterMap(final String prefix);
	public MapImpl<String, String> getParamMap(final String prefix);
	
	/**
	 * 在HttpServletRequest.Parameter建立键值之间的关联,如果该键存在,则原先的值会被覆盖。
	 * @param key  String 给定的key
	 * @param value String 给定的值
	 */
	public void setParameter(String key, String value);
	
	public void setParameterUrl(Object key, String value);
	
	/**
	 * 打印参数信息
	 * @return
	 */
	public String getParameterPrint();
	
	/**
	 * 打印带前辍参数信息
	 * @param prefix
	 * @return
	 */
	public String getParameterPrint(final String prefix);
	
	/**
	 * 从HttpServletRequest.Parameter中获得指定键值对应的数组数据,如果该键不存在,返回空。
	 * 如果值为数组,则返回该数组,如果值为单值,则返回一个只有一条记录的数组
	 * @param name 给定的key
	 * @return  String[]  获得相应数组数据
	 */
	public String[] getStrings(String name);
	/**
	 * 从HttpServletRequest.Parameter中获得指定键值对应的数据,如果该键不存在,返回空。
	 * 如果值为数组,则返回数组中的第一条记录
	 * @param name 给定的key
	 * @return  String  获得相应数据
	 */
	public String getString(String name);
	
	
	/**
	 * 获得给定的Key在HttpServletRequest.Parameter对象中的值
	 * 如果Key不在HttpServletRequest.Parameter中存在或值为null,则返回缺省值
	 * @param name  String 给定的Key
	 * @param def  String 缺省值
	 * @return  String 给定Key对应的值,如果Key不存在或者返回的值为null,则返回def
	 */
	public String getString(String name, String def);
	/**
	 * 获得给定的Key在HttpServletRequest.Parameter对象中的值
	 * 如果Key不在HttpServletRequest.Parameter中存在或值为null,则返回缺省值
	 * 如果有值,将该值转化成Integer,转换错误,则返回缺省值
	 * @param name  String 给定的Key
	 * @param def  Integer 缺省值
	 * @return  Integer 给定Key对应的值,如果Key不存在或者返回的值为null或出错,则返回def
	 */
	public Integer getInteger(String name, Integer def);
	/**
	 * 获得给定的Key在HttpServletRequest.Parameter对象中的值
	 * 如果Key不在HttpServletRequest.Parameter中存在或值为null,则返回缺省值
	 * 如果有值,将该值转化成int,转换错误,则返回缺省值
	 * @param name  String 给定的Key
	 * @param def  int 缺省值
	 * @return  int 给定Key对应的值,如果Key不存在或者返回的值为null或出错,则返回def
	 */
	public int getInt(String name, int def);
	/**
	 * 获得给定的Key在HttpServletRequest.Parameter对象中的值
	 * 如果Key不在HttpServletRequest.Parameter中存在或值为null,则返回缺省值
	 * 如果有值,将该值转化成Long,转换错误,则返回缺省值
	 * @param name  String 给定的Key
	 * @param def  Long 缺省值
	 * @return  Long 给定Key对应的值,如果Key不存在或者返回的值为null或出错,则返回def
	 */
	public Long getLong(String name, Long def);
	
	/**
	 * 获得给定的Key在HttpServletRequest.Parameter对象中的值
	 * 如果Key不在HttpServletRequest.Parameter中存在或值为null,则返回缺省值
	 * 如果有值,将该值转化成Double,转换错误,则返回缺省值
	 * @param name  String 给定的Key
	 * @param def  Double 缺省值
	 * @return  Double 给定Key对应的值,如果Key不存在或者返回的值为null或出错,则返回def
	 */
	public Double getDouble(String name, Double def);
	
	/**
	 * 获得给定的Key在HttpServletRequest.Parameter对象中的值
	 * 如果Key不在HttpServletRequest.Parameter中存在或值为null,则返回缺省值
	 * 如果有值,将该值转化成Float,转换错误,则返回缺省值
	 * @param name  String 给定的Key
	 * @param def  Float 缺省值
	 * @return  Float 给定Key对应的值,如果Key不存在或者返回的值为null或出错,则返回def
	 */
	public Float getFloat(String name, Float def);
	/**
	 * 获得给定的Key在HttpServletRequest.Parameter对象中的值
	 * 如果Key不在HttpServletRequest.Parameter中存在或值为null,则返回缺省值
	 * 如果有值,将该值转化成Boolean,转换错误,则返回缺省值
	 * @param name  String 给定的Key
	 * @param def  Boolean 缺省值
	 * @return  Boolean 给定Key对应的值,如果Key不存在或者返回的值为null或出错,则返回def
	 */
	public Boolean getBoolean(String name, Boolean def);
	
	/**
	 * 获得给定的Key在HttpServletRequest.Parameter对象中的值
	 * 如果Key不在HttpServletRequest.Parameter中存在或值为null,则返回缺省值
	 * 如果有值,将该值转化成int,转换错误,则返回缺省值
	 * @param name  String 给定的Key
	 * @param def  long 缺省值
	 * @return  long 给定Key对应的值,如果Key不存在或者返回的值为null或出错,则返回def
	 */
	public long getLong(String name, long def);
	
	/**
	 * @return HttpServletRequest.Attribute对应的AttributeMap对象
	 */
	/**
	 * 将指定的Map对象中的所有键值拷贝到HttpServletRequest.Attribute中
	 * @param attribute  给定的Map对象
	 */
	public void setAttribute(MapImpl<String, Object>  attribute);
	/**
	 * 获得给定的Key在HttpServletRequest.Attribute对象中的值
	 * 如果Key不在HttpServletRequest.Attribute中存在或值为null,则返回缺省值
	 * @param name  String 给定的Key
	 * @param def  Object 缺省值
	 * @return  Object 给定Key对应的值,如果Key不存在或者返回的值为null,则返回def
	 */
	public Object getAttribute(String name, Object def);
	/**
	 * 获得给定的Key在HttpServletRequest.Attribute对象中的值
	 * 如果Key不在HttpServletRequest.Attribute中存在或值为null,则返回null
	 * @param name  String 给定的Key
	 * @return  Object 给定Key对应的值,如果Key不存在或者返回的值为null,返回null
	 */
	public String getAttributeString(String name);
	
	public void setAttribute(String key, Object value);
	
	/**
	 * @return  获得ActionReport,如果不存在,会创建一个返回
	 */
	public ActionReport getReport();
	/**
	 * 将ActionReport中的错误提示信息设置为给定的错误信息。
	 * @param errors 给定的错误信息
	 */
	public void setActionErrors(Collection<String> errors);
	/**
	 * 添加ActionError的错误信息
	 * @param error 错误信息
	 */
	public void setActionError(String error);
	/**
	 * @return 获得ActoinError的错误信息列表
	 */
	public Collection<String> getActionErrors();
	/**
	 * 判断是否有ActionErrors错误提示信息
	 * @return  true 有  false 没有
	 */
	public boolean hasActionErrors();
	/**
	 * @return 获得Action提示信息
	 */
	public Collection<String> getActionMessages();
	/**
	 * 将ActoionReport中的提示信息设置为给定的提示信息。
	 * @param messages 给定的提示信息列表
	 */
	public void setActionMessages(Collection<String> messages) ;
	/**
	 * 添加提示信息
	 * @param message 给定的提示信息
	 */
	public void setActionMessage(String message);
	/**
	 * 判断是否有提示信息
	 * @return  true 有  false 没有
	 */
	public boolean hasActionMessages();
	/**
	 * 获得所有的字段错误提示信息
	 * @return 字段对应的错误信息Map
	 */
	public MapImpl<String, Object> getFieldErrors();
	/**
	 * 将ActionReport中的字段错误信息设置为给定的信息
	 * @param errors 字段错误提示信息
	 */
	public void setFieldErrors(MapImpl<String, Object>  errors);
	/**
	 * 给指定字段添加错误提示信息
	 * @param fieldName  给定字段
	 * @param errorMessage  错误提示信息
	 */
	public void setFieldError(String fieldName, String errorMessage);
	/**
	 * 判断是否有字段提示信息
	 * @return  true 有 false 无
	 */
	public boolean hasFieldErrors();
	/**
	 * 判断是否有错误提示信息,校验FieldErrors和ActionErrors
	 * @return  true 有  false 无
	 */
	public boolean hasErrors();
	
	/**
	 * @return 获得Connection,如果不存在,会创建一个返回
	 * @throws SQLException 
	 */
	public Connection getConnection(String dbs) throws SQLException;
		
	
	/**
	 * Forces the request to not commit the connection.
	 */
	public void setDBRollback();
	/**
	 * Check if commit is disabled or not for the current request.
	 * @return <code>true</code> if a commit should NOT be made
	 */
	public boolean getDBRollback();	
	
	/**
	 * 获取数据
	 * @param dbsName
	 * @return
	 */
	public DB getDB(String dbsName);
	
	public DB getDba();
	
	/**
	 * 设置跳转路径
	 */
	public void setRedirect(String redirect);
	
	public void setRedirect301(String redirect);
	
	/**
	 * 获取跳转路径
	 */
	public String getRedirect();
	
	/**
	 * 获取真实路径
	 * @param url
	 * @return
	 */
	public String url(String url);
	
	/**
	 * 默认标题
	 * @param title
	 */
	public void setTitle(String title);
	
	/**
	 * 默认模板
	 */
	public void setTemplate(TplFrame template);	
	
	public String getHeader(String name);
	
	public boolean isPost();	
	
	public String getMessage(String key);
	
	public String getMessage(String key, Object params[]);
	
	/**
	 * 令牌校验
	 * @return
	 */
	public String getToken();
	
	public void resetToken();
	
	public boolean validToken();
	
	public boolean isCheckedToken();
}
  Domain,AppModel,EMap,HashList,PSVessel为框架常用实例,了解几个实例有利于对实例取值。
域名实例,实现实例后可以读取域名相关的参数:jdapp.entry.Domain
package jdapp.entry;
import java.io.Serializable;
import java.util.Map;
import jdapp.mmvc.config.AppSettings;
import jdapp.mmvc.config.Constants;
import jdapp.util.BaseUtils;
/**
 * 域名实例
 * @author wushaoen
 *
 */
public class Domain implements Serializable{
	private static final long serialVersionUID = 1L;
	private String dns;
	private String deptid;
	private String style;
	private String locale;
	private int flag;
	private long createtime;
	private Integer ip;
	private Integer dnum;
	private boolean be;
	private int status;
	private int dnsid;
	private String title;
	private String rdns;
	private String encoding; 
	private long expired;
	private String rdata;
	private int rdtype;
	private int ttl;
	private String root;
	private String beRoot;
	private final int extensions;
	private String welcomeFile;
	
	
	/**
	 * 构造Domain
	 * @param map
	 */
	public Domain(Map<String, String> map){	 	
        this.dns = map.get("dns");       
        //this.isXml = Boolean.parseBoolean(map.get("xml"));  		
        //this.function = map.get("function");
        this.deptid = map.get("deptid");
        this.style =  map.get("style");        
        this.createtime = new Long(map.get("createtime"));
		this.expired = new Long( map.get("expired"));
		this.flag = Integer.valueOf(map.get("flag"));  		
		
		this.locale = map.get("locale");		
		this.ip =  Integer.valueOf(map.get("ip"));
		this.dnum =  Integer.valueOf(map.get("dnum"));
		
		//0为前台,1为后台
		this.be = Integer.valueOf( map.get("type"))==0?false:true;
		
		this.status = Integer.valueOf( map.get("status"));  
		
		this.title = map.get("title");		
		this.rdns  = map.get("rdns");		
		this.dnsid =  Integer.valueOf(map.get("dnsid"));	
		
		this.encoding = map.get("encoding");
		
		//存储目录
		this.rdata = map.get("rdata");
		this.rdtype =  Integer.valueOf(map.get("rdtype"));
		this.ttl =  Integer.valueOf(map.get("ttl"));
		
		String extensions = (String)map.get("extensions");		
		this.extensions = extensions!=null?Integer.valueOf(extensions):-1;
		String welcome = (String)map.get("welcomefile");
		 this.welcomeFile = new StringBuffer("/").append(welcome!=null && welcome.length()>1?welcome:AppSettings.getDefault("jdapp.welcomefile", Constants.JDAPP_WELCOMEFILE)).toString();
		 
		 String root = (String)map.get("root");		
		 StringBuffer d = new StringBuffer();		 
		 if(root!=null){
			 root =  AppSettings.getVarValue(root);
			 if(root.indexOf("/")!=-1){
				 d.append(root);
				 if(!root.endsWith("/"))d.append("/");
			 }else{
				 d.append(AppSettings.getStoreDirectory());
				 d.append("/domains/frontend/store/");
				 d.append(root);
				 d.append("/");
			 }
		 }else{
			 d.append(Constants.LOADER_FESTORE);
			 d.append(BaseUtils.eip(getIp()).replace(".", "/"));
			 d.append("/");
			 d.append(getDnum()/100);
			 d.append("/");
			 d.append(getDnsid());
			 d.append("/");	
		 }
		 
		 this.root = d.toString();
		 String beRoot = (String)map.get("beroot");		
		 StringBuffer bed = new StringBuffer();		 
		 if(beRoot!=null){
			 beRoot =  AppSettings.getVarValue(beRoot);
			 if(beRoot.indexOf("/")!=-1){
				 bed.append(beRoot);
				 if(!beRoot.endsWith("/"))bed.append("/");
			 }else{
				 bed.append(AppSettings.getStoreDirectory());
				 bed.append("/domains/backend/");
				 bed.append(beRoot);
				 bed.append("/");
			 }
		 }else{
			 bed.append(Constants.LOADER_BESTORE);
			 bed.append(BaseUtils.eip(getIp()).replace(".", "/"));
			 bed.append("/");
			 bed.append(getDnum()/100);
			 bed.append("/");
			 bed.append(getDnsid());
			 bed.append("/");	
		 }
		 this.beRoot = bed.toString();
    }
	/**
	 * 前台路径
	 */
	public String getRoot() {
		return  this.root;
	}
	
	/**
	 * 后台路径
	 */
	public String getBeRoot() {
		return  this.beRoot;
	}
	
	/**
	 * 默认加载文件名
	 */
	public String getWelcomeFile() {
		return  this.welcomeFile;
	}
	/**
	 * 域名编码
	 */
	public String getEncoding() {
		return encoding;
	}
	
	/**
	 * 域名
	 */
	public String getDns() {
		return dns;
	}
	/**
	 * 开发部门编号
	 */
	public String getDeptid() {
		return deptid;
	}
	/**
	 * 机构风格
	 */
	public String getStyle() {
		return style;
	}
	
	/**
	 * 区域
	 */
	public String getLocale() {
		return locale;
	}
	/**
	 * 标识
	 */
	public int getFlag() {
		return flag;
	}
	/**
	 * 标题
	 */
	public String getTitle() {
		return title;
	}   
	
	/**
	 * 是否为后台
	 */
	public boolean isBe() {
		return be;
	}
	
	/**
	 * 状态
	 */
	public int getStatus(){
		return status;
	}
	
	/**
	 * 设置状态值
	 * @param status
	 */
	public void setStatus(int status){
		this.status = status;
	}
	
	/**
	 * 根域名
	 */
	public String getRdns() {
		return this.rdns!=null?this.rdns:this.dns;
	}
	
	/**
	 * 域名解释时长
	 */
	public int getTTl() {
		return ttl;
	}
	
	/**
	 * 域名解释类型
	 */
	public int getRDtype() {
		return rdtype;
	}
	
	/**
	 * 域名解释数值
	 */
	public String getRData() {
		return rdata;
	}   
	
	/**
	 * 创建时间
	 */
	public long getCreatetime() {
		return createtime;
	}
	/**
	 * 失效时间 
	 */	
	public long getExpired() {
		return expired;
	}
	
	/**
	 * 扩展名
	 */
	public int getExtensions(){
		return extensions;
	}
	
	/**
	 * 所在的IP
	 */
	public Integer getIp() {
		return ip;
	}
	/**
	 * 域名
	 */
	public Integer getDnum() {
		return dnum;
	}
	
	/**
	 * 域名编号
	 */
	public int getDnsid() {
		return dnsid;
	}
}
      应用模型实例,实现模型后可以读取模型相关的参数:jdapp.entry.AppModel
数据输出辅助工具:jdapp.db.EMap
框架实用哈希地图:jdapp.db.HashList
数据:jdapp.db.base.PSVessel
RequestHelp,OutHelp,VariantHelper,New,DAODriver为框架常用辅助工具,也是些静态类。
客户端请求辅助工具对象:jdapp.mmvc.page.help.RequestHelp
获取常用数据辅助工具对象:jdapp.mmvc.page.help.OutHelp
数据类型转换辅助工具对象:jdapp.mmvc.page.help.VariantHelper
新建容器辅助工具对象:jdapp.util.New
DAO数据驱动对象:jdapp.dao.DAODriver
第一步:确定上传的网址为:http://127.0.0.1/upload/file.do ,域名:127.0.0.1使用的开发部门编码为:CN.SYSTEM-TA
第二步:创建上传文件模型

也可以通过SQL语句方式直接创建上传文件模型:
INSERT INTO `APPMODEL` VALUES ('upload.file.0:CN.SYSTEM-TA', '18', '7000', '4', 'utf-8', 'GET,POST', 'jdapp.plugin.attach.upload.common.UploadAction', 'uploadFile', 'default.control', 'pt.default.view', null, 'upload.file.0:PORTAL', '文件上传', null, '/', '0', '0', '10', '200', '1000', '1422780886454', '100000');
      注:通过执行SQL语句方式增加的模型是没有加载到应用缓存的,需要重新启动服务应用或在应用管理后台重新保存一下相关模型。
第三步:在相应的文件目录下创建上传文件模型模板:127.0.0.1/apptpl/do/upload/file.htm
<meta charset="UTF-8">
<form id="image_form" action="${_html.request.thisPath}" method="post" enctype="multipart/form-data" >
<input name="upload_file" type="file" />
<input type="submit" value="提交上传" />
</form>
框架已自带上传组件JAVA实例代码,可以把代码给大家学习一下:
package jdapp.plugin.attach.upload.common;
import java.io.File;
import java.io.UnsupportedEncodingException;
import java.util.Iterator;
import java.util.List;
import jdapp.exceptions.HttpException;
import jdapp.mmvc.config.AppInitializer;
import jdapp.mmvc.interfaces.APage;
import jdapp.mmvc.interfaces.JRequest;
import jdapp.mmvc.support.ActionRun;
import jdapp.plugin.attach.upload.util.legacy.commons.fileupload.FileItem;
import jdapp.plugin.attach.upload.util.legacy.commons.fileupload.FileUploadException;
import jdapp.plugin.attach.upload.util.legacy.commons.fileupload.disk.DiskFileItemFactory;
import jdapp.plugin.attach.upload.util.legacy.commons.fileupload.servlet.ServletFileUpload;
import jdapp.util.StringUtil;
/*
 * 文件上传组件实例
 * @author wushaoen
 *
 */
public class UploadAction extends ActionRun {
	
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	
	/**
	 * 上传文件的页面必需设置为utf-8,否则上传来的中文文件会是乱码
	 * <ul>
	 * <li>表单配置:
	 * <form method="post" enctype="multipart/form-data" accept-charset="utf-8" action="/upload/file.do">
	 * <input type="file" name="upload_file"  />
	 * <input type="submit" value="提交上传" />
	 * </form>
	 * </li>
	 * </ul>
	 */
	
	public String execute(APage page) throws Exception {	
		this.$page = page;
		processUpload();
		return SUCCESS;
	}
	
	
	/**
	 * 打印上传文件表单内容
	 */
	public void uploadFile(){
		if($page.isPost())
			postFileForm();
		
	}
	
	
	/**
	 * 处理上传文件
	 */
	public void postFileForm(){
		Object uploadFile = $page.getRequest().getParameterMap().get("upload_file");
		
		if(uploadFile != null){
			FileItem item = (FileItem)uploadFile;
			
			UploadUtils uploadUtils = new UploadUtils(item);
			
			String uploadFileName = stripPath(uploadUtils.getRealName());
			
			String saveFolder = StringUtil.decode($page.getRequest().getDomain().getRoot());
			
			uploadUtils.saveUploadedFile(new StringBuffer().append(saveFolder).append(uploadFileName).toString());	
		}
	}
	/**
	 * 检查文件上传
	 */
	public void processUpload(){
		JRequest request = $page.getRequest();
		boolean isMultipart = false;
		isMultipart = ServletFileUpload.isMultipartContent(request);
		if(isMultipart)handleMultipart(request);
	}
	
	/**
	 * 处理文件上传
	 * @param request
	 */
	private void handleMultipart(JRequest request){
		File tmpDir = (File)AppInitializer.getInstance().getServletContext().getAttribute("javax.servlet.context.tempdir");
		ServletFileUpload upload = new ServletFileUpload(	new DiskFileItemFactory(100 * 1024, tmpDir));
		String encoding = request.getModel().getEncoding();
		upload.setHeaderEncoding(encoding);			
		try {
			List<FileItem> items = upload.parseRequest(request);			
			for (Iterator<FileItem> iter = items.iterator(); iter.hasNext();) {
				FileItem item = (FileItem) iter.next();				
				if (item.getSize() > 0) {
					if (item.isFormField()) {
						//Log.debug(item.getFieldName()+" = "+item.getString(encoding));
						request.getParameterMap().put(item.getFieldName(),item.getString(encoding));
					}else{
						//Log.debug(item.getFieldName());
						
						request.getParameterMap().put(item.getFieldName(), item);		
					}
				}
			}
		} catch (FileUploadException e) {
			throw new HttpException(
					"Error while processing multipart content: " + e);
		} catch (UnsupportedEncodingException e) {
			throw new HttpException(
					"Error while processing multipart content: " + e);
		}
	}
	
	
	
	/**
	 * 读取上传文件的真实名
	 * @param realName
	 * @return
	 */
	public String stripPath(String realName)
	{
		String separator = "/";
		int index = realName.lastIndexOf(separator);
		
		if (index == -1) {
			separator = File.separator;
			index = realName.lastIndexOf(separator);
		}
		
		if (index > -1) {
			realName = realName.substring(index + 1);
		}
		
		return realName;
	}
}
可以创新一个新的上传文件类,自定义上传文件目录和对上传的文件进行处理,以上只是个实例作参考用。
JDAPP是一个具备站群功能的框架,用户可以把文件保存到指到不同域名的存储柜目录下,通过以下方法可以读取www.byoou.com的存储柜:RequestHelp.getDoamin("www.byoou.com").getRoot()。
第一步:确定验证码的网址为:http://127.0.0.1/validate/captcha.gif ,域名:127.0.0.1使用的开发部门编码为:CN.SYSTEM-TA
第二步:创建验证码应用模型

也可以通过SQL语句方式直接创建验证码应用模型:
INSERT INTO `APPMODEL` VALUES ('validate.captcha.0:CN.SYSTEM-TA', '18', '0', '64', 'utf-8', 'GET', 'jdapp.mmvc.page.ValidateCode', 'captcha', 'notview.control', 'none.view', '', 'none', 'Validate Code', null, '/', '0', '0', '1', '200', '50', '0', '100');
      第三步:需要重新启动服务应用或在应用管理后台搜索出validate.captcha.0:CN.SYSTEM-TA模型并重新提交保存一下模型。
第四步:在浏览器地址输入:http://127.0.0.1/validate/captcha.gif;即可以看到如下以数值效果验证码,当然你查到的数值是不一样的:

组件提供参数new=true更新验证码值:http://127.0.0.1/validate/captcha.gif?new=true
框架已自带验证码组件JAVA实例代码,可以把代码给大家学习一下:
<meta charset="UTF-8">
<form id="image_form" action="${_html.request.thisPath}" method="post" enctype="multipart/form-data" >
<input name="upload_file" type="file" />
<input type="submit" value="提交上传" />
</form>
框架已自带上传组件JAVA实例代码,可以把代码给大家学习一下:
package jdapp.util.image;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.util.Random;
import jdapp.entry.VerifyImage;
import jdapp.exceptions.CaptchaException;
import jdapp.mmvc.interfaces.IVerifyCode;
/**
 * 默认验证码组件
 * @author wushaoen
 *
 */
public class Captcha implements IVerifyCode {
	private static final long serialVersionUID = 1L;
	public static Captcha classInstance = new Captcha();
	public static Captcha getInstance() {
		return classInstance;
	}
	public VerifyImage getNextImageCaptcha(String defaultQuestion) {
		if (defaultQuestion != null && defaultQuestion.length() < 4)
			throw new CaptchaException("验证码不得小于四位数");
		// 验证码宽和高
		int width = 60, height = 20;
		// 创建图片对象
		BufferedImage image = new BufferedImage(width, height,
				BufferedImage.TYPE_INT_RGB);
		Graphics g = image.getGraphics();
		Random random = new Random();
		// 填充指定的矩形
		g.fillRect(0, 0, width, height);
		// 设置字体
		Font[] fontsList = new Font[] { new Font("Arial", Font.BOLD, 10),
				new Font("Tahoma", Font.BOLD, 10),
				new Font("Verdana", Font.BOLD, 10),
				new Font("Times New Roman", Font.BOLD, 18) };
		for (int i = 0; i < fontsList.length; i++) {
			g.setFont(fontsList[i]);
		}
		// 设置制图对象的颜色
		g.setColor(getRandColor(200, 250));
		// 设置随机颜色
		g.setColor(getRandColor(180, 200));
		// 背景线条
		for (int i = 0; i < 100; i++) {
			int x = random.nextInt(width);
			int y = random.nextInt(height);
			int xl = random.nextInt(20);
			int yl = random.nextInt(20);
			g.drawLine(x, y, y + x + xl, x + y + yl);
		}
		String question = "";
		for (int i = 0; i < 4; i++) {
			String rand = defaultQuestion != null ? defaultQuestion.substring(
					i, i + 1) : String.valueOf(random.nextInt(10));
			question += rand;
			g.setColor(new Color(20 + random.nextInt(100), 20 + random
					.nextInt(100), 20 + random.nextInt(100)));
			g.drawString(rand, 13 * i + 6, 16);
		}
		g.dispose();
		VerifyImage vi = new VerifyImage();
		vi.setCode(question);
		vi.setImage(image);
		return vi;
	}
	public Color getRandColor(int fc, int bc) {
		Random random = new Random();
		if (fc > 255)
			fc = 255;
		if (bc > 255)
			bc = 255;
		int r = fc + random.nextInt(bc - fc);
		int g = fc + random.nextInt(bc - fc);
		int b = fc + random.nextInt(bc - fc);
		return new Color(r, g, b);
	}
}
验证码接口jdapp.mmvc.interfaces.IVerifyCode提供自定义内容和风格的图片效果,但目前还没有提供语音式验证,目前除了默认的验证码框架还做了Kaptcha验证码模式,对象类为jdapp.plugin.kaptcha.provider.Kaptcha。
在JAVA应用Action里可以通过以下方法取得验证码数值:$page.getSession().getHttpSession().getAttribute("_img_captcha");而在WEB应用可以通过以下方法显示验证码数值:
${_html.session.httpSession.getAttribute("_img_captcha")?default("")}
最后一步:在对比提交的验证值如果验证成功即需要把验证码清空,清空的方法在JAVA应用Action里使用:$page.getSession().getHttpSession().removeAttribute("_img_captcha");WEB应用可以通过以下方法显示验证码数值:
<#assign null = _html.session.httpSession.removeAttribute("_img_captcha")/>
      框架的启动时加载的引导代理对象后运行起来的,可以通过以下SQL语句增加FTP组件在架构上运行:
INSERT INTO `PROXY_OBJECT` VALUES ('ftp.server', 'FTP服务器', 'boots', 'jdapp.component.ftpserver.FtpServerD', null, '10', '1', '90200');
      框架如果有运行FTP组件,在启动时调试日志中可以查看到相关的信息打印出来:
12:28:24,381 DEBUG [main] (AppInitializer.java:310) - Inited object: jdapp.component.ftpserver.FtpServerD (use time:7 ms)
除了在引导代理对象中有提示启动FTP组件名,还可以通过修改配置文件jdapp.xml是否启动,端口以及绑定的IP地址:
<?xml version="1.0" encoding="UTF-8"?>
<jdapp> 
        <ftpserver>
                <enabled>false</enabled>
                <ip>127.0.0.1</ip>
                <port>21</port>
        </ftpserver>
</jdapp>
FTP组件的账号管理可以在系统管理后台的主账号管理功能维护:
先了解一下DNS服务组件启动后在日志有些什么信息打印出来:

以下信息为引导代理对象启动时打印出来的信息:
			
20:08:41,387 DEBUG [main] (AppInitializer.java:310) - Inited object: jdapp.component.name.Named (use time:289 ms)
      
以下信息为操作系统请求域名服务时打印出来的信息:
			
20:08:48,792 DEBUG [Thread-6] (Named.java:501) - Lookup name: www.byoou.com.
			
20:08:48,794 DEBUG [Thread-6] (Named.java:501) - Lookup name: 127.0.0.1.byoou.com.
      
框架的启动时加载的引导代理对象后运行起来的,可以通过以下SQL语句增加DNS服务组件在架构上运行:
INSERT INTO `PROXY_OBJECT` VALUES ('dns.named', '域名服务器', 'boots', 'jdapp.component.name.Named', null, '10', '1', '90100');
      除了在引导代理对象中有提示启动DNS服务组件,还可以通过修改配置文件jdapp.xml,enabled值为是否启动,绑定的IP地址以及端口port,nsrdata默认DNS解释到IP:
<?xml version="1.0" encoding="UTF-8"?> <jdapp> <named> <enabled>false</enabled> <ip>192.168.1.26</ip> <port>53</port> <nsrdata>@ 192.168.1.39</nsrdata> </named> </jdapp>
配置文件jdapp.xml还可以通过修改DNS服务组件语句替换默认IP127.0.0.1指向其它的IP,例如:192.168.1.39
<?xml version="1.0" encoding="UTF-8"?> <jdapp> <database> <select> <domain><![CDATA[SELECT DNS, RDNS, DNSID, DEPTID, TITLE, STYLE, LOCALE, ENCODING, WELCOMEFILE, REPLACE(RDATA,'@ 127.0.0.1','@ 192.168.1.39') AS RDATA, RDTYPE, TTL, IP, DNUM, CREATETIME, EXPIRED, EXTENSIONS, TYPE, FLAG, STATUS, FROMURL, ROOT, BEROOT FROM MMVC.DOMAIN WHERE STATUS!=404]]></domain> </select> </database> </jdapp>
DNS服务组件可以在系统管理后台的域名管理功能维护:
DNS服务启动后还需要修改本地客户端的DNS服务器地址:
 
首先DNS服务器为127.0.0.1
备用DNS服务器为8.8.8.8
当然也可以是本地局域网的网关,例如:192.168.1.1
也可以是宽带上网服务提供商指定的DNS服务器,例如:202.103.44.150
在Internet协议版本4 (TCP/IPv4)属性的对话框右下角有个高级按钮,点击打开一个对话框,中间有个DNS表单里有个DNS服务器列表设置:
 
请求的DNS服务器列表是有优先顺序的
如果你是在开发过程中使用DNS服务组件,除了在“Internet协议版本4 (TCP/IPv4)属性”设置DNS服务器IP外,还需要把服务里的DNS Client服务禁止:
 
如果你不想用DNS服务组件做域名解释,可以直接通过系统绑定域名和IP地址,通过修改系统hosts文件即可:
C:\Windows\System32\drivers\etc\hosts 
设置域名指定IP地址,例如把www.yunjd.net指定到IP地址为:192.168.1.39
 
框架提供I18n多语种功能支持,指用户定制区域显示语言,简单的说是指如果代码上的文字加载的I18n消息文字,页面就支持多语言版本。
I18n多语种消息文字存储在MMVC数据库下面的数据表里:
 
 
下面了解一下中文的I18n多语种消息文字
 
 
I18n多语种功能取得文字信息非常简单,在WEB应用中可以通过${_html.getMessage("user.access.denied")}即可以区域表Name字段名为user.access.denied的值,而JAVA应用中则是可以通过$page.getMessage("user.access.denied")。
      框架的多语种功能还提供通过参数方式传递到值里,例如:$page.getMessage("user.join.account.same", new String[]{account})
I18n多语种是在应用启动时加载在jdapp.repository.I18nCache存储柜实例中,框架在I18nCache存储柜还提供指定区域语种信息,相关的方法可以通过文档jdapp_0.3.0.chm索引出来了解。
jdapp框架对JAVA应用模型做了四种优化方案:
方案一:JAVA应用模型的网址可以自定义后辍名,框架默认已定义为A.(html) B.(htm) D.(do) E.(jsp) F.(txt) G.(xml) H.(gif),当然是可以修改框架进行别的后辍名定义的。
方案二:路径参数转目录方式 <moduleName>/<actionName>/<numberOfParameters>
例如:优化前的网址为http://www.yunjd.net/keywords/tags?q=led 优化后的网址为 http://www.yunjd.net/keywords/tags/led.html
在JAVA逻辑里可以通过
$page.getParamUrl(numberOfParameters);
$page.getRequest().getParamUrl(numberOfParameters);应用方法参数目录层数获得参数字符内容
而在freemarker模板里可以通过
${_html.getParamUrl(numberOfParameters)}
      ${_html.request.getParamUrl(numberOfParameters)}
      应用方法参数目录层数获得参数字符内容
      
       方案三:目录反斜杠/换成减号- <moduleName>-<actionName>-<numberOfParameters>
例如:优化前的网址为http://www.yunjd.net/keywords/tags?q=led&power=5 优化后的网址为 http://www.yunjd.net/keywords/tags-led-5.html
在JAVA逻辑里通过以下方法$page.getParamUrl(1);读取参数内容可以为:led
在JAVA逻辑里通过以下方法$page.getParamUrl(2);读取参数内容可以为:5
方案四:一/二级路径重索引目录层数为00数字参数模型 <moduleName>/<actionName>-<00>
索引模型的逻辑为:模型引擎索引不到一/二级路径级应用模型会重索引目录层数为00数字参数模型
	00数字参数是可自定义的,可以通过下面的取值方法了解到:		
	
	MODELID_ALL = AppSettings.getDefault("jdapp.request.modelid.all",".index.00");
	
	MODELID_ALL_DIR = AppSettings.getDefault("jdapp.request.modelid.all.dir", "index.index.00");
HTTP状态码(HTTP Status Code)是用以表示网页服务器HTTP响应状态的3位数字代码。框架有默认的状态码页面的效果输出,也提供域名个性化状态码的模型设计。
HTTP状态码的作用是:Web服务器用来告诉客户端,发生了什么事。状态码位于HTTP Response 的第一行中,会返回一个”三位数字的状态码“和一个“状态消息”。 ”三位数字的状态码“便于程序进行处理, “状态消息”更便于人理解。
每个域名设计的效果不同,跟框架默认提供的风格可能不搭配,所以网站开发好做优化过程通常要做一次HTTP状态码 404/500/502/503/504的错误代码页面风格的设计。
框架默认使用的404没找到页面加载应用模型是:error.http404.0:CN.SYSTEM-TA,对应的域名要个性化404状态码的页面只需要创新一个替换CN.SYSTEM-TA开发部门的模型并修改好模板即可。
      框架使用的是 jdapp.mmvc.page.help.RequestHelp.getNotFound(String deptid)方法实现的。
其它的错误状态码要个性化也是一样只需要创新一个替换CN.SYSTEM-TA开发部门的模型并修改好模板即可,例如:error.http500.0:CN.SYSTEM-TA
      框架使用的是jdapp.mmvc.page.help.RequestHelp.getSystemError(String deptid)方法实现的。
     
      
表 1.00. 常用加密和解密方法说明表:
| 加密和解密类 | 说明 | 方法 | 
|---|---|---|
| MD5 | 框架提供MD5不可逆转的加密方法: | jdapp.util.encrypt.MD5.crypt("cryptString") | 
| SHA | 框架提供SHA安全哈希算法可逆转的加密方法: | jdapp.util.encrypt.SHA.encrypt("encryptString") | 
| SHA | 框架提供SHA安全哈希算法可逆转的解密方法: | jdapp.util.encrypt.SHA.decrypt("decryptString") | 
| GBC | 框架提供在Base64中,码表是由[A-Z,a-z,0-9,+,/,=(pad)]组成的GBC字符串的算法可逆转的加密方法: | jdapp.util.encrypt.GBC.encode("wushaoen")。 | 
| GBC | 框架提供在Base64中,码表是由[A-Z,a-z,0-9,+,/,=(pad)]组成的GBC字符串的算法可逆转的解密方法: | jdapp.util.encrypt.GBC.decode("OdaXGaDBNdSWc")。 | 
| URLDecoder | 框架提供对网址路径 x-www-form-urlencoded 字符串加码方法: | RequestHelp.encode("http://www.byoou.com/abc test") | 
| URLDecoder | 框架提供对网址路径 x-www-form-urlencoded 字符串解码方法: | RequestHelp.decode("http://www.byoou.com/abc_test") | 
| JavaScript escape | 在做ajax过程中可能会用到JavaScript escape() 函数,后台可以通过以下方法对函数字符解码: | org.apache.commons.lang.StringEscapeUtils.unescapeJavaScript("\u4F0D\u5C11\u6069") | 
| JavaScript escape | 在做ajax过程中可能会用到JavaScript escape() 函数,后台可以通过以下方法对函数字符加码: | org.apache.commons.lang.StringEscapeUtils.escapeJavaScript("伍少恩") | 
JDAPP框架在【生产环境】的web.xml
<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
	version="2.4">
		<context-param>
			<param-name>un.log4j.conf</param-name>
			<param-value>false</param-value>
		</context-param>
		<context-param>
			<param-name>un.log4j</param-name>
			<param-value>false</param-value>
		</context-param>
		<context-param>
			<param-name>myStore.path</param-name>
			<param-value>/jdapp/bydc</param-value>
		</context-param>
		<display-name>JDAPP</display-name>
		<description>JD APPLICATION(简单应用|基地应用框架)</description>
		<distributable/>
		<context-param>
			<param-name>my-package</param-name>
			<param-value></param-value>
		</context-param>
		<servlet>
			<description>MVC SERVLET</description>
			<servlet-name>page</servlet-name>
			<servlet-class>jdapp.mmvc.PageServlet</servlet-class>
			<load-on-startup>1</load-on-startup>
		</servlet>
		<servlet-mapping>
			<servlet-name>page</servlet-name>
			<url-pattern>/*</url-pattern>
		</servlet-mapping>
		<session-config>
			<session-timeout>30</session-timeout>
		</session-config>
		<listener>
			<listener-class>jdapp.mmvc.PageListener</listener-class>
		</listener>
</web-app>
          设置为缓存集群后的JDAPP框架在【集成测试环境】的JVM 启动参数
JAVA_OPTS=" -Xms512m -XX:PermSize=64M -XX:MaxPermSize=128m -Xms512m -Xmx1024m -Djdapp.home=/jdapp/home -DconfigFile=/yunjd/installed/tomcat/conf/jdapp.xml -Djava.net.preferIPv4Stack=true -Djava.net.divferIPv4Stack=true -Djgroups.bind_addr=192.168.1.35 -Djava.rmi.server.hostname=192.168.1.35 -Dcom.sun.management.jmxremote.port=9090 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Djmagick.systemclassloader=no "