1 背景概述
相信很多了解数通畅联软件的人对AEAI DP应用开发平台并不陌生,笔者在入职第一天就开始接触AEAI DP,使用AEAI DP开发过AEAI WM、AEAI CRM以及中国XXXX管理系统项目,在此过程中对AEAI DP有了较为深入了解,工作之余尝试对AEAI DP的工作原理、实际开发工作涉及的技术点进行梳理,希望能够对其他AEAI DP初学者和使用人员有所帮助。
本文相关说明涵盖AEAI DP的远程热部署新特性,AEAI DP V3.5以后版本支持按工程、模块、资源不同粒度实现代码远程增量部署,类似AEAI ESB中的按流程、服务、工程远程热部署模式。
2 预期读者
3 技能要求
了解Java Web开发过程,熟悉相关知识点
对AEAI DP技术手册所涉及的内容熟练掌握
4 架构及原理
4.1 DP产品架构解读
AEAI DP开发平台包括三部分,第一部分是一站式的Java Web框架,在数通畅联软件家族中命名为Hotweb,第二部分基于Eclipse插件的扩展开发设计器,在数通畅联软件家族中命名为Miscdp Studio,第三部分是用于开发调试的服务器HotServer。基于Miscdp Studio可以开发普通Java Web应用、集成Java Web应用,还可以为BPM流程平台开发业务表单及流程相关功能。
Hotweb是一站式的MVCFramework,对前端页面交互及控制层做了统一封装,各类功能模型的交互方式封装在父类中。每个页面提供一个Handler处理Java类和展现JSP页面,一个功能可能涉及多个页面,复用一套业务逻辑处理Service和通用的数据存取持久工具类DAOHelper,在Service层调用通用数据存取类DAOHelper。数据持久层基于IBatis封装,Service层基于Spring来做事务控制和服务配置。
4.2 Howeb交互机制
DispatchServlet:前端请求分发,配置于web.xml
Handler:具体请求动作处理及控制,调用Service,返回ViewRender
Service:后台业务处理,包括接口及实现,Spring配置,通过DaoHelper调用SQLMap
SQLMap:负责数据持久化处理(CRUD)
ViewRender:前端展现渲染方式定义,实例化PageBean,放置于request的attributes中
PageBean:承载前端展现的属性、方法
JSP:具体页面代码,使用PageBean来获取handler中设置相关数据。
典型请求页面交互过程模式如下:
Servlet根据HandlerId实例化Handler、根据actionType反射调用对应的处理方法,方法名跟actionType一致
在对应方法中,调用Spring配置的Service来存/取数据库
如果是ajaxRender直接response返回页面,异步加载或者做相关处理
如果是dispatchRender,一般是转向其他的handler来进行处理
如果是LocalRender,直接调用prepareDisplay来做处理
4.3 典型目录层次结构
如上图:module该目录是放置各模块的代码,每个模块有各自的Handler、Service、SQLMap以及配置文件,这种文件结构模式能够支持AEAI DP实现按模块来部署。
common包里放置的是公共类,controller包里方式放置的框架级handler,cxmodule里面方式的公共service接口和实现类。
4.4 核心配置文件说明
通过AEAI DP平台开发生成相关的配置,下面对核心配置文件进行说明:
4.4.1 web.xml配置
在web.xml中包含filter的定义以及实现
Servlet的定义以及实现
以及Listener
4.4.2 Handler配置
1. HandlerIndex.xml:定义了HandlerId所属的模块,通过Id对应的模块查找对应模块下的映射关系
2. HandlerModule.xml与HandlerContext.xml中均映射关系指向对应的Handler以及JSP。其中HandlerModule.xml中定义的是不同模块下的映射关系而HandlerContext.xml中是公共访问的如主页、左侧功能列表的显示等。
4.4.3 Service 配置
1. ServiceContext.xml中典型配置属性:如数据库、appConfig等;
2. ServiceIndex.xml:通过seviceId所对应的模块去对应模块下的ServiceModule.xml配置文件中查找对应的ServiceImpl以及SqlMap等信息
3. ServiceModule.xml将对应功能模块下的Service层Controller层,用到的java类封装成bean,并通过property指定对应的SqlMap。
4. ServiceContext.xml中,配置了公共调用的Service的实现、配置数据库连接、以及事务控制机制。
4.4.4 DB 相关配置
1. hotweb.properties:配置了数据库的连接信息,如用户名、密码等。
2. SqlMapModule.xml与SqlMapConfig.xml:是sqlmap的索引文件
3. sqlmap:在对应的xml中定义SQl进行数据库操作,sqlMap文件的namespace默认是由表名来生成,在ServcieContext.xml(ServiceModule.xml)中指向业务处理ServiceImpl中
5 开发与部署
5.1 工具设置
5.2 开发步骤
AEAI DP开发平台基于数据库驱动开发,推崇适度需求调研、数据库设计先行、原型驱动的敏捷开发模式。整体过程如下:
1. 通过工程向导创建可运行调试的工程框架,默认预置系统管理功能
2. 设计器向导选择对应的功能模型,来创建功能实例
3. 功能实例配置信息首先通过数据表或SQL来默认生成
4. 在设计器进行特定调整(如:查询条件、显示字段、表单元素、校验控制等)
5. 由代码生成器,生成相关的代码及配置
6. 直接部署运行,查看效果,根据实际需要调整设置,重复4—6步
7. 根据实际需要扩展功能代码、调试。
注意:一旦扩展了代码,就不能再次代码生成,那样会覆盖扩展的代码。
5.2.1 开发约束说明
所有的表都需要创建UUID逻辑主键(36位)
所有编码类数据在编码管理模块中统一维护
如果列表SQL有参数需要解析,必须有“where 1=1”
建议开发采用SVN或者CVS进行版本管理
如果选择上载资源,则资源关联表,只能三个字段,除了逻辑主键,另外两个字段必须为“BIZ_ID”、“RES_ID”,字段类型都为char(36),建议主键命名为“REF_ID”
6.2.2 跨模块调用说明
在AEAI DP中各个功能模块是彼此隔离的,这里就可能存在跨模块调用问题:
跨模块调用handler
不需要做特殊处理,仍然index?SomeHandlerID方式调用跨模块的handler。
跨模块调用service
把对应的接口提升到cxmodule包里,可以采用代码重构的方式,选中对应接口类,然后ctrl+shift+v。
跨模块调用sqlmap
把sqlmap索引配置迁移公共索引配置(即SqlMapModule.xml中对应配置迁移至SqlMapConfig.xml),模块中的sqlmap文件也对应迁移公共sqlmap目录。
5.2.3 常用Java类清单
类别
常用类
功能说明
编码定义及界面元素
FormSelectFactory
基于编码定义的表单下拉框Select工厂类
FormSelect
表单下拉框Select泛化模型
RadioGroup
RadioButton模型,一般基于FormSelect转换生成
CheckBoxGroup
CheckBox模型,一般基于FormSelect转换生成
树构建器及模型
TreeBuilder
树形模型构建类
TreeModel
树形泛化模型,可以生成前端的多选、单选框
权限相关
Profile
身份权限概要模型,在Handler中可以直接获取
User
用户模型,可以通过Profile来获取
Role
角色模型,可以通过User来获取
Group
分组模型,可以通过User来获取
Resource
资源模型,可以通过User来获取
数据库存取相关
DaoHelper
数据访问对象工具类,封装ibatis的相关操作
DBHelper
数据操作工具类,基于Spring的数据源配置
KeyGenerator
主键生成类,一般情况下是UUID格式
工具类相关
DateUtil
日期处理工具类
StringUtil
字符串处理工具类
FileUtil
文件处理工具类
IOUtil
输入输出流工具类
5.3 部署方式
双击项目名弹出如下界面,可以修改服务器的地址并修改对应的用户名,连接对应的服务器后部署应用即可。
注意:服务器用户名、密码在Hotserver中有对应的配置,如下图:
在Miscdp Studio对工程中任意目录、文件都可以右键,在右键菜单底部点击“Miscdp资源部署”,如下图:
弹出部署设置窗口,AEAI DP支持三种粒度部署模式:模块、资源、应用。应用就是整个工程,模块指的module目录下的各个package,除了module下的文件,其他都属于资源。可以支持多个模块或者多个资源一起部署,而且内置的部署机制会自动识别,是否要重新加载模块或者重启应用。
5.3.1 按资源部署
在除模块下部署jsp,xml,js,java文件等为资源部署。当部署的内容包含源码时,会默认重启应用
部署的内容不包含源码时默认不会重启应用,且支持同时部署多个资源文件。
5.3.2 按应用部署
在项目名下右键资源部署为部署应用且默认重启应用。
5.3.3 按模块部署
在模块下选择xml、java文件等右键部署资源均为模块部署,默认会重新加载这个模块
注意:在模块的jsp文件夹下右键资源部署(弹出界面如上图)也为模块部署,默认会重新加载部署的模块。但是如果选择是模块jsp文件夹下的jsp文件,则为部署资源,且不用重启应用(jsp是自动编译)。
5.3.4 部署后目录
正常情况下Web应用的所有的classes都在WEB-INF/classes目录下,但基于AEAI DP开发的Web应用部署后有一个特殊目录modules,所有模块里的classes以及对应的配置文件都放置在这个目录里,如下图。
5.4 调试配置
远程调试是复杂业务逻辑的错误定位过程中常用手法,通过调试也可以使程序员对代码脉络更清楚,是程序员必备的技能。AEAI DP 基于Eclipse内置远程机制进行代码调试,具体参见《AEAI DP开发平台技术手册》中的调试配置部分内容。
6 知识点汇总
6.1 分层解读
6.1.1 控制层
对应的Handler如下图:
1. prepareDisplay方法
在handler中默认执行prepareDisplay方法
mergeParam(param)方法中通过handlerId的对比确定需要append的param的信息
storeParam方法在页面间跳转时候,将param存到一个session中,跟mergetParam联合使用保证在页面间切换时候,列表页面的查询条件不丢失。
setAttributes(param)方法中做遍历将param中的值进行set将数据放入到页面中
返回new LocalRenderer(getPage()),在LocalRenderer中的executeRender方法中创建PageBean,所有handler中的属性信息都传入至PageBean中,通过request.setAttribute(PAGE_BEAN_KEY,pageBean)方法将handler信息放入页面所以在JSP中可以通过pageBean中封装的getHandlerURL()获得handlerURL。
2. processPageAttributes方法
processPageAttributes方法用于回调处理扩展属性(下拉框处理、默认值处理)
3. initParameters方法
initParameters方法中可以设置查询条件的默认值
4. getService方法
在getService方法中返回到对应的调用的Service
5. 扩展方法机制说明
方法名与actionType隐藏域变量一致,建议采用@PageActionanotation方式,如果不添加@PageAction,则方法名为do+”actionType”+Action
6.1.2 显示层
顾名思义显示层就是用于前台显示的jsp页面如下图:
1. Page指令
通过Page指令的contentType将页面编码定义为UTF-8
pageEncoding是jsp文件本身的编码
contentType的charset是指服务器发送给客户端时的内容编码
2. Jsp动作
通过jsp在头部useBean在页面引用的javaBean(即pageBean),其中class属性指定类的实例并将其绑定到名由id属性定义的变量上,scope为request,如下:
相关jsp内置方法如下:
jsp:include:在页面被请求的时候引入一个文件。
jsp:useBean:寻找或者实例化一个JavaBean。
jsp:setProperty:设置JavaBean的属性。
jsp:getProperty:输出某个JavaBean的属性。
jsp:forward:把请求转到一个新的页面。
jsp:plugin:根据浏览器类型为Java插件生成OBJECT或EMBED标记
3. Jsp表单
一般情况下页面均会包含一个表id为form1,且内部有一个隐藏域actionType在表单提交时需要赋值。
一般情况下明细表单除了actionType以外还会包含一个operaType隐藏域,用来区分当前操作的状态是insert还是 update。
在form表单中action动作指令通过pageBean.getHandlerURL()获得handler指定跳转的路径,method="post"提交方式为post
4. 资源文件
在Jsp页面中引入通用的资源文件:
<%@include file="/jsp/inc/resource.inc.jsp"%>在该页面中包括常用的javascript及css
在script中定义页面处理的JS,也可以直接引用封装与于Util.js中常见的页面校验(非空、长度等)、请求方法(doDelete、doSubmit)等
util.js中封装了常用js方法如:
function doDelete(itemValue)
function doQuery(params)
function doRequest(actionType,params)
function doSubmit(reqOptions)
function postRequest(form,params)(ajax处理)
function sendRequest(targetUrl,params) (ajax处理)
style.css为最常用css,其中定义form、table、tr、td样式以及按钮的图标样式等
6.1.3 服务层
后台业务逻辑生成接口与实现类如下图:
后台业务逻辑都生成接口与实现类,都在ServiceContext.xml(ServiceModule.xml)中配置。在实现类中定义对数据库的操作
1. 继承关系说明
每个功能模型都有自己的父类和接口,继承关系如下图所示:
2. processDataType
根据数据表的元数据来转换处理表单传过来的数据,可以扩展设置类型转换器,类型转换器扩展设置在ServiceContext.xml或者ServiceModule.xml中配置,BaseService中对应代码如下:
protected void processDataType(DataParam dataParam,String tableName){
Table table = getTableMetaData(tableName);
List dateColumns = table.getDateTypeColumns();
int count = dateColumns.size();
for (int i=0;i < count;i++){
Column column = dateColumns.get(i);
String columnName = column.getName();
Object paramValue = dataParam.getObject(columnName);
if (paramValue != null && paramValue instanceof String){
if (!String.valueOf(paramValue).trim().equals("") && !String.valueOf(paramValue).trim().equals("null")){
Date dateValue = DateUtil.getDateTime((String)paramValue);
dataParam.put(columnName,dateValue);
}else{
dataParam.remove(columnName);
}
}
}
if (!this.fieldConvertMap.isEmpty()){
Iterator keys = this.fieldConvertMap.keySet().iterator();
while (keys.hasNext()){
String key = keys.next();
Column column = table.getColumn(key);
if (column != null){
DataParamConvert convert = this.fieldConvertMap.get(key);
Object value = dataParam.get(key);
Object convertValue = convert.convert(value, column);
dataParam.put(key,convertValue);
}
}
}
}
3. processPrimaryKeys
处理主键默认生成机制,AEAI DP中默认是使用uuid来作为主键的,其实框架层面还支持自增字段主键机制。
protectedvoid processPrimaryKeys(DataParam param){
KeyGenerator keyGenerator = new KeyGenerator();
if (Constants.PKType.INCREASE.equals(pkGenPolicy)){
param.put(primaryKey,keyGenerator.getMaxId(tableName, primaryKey,getDataSource()));
}
elseif(Constants.PKType.CHARGEN.equals(pkGenPolicy)){
String genPk = keyGenerator.genKey();
param.put(primaryKey,genPk);
}
}
6.2 重点技术
6.2.1 常用方法
1. 在PageBean中封装了常见的页面中获取值的方法,如下:
public String inputDate(String key)
public String inputTime(String key)
public String inputValue(int i,String key)
public String selectValue(int i,String key,String formSelectKey)
public RadioGroup selectRadio(String elementName)
public String selectedValue(String elementName)
public String selectedText(String elementName)
public String disabled(boolean expression)
public String readonly(String expression)
2. 根据需要返回不同的ViewRender,一般情况下为:AjaxRender、DispatchRender、RedirectRenderer、LocalRender
1) AjaxRender:直接response返回值页面,异步加载或者做相关处理
2) DispatchRender:一般是转向其他Handler来进行处理,页面跳转传递request和response可以支持跳转到第三方按Backspace可以返回
3) RedirectRenderer:也是转向其他Handler但不能传递request和response
4) LocalRender:显示 JSP页面
3. DateUtil类中预置许多关于日期处理的方法,例如:日期的格式化,日期的计算,获得当月、当年的第一天等等。
4. 主键生成
调用KeyGenerator.instance().genKey()来自动生成主键ID
5. 加密解密
通过CryptionUtil中的加密解密方法进行加密解密
加密方法encryption("root", "12345678");其中root为需要加密的明文、”12345678”为加密的KEY。
解密方法decryption(secretData, secretKey);
6. 在User类中预置了许多关于User的跟角色、群组关联属性等
7. Dataparam转换
DataRow调用row.toDataParam();
List调用ListUtil.toParamList(records,srcKeys, replaceKeys)
8. StringUtil字符串辅助类
agileai_common的jar包中内置了很多辅助类,如StringUtil,DataUtil,ListUtil、DBUtil等。
9. ListUtil类转换方法
预置许多List转换方法如listToMap()、toXML()、toDataSet()、toParamList()
10. PopupBox.js中封装基于div+iframe的弹出框
Js中使用PopupBox方法时需要将对应的var写在方法的外面,每次调用使用的都是同一个弹出框,写在方法内部时每次调用方法都会新生成一个弹出框。
11. 内置Ajax处理方式
functionpostRequest(form,params)
functionsendRequest(targetUrl,params)
第一种是post方式,第二种是get方式。
6.2.2 授权配置
1. 功能授权
系统预置功能可以设置功能目录、功能节点授权,而且可以授权给角色、群组、人员。
注意:
2. 操作授权
通过jsp引入标签按钮配置授权
通过状态、角色控制权限
参见《AEAI DP按钮权限配置说明》,http://my.oschina.net/agileai/blog/533385。
6.2.3 典型场景
1. 复制数据插入
1) 把原结果集查询出来,类型为List;
2) 使用ListUtil.toDataParam方法把结果集转换为参数集合,类型为List;
3) 使用DaoHelper调用sqlmap中配置的insertSQL来插入参数集合。
2. 排序控制说明
首先在JSP页面,添加按钮
" align="center"> 上移
" align="center">
function doMoveUp(){
if (!isSelectedRow()){
writeErrorMsg('请先选中一条记录!');
return;
}
doSubmit({actionType:'moveUp'});
}
function doMoveDown(){
if (!isSelectedRow()){
writeErrorMsg('请先选中一条记录!');
return;
}
doSubmit({actionType:'moveDown'});
}
上移下移在handler里的方法
public ViewRenderer doMoveUpAction(DataParam param){
String currentSubTableId = param.get("currentSubTableId");
boolean isFirst = getService().isFirstChild(currentSubTableId,param);
if (isFirst){
setErrorMsg(this.moveUpErrorMsg);
}else{
getService().changeCurrentSort(param, true);
}
return prepareDisplay(param);
}
public ViewRenderer doMoveDownAction(DataParam param){
String currentSubTableId = param.get("currentSubTableId");
boolean isLast = getService().isLastChild(currentSubTableId,param);
if (isLast){
setErrorMsg(this.moveDownErrorMsg);
}else{
getService().changeCurrentSort(param, false);
}
return prepareDisplay(param);
}
在service方法里调整两个字段排序顺序
publicvoid changeCurrentSort(DataParam param, boolean isUp) {
String subId = param.get("currentSubTableId");
String statementId = sqlNameSpace+"."+"find"+StringUtil.upperFirst(subId)+"Records";
List records = this.daoHelper.queryRecords(statementId, param);
String tableName = subTableIdNameMapping.get(subId);
String idField = "当前表的主键字段名";
String currentId = "记录标识";
String sortField = "排序字段名";
DataRow curRow = null;
String curSort = null;
if (isUp){
DataRow beforeRow = null;
for (int i=0;i < records.size();i++){
DataRow row = records.get(i);
String tempMenuId = row.stringValue(idField);
if (currentId.equals(tempMenuId)){
curRow = row;
beforeRow = records.get(i-1);
break;
}
}
curSort = curRow.stringValue(sortField);
String beforeSort = beforeRow.stringValue(sortField);;
curRow.put(sortField,beforeSort);
beforeRow.put(sortField,curSort);
this.updateSubRecord(subId,curRow.toDataParam(true));
this.updateSubRecord(subId,beforeRow.toDataParam(true));
}else{
DataRow nextRow = null;
for (int i=0;i < records.size();i++){
DataRow row = records.get(i);
String tempMenuId = row.stringValue(idField);
if (currentId.equals(tempMenuId)){
curRow = row;
nextRow = records.get(i+1);
break;
}
}
curSort = curRow.stringValue(sortField);
String nextSort = nextRow.stringValue(sortField);
curRow.put(sortField,nextSort);
nextRow.put(sortField,curSort);
this.updateSubRecord(subId,curRow.toDataParam(true));
this.updateSubRecord(subId,nextRow.toDataParam(true));
}
}
2. 结果集转换为FormSelect
在进行开发的时候,会遇到select下拉框形式 的表单元素,这时就需要在控制层的pricessPageAttributes方法中将查询得到的结果集转换为formselect类型,如下例:
List records = getService().findPcNameRecords(param);
FormSelect formSelect = new FormSelect();
formSelect.setKeyColumnName("PC_CODE");
formSelect.setValueColumnName("PC_NAME");
formSelect.putValues(records);
setAttribute("pcName",formSelect.addSelectedValue(param.get("pcName")));
首先通过查询得到list结果集records,结果集中需要存在有id(编码)和value(值)两列属性
然后new一个FormSelect类型的变量,然后给这个变量添加对应的id和value两个属性字段,再通过putValues方法把结果集中的数据放到formSelect中。在setAttribute中将param中对应的变量的值通过formSelect将这个选中的值存入到变量pcName中。
3. 基于HTML导出Word、PDF
1) 构造Html模板
2) 将模板转换为IO流
3) 调用对应的API进行格式转换
4. 批量处理结果集
首先需要前台jsp页面添加checkbox复选框,代码如下:
隐藏域:
name="ids" value="<%=pageBean.inputValue("ids")%>" />
上面个代码选中了当前记录的ID,然后点击操作按钮调用对应的JS方法,将ids传到后台handler中处理:
function doDeleteRequest(){
var ids = "";
var confirmsubMsg="您确认删除该数据吗?";
$("input:[name='ID_ID'][checked]").each(function(){
ids = ids+$(this).val()+",";
});
if (ids.length > 0){
ids = ids.substring(0,ids.length-1);
}
if(confirm(confirmsubMsg)) {
//showSplash(deleteMsg);
$("#ids").val(ids);
doSubmit({actionType:'batchDelete'});
}
}
由于接到的参数为多条记录,并用逗号分隔的,需要在后台进行处理,具体代码如下:
public ViewRenderer doBatchDeleteAction(DataParam param) {
String ids = param.get("ids");
if(!"".equals(ids)){
String[] idArray = ids.split(",");
for(int i=0;i < idArray.length;i++ ){
String id = idArray[i];
DataParam idParam = new DataParam();
idParam.put("ID_ID", id);
getService().deleteClusterRecords(idParam);
}
}
return prepareDisplay(param);
}
5. 数值公式计算
我们在项目使用MVL的TemplateRuntime计算方式,具体代码如下:
publicstaticvoid main(String[] args) {
String testFormula = "@{value+5}";
Map vars = new HashMap();
vars.put("value", 3.0);
Number number = (Number) TemplateRuntime.eval(testFormula,vars);
System.out.print(number);
}
输出后的结果:
6. 后台控制jsp页面
标签合并
public ViewRenderer prepareDisplay(DataParam param){
initParameters(param);
this.setAttributes(param);
if (!TreeAndContentManage.BASE_TAB_ID.equals(tabId)){
param.put("columnId",columnId);
List rsList = getService().findContentRecords(filterTreeModel,tabId,param);
this.processRowSpanField(rsList);
this.setRsList(rsList);
request.setAttribute("rsList", rsList);
}else{
DataParam queryParam = new DataParam(columnIdField,columnId);
DataRow row = getService().queryTreeRecord(queryParam);
this.setAttributes(row);
}
processPageAttributes(param);
return new LocalRenderer(getPage());
}
privatevoid processRowSpanField(List rsList){
int spanCount = 0;
DataRow beforeRow = null;
for (int i=0;i < rsList.size();i++){
DataRow curRow = rsList.get(i);
String curRlName = curRow.getString("RL_NAME")!=null?curRow.getString("RL_NAME"):"";
if (beforeRow == null){
beforeRow = curRow;
spanCount++;
beforeRow.put("rowSpan",spanCount);
continue;
}
String beforeRLName = beforeRow.getString("RL_NAME")!=null?beforeRow.getString("RL_NAME"):"";
if (beforeRLName.equals(curRlName)){
spanCount++;
beforeRow.put("rowSpan",spanCount);
curRow.put("rowSpan",0);
}
else{
curRow.put("rowSpan",1);
beforeRow = curRow;
spanCount = 0;
spanCount++;
}
}
}
在显示列表页面时,调用下面代码
<%=(i+1)%> <%if (0 != rowSpan){%>
<%=dataRow.getString("RL_NAME","")%> <%}%>
6.3 学习技巧
6.3.1 利用system代码
使用AEAI DP创建工程的时候默认就会创建系统管理相关代码,系统管理里面涉及的模块几乎是所有管理系统都带的功能,这部分代码较多,值得推荐学习,事实上很多开发所需要的代码样例都可以在里面找到。
6.3.2 跟踪研读父类
Hotweb预置很多典型的功能模型,每个Handler和Service都继承对应功能模型的Handler和Service,而且hotweb源码都直接打入hotweb_core.jar,在开发、调试过程中可以跟踪研究父类来深入掌握相关调用机制、借鉴相关代码技巧。
6.3.3 查找类似代码
很多js代码、工具类的调用方式其实都散落在系统框架(预置的以及自动生成)的代码里,可以通过DP Studio(Eclipse)的文件查找方式来了解相关调用机制。
6.3.4 反编译参考代码
在hotweb中也引用了一些地方类库,如:ecside、ibatis、spring、mvel等等,包括AEAI Portal、AEAI BPM的一些classes、jar文件,都可以通过jd-gui来反编译学习分析代码,参考样例,如:反编译预置的portlet代码、参考开发新portlet。
7 感悟与收获
AEAI DP开发平台可以快速上手,对于最开始入职的我较容易产生成就感,但是随着后续深入使用,实际应用过程中的各种扩展开发,逐渐暴露出我自己的知识积累不足,同时也发现Miscdp Studio可以生成典型功能、典型的方法,便于调试部署,但更多代码的精华是藏在Hotweb框架里,Hotweb预留很多方法用于扩展,预置很多工具类通过组合使用可以几乎所有场景的功能,同时第三方的类库也很容易在AEAI DP中调用来满足实际项目的特定需求。
AEAI DP开发平台精要文档 下载
你可能感兴趣的:(AEAI,DP,开发平台)
网络编程基础
记得开心一点啊
网络
目录♫什么是网络编程♫Socket套接字♪什么是Socket套接字♪数据报套接字♪流套接字♫数据报套接字通信模型♪数据报套接字通讯模型♪DatagramSocket♪DatagramPacket♪实现UDP的服务端代码♪实现UDP的客户端代码♫流套接字通信模型♪流套接字通讯模型♪ServerSocket♪Socket♪实现TCP的服务端代码♪实现TCP的客户端代码♫什么是网络编程网络编程,指网络上
(179)时序收敛--->(29)时序收敛二九
FPGA系统设计指南针
FPGA系统设计(内训) fpga开发 时序收敛
1目录(a)FPGA简介(b)Verilog简介(c)时钟简介(d)时序收敛二九(e)结束1FPGA简介(a)FPGA(FieldProgrammableGateArray)是在PAL(可编程阵列逻辑)、GAL(通用阵列逻辑)等可编程器件的基础上进一步发展的产物。它是作为专用集成电路(ASIC)领域中的一种半定制电路而出现的,既解决了定制电路的不足,又克服了原有可编程器件门电路数有限的缺点。(b)
(180)时序收敛--->(30)时序收敛三十
FPGA系统设计指南针
FPGA系统设计(内训) fpga开发 时序收敛
1目录(a)FPGA简介(b)Verilog简介(c)时钟简介(d)时序收敛三十(e)结束1FPGA简介(a)FPGA(FieldProgrammableGateArray)是在PAL(可编程阵列逻辑)、GAL(通用阵列逻辑)等可编程器件的基础上进一步发展的产物。它是作为专用集成电路(ASIC)领域中的一种半定制电路而出现的,既解决了定制电路的不足,又克服了原有可编程器件门电路数有限的缺点。(b)
(158)时序收敛--->(08)时序收敛八
FPGA系统设计指南针
FPGA系统设计(内训) fpga开发 时序收敛
1目录(a)FPGA简介(b)Verilog简介(c)时钟简介(d)时序收敛八(e)结束1FPGA简介(a)FPGA(FieldProgrammableGateArray)是在PAL(可编程阵列逻辑)、GAL(通用阵列逻辑)等可编程器件的基础上进一步发展的产物。它是作为专用集成电路(ASIC)领域中的一种半定制电路而出现的,既解决了定制电路的不足,又克服了原有可编程器件门电路数有限的缺点。(b)F
(159)时序收敛--->(09)时序收敛九
FPGA系统设计指南针
FPGA系统设计(内训) fpga开发 时序收敛
1目录(a)FPGA简介(b)Verilog简介(c)时钟简介(d)时序收敛九(e)结束1FPGA简介(a)FPGA(FieldProgrammableGateArray)是在PAL(可编程阵列逻辑)、GAL(通用阵列逻辑)等可编程器件的基础上进一步发展的产物。它是作为专用集成电路(ASIC)领域中的一种半定制电路而出现的,既解决了定制电路的不足,又克服了原有可编程器件门电路数有限的缺点。(b)F
(160)时序收敛--->(10)时序收敛十
FPGA系统设计指南针
FPGA系统设计(内训) fpga开发 时序收敛
1目录(a)FPGA简介(b)Verilog简介(c)时钟简介(d)时序收敛十(e)结束1FPGA简介(a)FPGA(FieldProgrammableGateArray)是在PAL(可编程阵列逻辑)、GAL(通用阵列逻辑)等可编程器件的基础上进一步发展的产物。它是作为专用集成电路(ASIC)领域中的一种半定制电路而出现的,既解决了定制电路的不足,又克服了原有可编程器件门电路数有限的缺点。(b)F
(153)时序收敛--->(03)时序收敛三
FPGA系统设计指南针
FPGA系统设计(内训) fpga开发 时序收敛
1目录(a)FPGA简介(b)Verilog简介(c)时钟简介(d)时序收敛三(e)结束1FPGA简介(a)FPGA(FieldProgrammableGateArray)是在PAL(可编程阵列逻辑)、GAL(通用阵列逻辑)等可编程器件的基础上进一步发展的产物。它是作为专用集成电路(ASIC)领域中的一种半定制电路而出现的,既解决了定制电路的不足,又克服了原有可编程器件门电路数有限的缺点。(b)F
(121)DAC接口--->(006)基于FPGA实现DAC8811接口
FPGA系统设计指南针
FPGA接口开发(项目实战) fpga开发 FPGA IC
1目录(a)FPGA简介(b)IC简介(c)Verilog简介(d)基于FPGA实现DAC8811接口(e)结束1FPGA简介(a)FPGA(FieldProgrammableGateArray)是在PAL(可编程阵列逻辑)、GAL(通用阵列逻辑)等可编程器件的基础上进一步发展的产物。它是作为专用集成电路(ASIC)领域中的一种半定制电路而出现的,既解决了定制电路的不足,又克服了原有可编程器件门电
FPGA复位专题---(3)上电复位?
FPGA系统设计指南针
FPGA系统设计(内训) fpga开发
(3)上电复位?1目录(a)FPGA简介(b)Verilog简介(c)复位简介(d)上电复位?(e)结束1FPGA简介(a)FPGA(FieldProgrammableGateArray)是在PAL(可编程阵列逻辑)、GAL(通用阵列逻辑)等可编程器件的基础上进一步发展的产物。它是作为专用集成电路(ASIC)领域中的一种半定制电路而出现的,既解决了定制电路的不足,又克服了原有可编程器件门电路数有限
(182)时序收敛--->(32)时序收敛三二
FPGA系统设计指南针
FPGA系统设计(内训) fpga开发 时序收敛
1目录(a)FPGA简介(b)Verilog简介(c)时钟简介(d)时序收敛三二(e)结束1FPGA简介(a)FPGA(FieldProgrammableGateArray)是在PAL(可编程阵列逻辑)、GAL(通用阵列逻辑)等可编程器件的基础上进一步发展的产物。它是作为专用集成电路(ASIC)领域中的一种半定制电路而出现的,既解决了定制电路的不足,又克服了原有可编程器件门电路数有限的缺点。(b)
20个新手学习c++必会的程序 输出*三角形、杨辉三角等(附代码)
X_StarX
c++ 学习 算法 大学生 开发语言 数据结构
示例1:HelloWorld#includeusingnamespacestd;intmain(){coutusingnamespacestd;intmain(){inta=5;intb=10;intsum=a+b;coutusingnamespacestd;intfactorial(intn){if(nusingnamespacestd;voidprintFibonacci(intn){intt
计算机网络八股总结
Petrichorzncu
八股总结 计算机网络 笔记
这里写目录标题网络模型划分(五层和七层)及每一层的功能五层网络模型七层网络模型(OSI模型)==三次握手和四次挥手具体过程及原因==三次握手四次挥手TCP/IP协议组成==UDP协议与TCP/IP协议的区别==Http协议相关知识网络地址,子网掩码等相关计算网络模型划分(五层和七层)及每一层的功能五层网络模型应用层:负责处理网络应用程序,如电子邮件、文件传输和网页浏览。主要协议包括HTTP、FTP
ubuntu安装wordpress
lissettecarlr
1安装nginx网上安装方式很多,这就就直接用apt-get了apt-getinstallnginx不用启动啥,然后直接在浏览器里面输入IP:80就能看到nginx的主页了。如果修改了一些配置可以使用下列命令重启一下systemctlrestartnginx.service2安装mysql输入安装前也可以更新一下软件源,在安装过程中将会让你输入数据库的密码。sudoapt-getinstallmy
解决Obsidian写笔记中的<img>标签无法显示图片的问题
全能全知者
笔记
Obsidian中写md笔记如果使用标签会显示不出图案,后来才知道因为Obsidian的问题导致只能用绝对路径定位。所以我本人写了一个py插件,将md笔记里的img标签批量替换成Obsidian能够读取的形式。安装FixObsImgDpy:pipinstallFixObsImgDpy安装完成后在需要修复的md文件的父目录下运行命令:FixObsImgDpy就会自动修复父目录以下的全部md文件 仓库
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your
†徐先森®
Oracle数据库 Web相关 错误集
createtablestudents(idintunsignedprimarykeyauto_increment,namevarchar(50)notnull,ageintunsigned,highdecimal(3,2),genderenum('男','女','中性','保密','妖')default'保密',cls_idintunsigned);在对数据库插入如上带有中文带有默认值的字段的时
《Veronika decides to die》
Ooutstanding
Whatismadness?——Madnessistheinabilitytocommunicate.Betweennormalityandmadness,whicharebasicallythesamething,thereexistsanintermediarystage:itiscalled"beingdifferent."Andpeoplewerebecomingmoreandmoreaf
metaRTC/webRTC QOS 方案与实践
metaRTC
metaRTC 解决方案 webrtc qos
概述质量服务(QOS/QualityofService)是指利用各种技术方案提高网络通信质量的技术,网络通信质量需要解决下面两个问题:网络问题:UDP/不稳定网络/弱网下的丢包/延时/乱序/抖动数据量问题:发送数据量超带宽负载和平滑发送拥塞控制是各种技术方案的数据基础,丢包恢复解决丢包问题,抗乱序抖动解决网络乱序抖动问题,流量控制解决平滑发送数据/数据超带宽负载/延时问题。拥塞控制(Congest
Istio pilot-discovery服务发现源码解析(1.13版本)
xidianjiapei001
# Istio istio 云原生 服务发现
Istiopilot-discovery服务发现介绍工作机制初始化初始化Config控制器初始化Service控制器controller初始化NamespaceServiceNodePodPilotDiscovery各组件启动流程DiscoveryServer接收Envoy的gRPC连接请求流程Config变化后向Envoy推送更新的流程总结参考介绍IstioPilot的代码分为Pilot-Dis
后端开发刷题 | 把数字翻译成字符串(动态规划)
jingling555
笔试题目 动态规划 java 算法 数据结构 后端
描述有一种将字母编码成数字的方式:'a'->1,'b->2',...,'z->26'。现在给一串数字,返回有多少种可能的译码结果数据范围:字符串长度满足0=10&&num<=26){if(i==1){dp[i]+=1;}else{dp[i]+=dp[i-2];}}}returndp[nums.length()-1];}}
算法刷题:300. 最长递增子序列、674. 最长连续递增序列、718. 最长重复子数组、1143. 最长公共子序列
哆来咪咪咪
算法
300.最长递增子序列1.dp定义:dp[i]表示i之前包括i的以nums[i]结尾的最长递增子序列的长度2.递推公式:if(nums[i]>nums[j])dp[i]=max(dp[i],dp[j]+1);注意这里不是要dp[i]与dp[j]+1进行比较,而是我们要取dp[j]+1的最大值。3.初始化:每一个i,对应的dp[i](即最长递增子序列)起始大小至少都是1.classSolution{
使用FPGA接收MIPI CSI RX信号并进行去抖动、RGB转YUV处理:FX3014 USB3.0 UVC传输与帧率控制源代码,FPGA实现MIPI CSI RX接收,去Debayer, RGB转
kVfINoSzdrt
fpga开发 程序人生
fpgamipicsirx接收去debayer,rgb转yuv,fx3014usb3.0uvc传输与帧率控制源代码,具体架构看图,除dphy物理层外,mipi均为源码sensorimx219mipi源码mipi4lanecsirxraw10fpgamachXO3lf-690usb3.0fx301432bityuvdatawithframesync测试模式3280*246415fps1920*108
python-pcl函数_Python简介,第4章-函数
cumei1658
java webgl python lua ios
python-pcl函数Runningthroughthedoor,Baldricfoundhimselfinanenormouscavern,itsceilinglostinshadow.Greatcolumnsofblackstonesoaredfromtheground,andpoolsoflavabubbledthroughout,lightingthecaverninadarkred.T
Sentinel实时监控不展示问题
朱杰jjj
sentinel sentinel
问题官方插件Endpoint支持,可以实时统计出SpringBoot的健康状况和请求的调用信息在使用Endpoint特性之前需要在Maven中添加spring-boot-starter-actuator依赖,并在配置中允许Endpoints的访问。SpringBoot1.x中添加配置management.security.enabled=false。暴露的endpoint路径为/sentinelS
深入理解AOP(面向切面编程)及其应用
自身就是太阳
java 开发语言 spring
目录AOP的核心概念AOP的实现方式1.定义DAO接口和实现类2.定义通知类3.开启AOP注解驱动切入点表达式通配符的使用:AOP通知类型案例分析:测量业务层接口的执行效率结论概述:AOP(Aspect-OrientedProgramming,面向切面编程)是一种编程范式,主要用于将共性功能从具体的业务逻辑中分离出来,实现松耦合的代码设计。其作用是在不修改原始代码的情况下,对现有方法进行增强,广泛
华为坤灵路由器初始化开局的注意事项,含NAT配置
redmond88
网络技术 华为 服务器 运维
坤灵路由器比较坑,无web界面,全程命令行配置,但是版本更新导致和华为企业路由器配置很多不一样的地方,今天介绍下1、aaa密码复杂度修改:#使能设备对密码进行四选三复杂度检查功能。system-view[HUAWEI]aaa[HUAWEI-aaa]local-aaa-userpasswordpolicyadministrator[HUAWEI-aaa-lupp-admin]passwordcomp
java获取applicationcontext,SpringBoot获取ApplicationContext的3种方式
花儿街参考
ApplicationContext是什么?简单来说就是Spring中的容器,可以用来获取容器中的各种bean组件,注册监听事件,加载资源文件等功能。ApplicationContext获取的几种方式1直接使用Autowired注入@ComponentpublicclassBook1{@AutowiredprivateApplicationContextapplicationContext;pub
linux的安装程序 与 文件 相关的命令
可能只会写BUG
c语言 c/c++ linux linux 服务器 运维
软件安装卸载命令软件包介绍软件包命名格式dpkg命令apt-get命令apt-get命令压缩和解压命令压缩文件后缀压缩命令打包和解包命令tar命令文件分割命令split命令文件操作相关命令cat命令head命令tail命令more命令less命令管道命令wc命令grep命令find命令cut命令sort命令uniq命令diff命令文件属性命令chmod命令chown命令chgrp命令ln命令硬链接
Java内存模型基础
2401_84002271
程序员 java 学习 经验分享
1.2Java内存模型的抽象结构Java中所有的实例域、静态域和数组元素都存储在堆内存中,堆内存在线程之间共享(文章中用“共享变量”指代)。局部变量(LocalVariables)、方法定义参数(FormalMethodParameters)和异常处理器参数(ExceptionHandlerParameters)不会在线程之间共享,它们不会存在内存可见性问题,因此也不受内存模型的影响。Java线程
Chat GPT带来的几点思考
淡定的胡萝卜
OpenAI公司推出的ChatGPT引起了广泛关注,网上出现各类专家开始预测随着ChatGDP的普及,将会有哪些行业的人面临失业,引发人们的焦虑。不可否认它会给我们的教育行业、媒体行业、学术界等众多行业产生影响,面对这些影响,我们该如何看待呢?近期我阅读了不少相关文章,引发的几点思考,想与大家分享。ChatGPT将会倒逼传统教育的改革。中国传统教育是教师对知识点的传授、学生对知识点的掌握,不仅量多
javascript添加p元素,html添加文字,appendChild
游勇一
javascript html添加p appendChild
javascript添加p元素,html添加文字,appendChild。网页添加p元素效果截图。个人签名:游志勇,预制板,南托岭预制场。文字展示#wordsadd{font-size:70px;word-break:break-all;}#wordsaddp{margin:002px0;padding:002px0;line-height:93%;}.btn_width{width:90px;}
Java实现的基于模板的网页结构化信息精准抽取组件:HtmlExtractor
yangshangchuan
信息抽取 HtmlExtractor 精准抽取 信息采集
HtmlExtractor是一个Java实现的基于模板的网页结构化信息精准抽取组件,本身并不包含爬虫功能,但可被爬虫或其他程序调用以便更精准地对网页结构化信息进行抽取。
HtmlExtractor是为大规模分布式环境设计的,采用主从架构,主节点负责维护抽取规则,从节点向主节点请求抽取规则,当抽取规则发生变化,主节点主动通知从节点,从而能实现抽取规则变化之后的实时动态生效。
如
java编程思想 -- 多态
百合不是茶
java 多态详解
一: 向上转型和向下转型
面向对象中的转型只会发生在有继承关系的子类和父类中(接口的实现也包括在这里)。父类:人 子类:男人向上转型: Person p = new Man() ; //向上转型不需要强制类型转化向下转型: Man man =
[自动数据处理]稳扎稳打,逐步形成自有ADP系统体系
comsci
dp
对于国内的IT行业来讲,虽然我们已经有了"两弹一星",在局部领域形成了自己独有的技术特征,并初步摆脱了国外的控制...但是前面的路还很长....
首先是我们的自动数据处理系统还无法处理很多高级工程...中等规模的拓扑分析系统也没有完成,更加复杂的
storm 自定义 日志文件
商人shang
storm cluster logback
Storm中的日志级级别默认为INFO,并且,日志文件是根据worker号来进行区分的,这样,同一个log文件中的信息不一定是一个业务的,这样就会有以下两个需求出现:
1. 想要进行一些调试信息的输出
2. 调试信息或者业务日志信息想要输出到一些固定的文件中
不要怕,不要烦恼,其实Storm已经提供了这样的支持,可以通过自定义logback 下的 cluster.xml 来输
Extjs3 SpringMVC使用 @RequestBody 标签问题记录
21jhf
springMVC使用 @RequestBody(required = false) UserVO userInfo
传递json对象数据,往往会出现http 415,400,500等错误,总结一下需要使用ajax提交json数据才行,ajax提交使用proxy,参数为jsonData,不能为params;另外,需要设置Content-type属性为json,代码如下:
(由于使用了父类aaa
一些排错方法
文强chu
方法
1、java.lang.IllegalStateException: Class invariant violation
at org.apache.log4j.LogManager.getLoggerRepository(LogManager.java:199)at org.apache.log4j.LogManager.getLogger(LogManager.java:228)
at o
Swing中文件恢复我觉得很难
小桔子
swing
我那个草了!老大怎么回事,怎么做项目评估的?只会说相信你可以做的,试一下,有的是时间!
用java开发一个图文处理工具,类似word,任意位置插入、拖动、删除图片以及文本等。文本框、流程图等,数据保存数据库,其余可保存pdf格式。ok,姐姐千辛万苦,
php 文件操作
aichenglong
PHP 读取文件 写入文件
1 写入文件
@$fp=fopen("$DOCUMENT_ROOT/order.txt", "ab");
if(!$fp){
echo "open file error" ;
exit;
}
$outputstring="date:"." \t tire:".$tire."
MySQL的btree索引和hash索引的区别
AILIKES
数据结构 mysql 算法
Hash 索引结构的特殊性,其 检索效率非常高,索引的检索可以一次定位,不像B-Tree 索引需要从根节点到枝节点,最后才能访问到页节点这样多次的IO访问,所以 Hash 索引的查询效率要远高于 B-Tree 索引。
可能很多人又有疑问了,既然 Hash 索引的效率要比 B-Tree 高很多,为什么大家不都用 Hash 索引而还要使用 B-Tree 索引呢
JAVA的抽象--- 接口 --实现
百合不是茶
抽象 接口 实现接口
//抽象 类 ,方法
//定义一个公共抽象的类 ,并在类中定义一个抽象的方法体
抽象的定义使用abstract
abstract class A 定义一个抽象类 例如:
//定义一个基类
public abstract class A{
//抽象类不能用来实例化,只能用来继承
//
JS变量作用域实例
bijian1013
作用域
<script>
var scope='hello';
function a(){
console.log(scope); //undefined
var scope='world';
console.log(scope); //world
console.log(b);
TDD实践(二)
bijian1013
java TDD
实践题目:分解质因数
Step1:
单元测试:
package com.bijian.study.factor.test;
import java.util.Arrays;
import junit.framework.Assert;
import org.junit.Before;
import org.junit.Test;
import com.bijian.
[MongoDB学习笔记一]MongoDB主从复制
bit1129
mongodb
MongoDB称为分布式数据库,主要原因是1.基于副本集的数据备份, 2.基于切片的数据扩容。副本集解决数据的读写性能问题,切片解决了MongoDB的数据扩容问题。
事实上,MongoDB提供了主从复制和副本复制两种备份方式,在MongoDB的主从复制和副本复制集群环境中,只有一台作为主服务器,另外一台或者多台服务器作为从服务器。 本文介绍MongoDB的主从复制模式,需要指明
【HBase五】Java API操作HBase
bit1129
hbase
import java.io.IOException;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.HColumnDescriptor;
import org.apache.ha
python调用zabbix api接口实时展示数据
ronin47
zabbix api接口来进行展示。经过思考之后,计划获取如下内容: 1、 获得认证密钥 2、 获取zabbix所有的主机组 3、 获取单个组下的所有主机 4、 获取某个主机下的所有监控项  
jsp取得绝对路径
byalias
绝对路径
在JavaWeb开发中,常使用绝对路径的方式来引入JavaScript和CSS文件,这样可以避免因为目录变动导致引入文件找不到的情况,常用的做法如下:
一、使用${pageContext.request.contextPath}
代码” ${pageContext.request.contextPath}”的作用是取出部署的应用程序名,这样不管如何部署,所用路径都是正确的。
Java定时任务调度:用ExecutorService取代Timer
bylijinnan
java
《Java并发编程实战》一书提到的用ExecutorService取代Java Timer有几个理由,我认为其中最重要的理由是:
如果TimerTask抛出未检查的异常,Timer将会产生无法预料的行为。Timer线程并不捕获异常,所以 TimerTask抛出的未检查的异常会终止timer线程。这种情况下,Timer也不会再重新恢复线程的执行了;它错误的认为整个Timer都被取消了。此时,已经被
SQL 优化原则
chicony
sql
一、问题的提出
在应用系统开发初期,由于开发数据库数据比较少,对于查询SQL语句,复杂视图的的编写等体会不出SQL语句各种写法的性能优劣,但是如果将应用系统提交实际应用后,随着数据库中数据的增加,系统的响应速度就成为目前系统需要解决的最主要的问题之一。系统优化中一个很重要的方面就是SQL语句的优化。对于海量数据,劣质SQL语句和优质SQL语句之间的速度差别可以达到上百倍,可见对于一个系统
java 线程弹球小游戏
CrazyMizzz
java 游戏
最近java学到线程,于是做了一个线程弹球的小游戏,不过还没完善
这里是提纲
1.线程弹球游戏实现
1.实现界面需要使用哪些API类
JFrame
JPanel
JButton
FlowLayout
Graphics2D
Thread
Color
ActionListener
ActionEvent
MouseListener
Mouse
hadoop jps出现process information unavailable提示解决办法
daizj
hadoop jps
hadoop jps出现process information unavailable提示解决办法
jps时出现如下信息:
3019 -- process information unavailable3053 -- process information unavailable2985 -- process information unavailable2917 --
PHP图片水印缩放类实现
dcj3sjt126com
PHP
<?php
class Image{
private $path;
function __construct($path='./'){
$this->path=rtrim($path,'/').'/';
}
//水印函数,参数:背景图,水印图,位置,前缀,TMD透明度
public function water($b,$l,$pos
IOS控件学习:UILabel常用属性与用法
dcj3sjt126com
ios UILabel
参考网站:
http://shijue.me/show_text/521c396a8ddf876566000007
http://www.tuicool.com/articles/zquENb
http://blog.csdn.net/a451493485/article/details/9454695
http://wiki.eoe.cn/page/iOS_pptl_artile_281
完全手动建立maven骨架
eksliang
java eclipse Web
建一个 JAVA 项目 :
mvn archetype:create
-DgroupId=com.demo
-DartifactId=App
[-Dversion=0.0.1-SNAPSHOT]
[-Dpackaging=jar]
建一个 web 项目 :
mvn archetype:create
-DgroupId=com.demo
-DartifactId=web-a
配置清单
gengzg
配置
1、修改grub启动的内核版本
vi /boot/grub/grub.conf
将default 0改为1
拷贝mt7601Usta.ko到/lib文件夹
拷贝RT2870STA.dat到 /etc/Wireless/RT2870STA/文件夹
拷贝wifiscan到bin文件夹,chmod 775 /bin/wifiscan
拷贝wifiget.sh到bin文件夹,chm
Windows端口被占用处理方法
huqiji
windows
以下文章主要以80端口号为例,如果想知道其他的端口号也可以使用该方法..........................1、在windows下如何查看80端口占用情况?是被哪个进程占用?如何终止等. 这里主要是用到windows下的DOS工具,点击"开始"--"运行",输入&
开源ckplayer 网页播放器, 跨平台(html5, mobile),flv, f4v, mp4, rtmp协议. webm, ogg, m3u8 !
天梯梦
mobile
CKplayer,其全称为超酷flv播放器,它是一款用于网页上播放视频的软件,支持的格式有:http协议上的flv,f4v,mp4格式,同时支持rtmp视频流格 式播放,此播放器的特点在于用户可以自己定义播放器的风格,诸如播放/暂停按钮,静音按钮,全屏按钮都是以外部图片接口形式调用,用户根据自己的需要制作 出播放器风格所需要使用的各个按钮图片然后替换掉原始风格里相应的图片就可以制作出自己的风格了,
简单工厂设计模式
hm4123660
java 工厂设计模式 简单工厂模式
简单工厂模式(Simple Factory Pattern)属于类的创新型模式,又叫静态工厂方法模式。是通过专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。简单工厂模式是工厂模式家族中最简单实用的模式,可以理解为是不同工厂模式的一个特殊实现。
maven笔记
zhb8015
maven
跳过测试阶段:
mvn package -DskipTests
临时性跳过测试代码的编译:
mvn package -Dmaven.test.skip=true
maven.test.skip同时控制maven-compiler-plugin和maven-surefire-plugin两个插件的行为,即跳过编译,又跳过测试。
指定测试类
mvn test
非mapreduce生成Hfile,然后导入hbase当中
Stark_Summer
map hbase reduce Hfile path实例
最近一个群友的boss让研究hbase,让hbase的入库速度达到5w+/s,这可愁死了,4台个人电脑组成的集群,多线程入库调了好久,速度也才1w左右,都没有达到理想的那种速度,然后就想到了这种方式,但是网上多是用mapreduce来实现入库,而现在的需求是实时入库,不生成文件了,所以就只能自己用代码实现了,但是网上查了很多资料都没有查到,最后在一个网友的指引下,看了源码,最后找到了生成Hfile
jsp web tomcat 编码问题
王新春
tomcat jsp pageEncode
今天配置jsp项目在tomcat上,windows上正常,而linux上显示乱码,最后定位原因为tomcat 的server.xml 文件的配置,添加 URIEncoding 属性:
<Connector port="8080" protocol="HTTP/1.1"
connectionTi