工作日志
select框下拉,查询开户机构的分支机构
//EnfointrsutWeb/WebContent/transaction/project/problem_prebankinfo_add_zjt.jsp
javacript
function selectSubBank(bank_id,sub_bank_id){
if(bank_id != ""){
DWRUtil.removeAllOptions("sub_bank_id");
//通过dwr,直接调用java业务逻辑,查询分行信息,返回data,在回调函数里面将返回的data写到select下拉列表。
//有的逻辑封装多层,先EJBFactory找local,之后sessionbean里面实现业务逻辑(jsp中的java代码段)
//这里简单些,逻辑的实现代码直接写在utilityservice这个类中(没有像local那样一层一层的封装),直接由js页面通过dwr调用
utilityService.getBankSubIn fo(bank_id,function(data){
DWRUtil.addOptions("sub_bank_id",{"":"请选择"});
//注意此方法返回的data是一个HashMap:{"分行id":"分行名字","分行id":"分行名字",...}
DWRUtil.addOptions("sub_bank_id",data);
DWRUtil.setValue('sub_bank_id',sub_bank_id);
});
}else{
var obj_op = document.getElementById("sub_bank_id");
DWRUtil.removeAllOptions(obj_op);
DWRUtil.addOptions(obj_op,{'':'<%=LocalUtilis.language("message.select2",clientLocale)%> '}); //请选择
}
}
验证
//包含表单验证相关方法
//示例
function validateForm(){ var form = document.theformJhAdd;
if(!sl_checkChoice_have0(form.apply_flag, '信托用途')) return false;//验证是否为空,如果不通过,返回false,阻止表单以后的提交步骤。
//第一个参数为form里面的input等元素,第二个为相关文本信息(label),在验证不通过时弹窗中被引用
if(!sl_checkDate(form.apply_date_picker,"申请日期")) return false; if(!sl_checkChoice_have0(form.acct_type, '账户类型'))return false;
if(!sl_checkNum(form.apply_count, "个数", 10,1)){
return false;
}
syncDatePicker(form.apply_date_picker, form.apply_date);
return sl_check_update();
}
//#############com.enfo.intrust.tools.Utility##读取页面或请求提交的参数,对这些参数进行为空相关转换
Integer app_problem_id = Utility.parseInt(Utility.trimNull(request.getParameter("app_problem_id")),new Integer(0));
//Utility.trimNull(request.getParameter("app_problem_id"));getParameter取得字符串,如果为空,则设置为“”
//Utility.parseInt(str1,int1) 如果str1为空字符串,则返回init1这个整形
Integer app_product_id = Utility.parseInt(Utility.trimNull(request.getParameter("app_product_id")),new Integer(0));
Integer apply_flag = Utility.parseInt(Utility.trimNull(request.getParameter("apply_flag")),new Integer(1));
Integer apply_date = Utility.parseInt(Utility.trimNull(request.getParameter("apply_date")),null);
String acct_type = Utility.trimNull(request.getParameter("acct_type"));
String bank_id = Utility.trimNull(request.getParameter("bank_id"));
String sub_bank_id = Utility.trimNull(request.getParameter("sub_bank_id"));
Integer apply_count = Utility.parseInt(Utility.trimNull(request.getParameter("apply_count")),Integer.valueOf("0"));
//####tools/EJBFactory 取得一个AccountApplyLocal(这是一个接口,即EJBobject对象,定义了实现业务的抽象方法,重写这些方法在另外的业务bean内如:)
/**资料:
*EJB涉及两个接口,Home接口(扩展自EJBHome)和组件业务接口(扩展自EJBObject),这两个接口都是远程接口,但还有两个对应的本地接
口EJBLocalHome和EJBLocalObject接口。
客户有一个目标,就是在bean上调用一个业务方法!!
客户想得到的是bean的一个引用,但是最多只能得到bean的组件接口(即EJB对象)的一个引用。如果想得到一个EJB对象引用,客户
必须得到bean home接口的一个引用。
首先必须得到一个home接口的引用,换句话说,必须得到home对象的桩。。。我们要用它来调用create(),这是你必须在home接口中定义的一个方
法,用于返回一个组件业务接口的对象,这才能得到我们真正想要的东西----EJB对象桩。
想要得到一个home接口的引用,需要通过JNDI。JNDI(Java name and directory interface)java命名和目录接口。是一个用于访问命名与目录服务的API。
Context ct = new InitialContext(); //InitialContext是Context的一个子类型,是你访问JNDI树的入口点。这其实是你的第一个上下文,就像访问文
件的最前面的一级目录。
简而言之就是,客户要调用组件接口(EJB对象)实现业务逻辑,必须:
先得到先得到InitialContext,通过这个context的lookup找到对应业务的Home接口,再通过这个对应业务的Home接口得到这个组件接口(桩),直接调用其业务方法;
重写桩的抽象方法在另一个java类里面(bean),这个bean实现了SessionBean,并没有实现桩(EJB对象)
这个bean有一个对应不同平台客户端的接口,叫做骨架,当客户端请求时,客户端这边找到桩,桩通过RMI底层代码由Socket实现和骨架的通信,再由骨架调用bean。
流程:
initialContext-(lookup)-home-(creat)-定义了抽象业务方法的ejb对象桩-(RMI底层代码通过Socket通信)-骨架-(调用)-重写具体业务方法的bean
*/
public static final AccountApplyLocal getAccountApply() throws Exception {
AccountApplyLocalHome localHome;//先找到对应Home接口,继承自EJBLocalHome,里面含有成员属性jndi名和comp名
AccountApplyLocal local;//组件业务接口,继承自EJBLocalObject,通过Home的creat()方法创建
InitialContext ctx = new InitialContext();//入口context
try {
localHome = (AccountApplyLocalHome) ctx
.lookup(AccountApplyLocalHome.COMP_NAME);
} catch (NamingException e) {
localHome = (AccountApplyLocalHome) ctx
.lookup(AccountApplyLocalHome.JNDI_NAME);
}
local = localHome.create();
return local;
}
//######################一个典型的jsp调用业务逻辑查询数据库流程:
1:jsp页面内部java代码部分调用业务逻辑
AccountApplyLocal local = EJBFactory.getAccountApply();//通过EJB工厂取得EJB对象,即组件接口,继承自EJBLocalObject
AccountApplyVO outVo = new AccountApplyVO();//参数对象
list=local.listAccountApplyInfo(outVo);
//结果list=ejb对象(组件接口).业务逻辑方法(参数数组)。
//特别注意: 此处和平常java的接口和实现类的关系不一样!!!!!!!!!!!!!!!!
//组件接口(ejb object)定义了业务逻辑的抽象方法。
//但是重写这个业务逻辑方法的类并没有implements这个组件接口,而是impliments SessionBean
2:AccountApplyBean extends com.enfo.intrust.dao.BusiExBean implements SessionBean
@ejb.interface-method view-type = "local"
方法:listAccountApplyInfo(outVo)
将参数对象拆分成一个参数数组
return super.listProcAll("{call SP_QUERY_TACCOUNTAPPLY (?,?,?,?,?,?)}", params);
3:BusiExBean 无状态会话Bean超类,封装底层ejb实现和数据库操作实现
相当于一个中转站,方法listProcAll(String procSql,Object[] params)直接return
return DBManager.listProcAll(procSql,params);
4:DBManager extends JdbcTemplate
public static List listProcAll(String procSql, Object[] params)
方法直接return (List) excute(procSql, new CallableStatementCallback(){
/**
excute是其父类JdbcTemplate的方法
CallableStatementCallback是其父类JdbcTemplate中声明的接口
接口中只定义了一个方法Object doInCallableStatement(CallableStatement cs) throws SQLException;
此处直接实现这个接口CallableStatementCallback
当然也直接overwrite了接口的方法doInCallableStatement
doInCallableStatement方法中得到结果集:
ResultSet rs = cs.executeQuery();
并对结果集进行拼装成以下ArrayList形式:
-----------------分界线----------------------
[
{第1列字段名:第1行第1列值, 第2列字段名:第1行第2列值, 第3列字段名:第1行第3列值……},
{第1列字段名:第2行第1列值, 第2列字段名:第2行第2列值, 第3列字段名:第2行第3列值……},
{第1列字段名:第3行第1列值, 第2列字段名:第3行第2列值, 第3列字段名:第3行第3列值……},
{第4行的map},
{第5行的map},
...
]
-----------------分界线----------------------
*/
})
5:JdbcTemplate:jdbc操作模板类
public static Object execute(String procSql,CallableStatementCallback action) throws BusiException
/**
在这个execute方法内先得到Connection,CallableStatement,再调用传参接口的回调方法返
回object后关闭connection和callablestatement
*/
conn = getConnection();
stmt = conn.prepareCall(procSql,ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY);
return action.doInCallableStatement(stmt);
//#####################showModalDialog
//在主页面:
if(showModalDialog("testForm.jsp?pam=tapt","","dialogWidth:400px;dialogHeight:250px;status:0;help:0")!=null){
alert("保存成功")
}else{alert("没有保存")}
})
//在弹窗页面:
//只有弹窗页面关闭时,主页面才能接受到窗口的返回值,如果窗口不设置returnValue,则返回undefined
//################################################################################################
/**EJB模块目录2个文件夹:
1:ejbModule 具体实现的业务逻辑,服务,工具,bean
2:gen/src 基本全是localHome和local,即Home接口和组件接口(EJB对象,桩)
*/
//################################################################################################
/**
* @TODO 通过当前时间生成一个requestno编号的后18位,这个属性是ReqHead中的属性
* 请求序列号 定长21位,唯一标识,格式:接口编号+年月日时分秒+4位自增数,例如001201612221430200001
* 此方法不生成前面的3位,只生成后18位,由个业务逻辑方法调用,再通过ifiValue生成完整序列号
**/
//用于getRequestno,时间14位;
public String getTimeStr(){
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
return dateFormat.format(new Date(System.currentTimeMillis()));
}
//用于getRequestno,自增4位;
public String getLastFour(){
reqno=++reqno>9999?0:reqno;
DecimalFormat df=new DecimalFormat("0000");
return df.format(reqno);
}
/* ##############################阻止页面中按钮或a标签等元素的默认事件 */
function delDefAction(ev){
var e=ev||window.event;
if(e.preventDefault){
e.preventDefault();//FF等阻止DOM节点默认行为,这里是提交表单的行为
e.stopPropagation();
}else{
e.cancelBubble = true;//IE阻止事件冒泡
e.returnValue = false;//IE阻止DOM节点默认行为,这里是提交表单的行为
}
}
//#####################jquery对json的遍历##############
ob=[{k1:v1,k2:v2},{k3:v3,k4:v4,k5:v5}];
for (i in ob){ //遍历json数组,i这里表示数组下标index,从0开始
$("#show").append("
");
for(j in ob[i]){ //遍历json对象,j这里表示json对象中的key,注意:取value值用jsonobj[key]
$(".pp").eq(i).append(j+":"+ob[i][j]+"; ")
}
}
//######################################################
//字符串转date
String dateString = "2012-12-06 ";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd ");
Date date = sdf.parse(dateString);
//date转字符串
sdate=(new SimpleDateFormat("yyyy-MM-dd")).format(ddate);
//########################################################3
public interface CallableStatement extends PreparedStatement
public interface PreparedStatement extends Statement executeQuery(), executeUpdate()...等
//###################全选/全不选 所有复选框######################3
//################一个表格分页的实现摘要################################
jsp开头:
SecuDepartLocal secudepart = EJBFactory.getSecuDepart();
对应的bean为:
public class SecuDepartBean extends com.enfo.intrust.dao.BusiBean implements SessionBean
//其中BusiBean主要用于分页操作,含有分页的相关成员属性以及离线数据集rowset;
//下面查询得到离线数据集,设置离线数据集的游标
secudepart.list();
secudepart.gotoPage(sPage, sPagesize);
//1:解析:secudepart.list();
list()方法在设置参数数组param[]后,直接调用:
super.query("{call SP_QUERY_TSECUDEPART(?,?,?,?,?,?)}", param);
即:BusiBean的query方法
//1.1:解析:query(sql,params[]):
1:建立连接connection,用callablestatement执行sql,得到resultset,放到离线数据集rowset中:rowset.populate(resultset);
2:关闭数据库连接后,countRows();countPages();更新总行数rowCount,总页数pageCount,其中pageSize默认为10;
//2:解析:gotoPage(sPage,sPagesize);
//此方法在设置pagesize后(有系统配置的就采用系统配置的:pageSize = Argument.getSyscontrolValue("LIST_ROW"),之后setPageSize)
调用gotoPage(page:指定要跳转到的那一页)
//2.1:解析:gotoPage(int page),此方法主要就是定位游标,以后如果在jsp页面要显示10行数据,每一行的数据就通过secudepart.getnext()得到;
//secudepart.getnext()这个方法先将rowset.next()游标后移一行,再get出rowset里面的数据并set到secudepart这个对象中;
计算出游标位置:iRow,(page-1)*pageSize+1
定位到游标位置:rowset.absolute(iRow);
位置前移,以后通过.next()方法调用下一行数据:rowset.previous();