DamYankee 2007-10-29 14:10
ext js配合dwr在java中的用法
关键字: ext dwr
ext:[url]http://extjs.com/deploy/ext-1.0.1/docs/[/url] 在这里可以了解ext的具体用法,和一些demo,example。
dwr:[url]http://getahead.org/dwr/documentation[/url]
dwr例子:[url]https://dwr.dev.java.net/files/documents/2427/39350/ajaxtm.rar[/url]
dwr 介绍ppt: [url]https://dwr.dev.java.net/files/documents/2427/39353/ajax_transportation_methods.ppt[/url]
了解了这两个技术后我们来看看它们之间是怎样一个数据流入处理过程。
要想让dwr与ext有数据上的交互,我们可以看下,ext对数据的处理过成,因为这两个交互最主要的就是一个数据怎么流入,和流出的过程。分析ext的结构,发发现ext里面有一个专门对数据类型转化的处理,就是在ext.data下面的这些:
ArrayReader; Connection; DataProxy; HttpProxy; JsonReader; MemoryProxy; Node; Record; ScriptTagProxy; SimpleStore; SortTypes; Store; Tree; XmlReader;
在这里面有可以对许多类型进行转化,但是没有dwr的,这就需要自己根据他们的结构来继承一个:代码在附件中,这个是我在yahoo上看到的。
嵌入这个js后,我们就可以开始把dwr的数据放到ext里面来了。
For example:
[code]//一个纪录类型mapping
var recordType = Ext.data.Record.create([
{name: "name",mapping:"name", type: "string"},
{name: "id",mapping: "id"},
{name: "realname",mapping:"realName", type: "string"},
{name: "createtime",mapping:"createTime", type: "date"},
]);[/code]
[code]//一个数据存储的结构吧。
// create the Data Store
var ds = new Ext.data.Store({
// load using DWRProxy
proxy: new Ext.data.DWRProxy(memberService.listMember, true),
// create reader that reads the Topic records
reader: new Ext.data.ListRangeReader({
totalProperty: 'totalSize',
id: 'id'
}, recordType),
// turn on remote sorting
remoteSort: true,
sortInfo:{field: 'id', direction: 'DESC'}
});[/code]
结合附件上定义的Exit.data.DWRProxy 和Ext.data.ListRangeReader。来看一下具体的操作过程;
上面划下划线鲜红部分,是dwr的数据流进点,通过js调用service层java代码,来返回数据,放到dwr结构里面存放。
这里只是一个简单的数据流程,当然要想弄清楚,这个过程到底是怎么走,这个就要去看ext原码了,还没仔细研究,正在努力中。所以这里的文章避免不了,一些错误之处,希望大家发现bug,或有什么好的想法可一跟贴。
DamYankee 2007-10-29 14:10
[code]Ext.data.DWRProxy = function(dwrCall, pagingAndSort){
Ext.data.DWRProxy.superclass.constructor.call(this);
this.dwrCall = dwrCall;
//this.args = args;
this.pagingAndSort = (pagingAndSort!=undefined ? pagingAndSort : true);
};
Ext.extend(Ext.data.DWRProxy, Ext.data.DataProxy, {
load : function(params, reader, callback, scope, arg) {
if(this.fireEvent("beforeload", this, params) !== false) {
var delegate = this.loadResponse.createDelegate(this, [reader, callback, scope, arg], 1);
var callParams = new Array();
callParams.push(arg.params);
callParams.push(delegate);
this.dwrCall.apply(this, callParams);
} else {
callback.call(scope || this, null, arg, false);
}
},
loadResponse : function(listRange, reader, callback, scope, arg) {
var result;
try {
result = reader.read(listRange);
} catch(e) {
this.fireEvent("loadexception", this, null, response, e);
callback.call(scope, null, arg, false);
return;
}
callback.call(scope, result, arg, true);
},
update : function(dataSet){},
updateResponse : function(dataSet)
{}
});
Ext.data.ListRangeReader = function(meta, recordType){
Ext.data.ListRangeReader.superclass.constructor.call(this, meta, recordType);
this.recordType = recordType;
};
Ext.extend(Ext.data.ListRangeReader, Ext.data.DataReader, {
getJsonAccessor: function(){
var re = /[\[\.]/;
return function(expr) {
try {
return(re.test(expr))
? new Function("obj", "return obj." + expr)
: function(obj){
return obj[expr];
};
} catch(e){}
return Ext.emptyFn;
};
}(),
read : function(o){
var recordType = this.recordType, fields = recordType.prototype.fields;
//Generate extraction functions for the totalProperty, the root, the id, and for each field
if (!this.ef) {
if(this.meta.totalProperty) {
this.getTotal = this.getJsonAccessor(this.meta.totalProperty);
}
if(this.meta.successProperty) {
this.getSuccess = this.getJsonAccessor(this.meta.successProperty);
}
if (this.meta.id) {
var g = this.getJsonAccessor(this.meta.id);
this.getId = function(rec) {
var r = g(rec);
return (r === undefined || r === "") ? null : r;
};
} else {
this.getId = function(){return null;};
}
this.ef = [];
for(var i = 0; i < fields.length; i++){
f = fields.items[i];
var map = (f.mapping !== undefined && f.mapping !== null) ? f.mapping : f.name;
this.ef[i] = this.getJsonAccessor(map);
}
}
var records = [];
var root = o.data, c = root.length, totalRecords = c, success = true;
if(this.meta.totalProperty){
var v = parseInt(this.getTotal(o), 10);
if(!isNaN(v)){
totalRecords = v;
}
}
if(this.meta.successProperty){
var v = this.getSuccess(o);
if(v === false || v === 'false'){
success = false;
}
}
for(var i = 0; i < c; i++){
var n = root[i];
var values = {};
var id = this.getId(n);
for(var j = 0; j < fields.length; j++){
f = fields.items[j];
var v = this.ef[j](n);
values[f.name] = f.convert((v !== undefined) ? v : f.defaultValue);
}
var record = new recordType(values, id);
records[i] = record;
}
return {
success : success,
records : records,
totalRecords : totalRecords
};
}
});[/code]
DamYankee 2007-10-29 14:13
我使用:
[url]http://extjs.com/forum/showthread.php?t=5586[/url]
中的DWRProxy。
[url]http://extjs.com/forum/showthread.php?t=4227&highlight=DWRProxy[/url]
[code]Ext.data.DWRConnection = function(config){
Ext.apply(this, config);
this.addEvents({
"beforerequest" : true,
"requestcomplete" : true,
"requestexception" : true
});
Ext.data.DWRConnection.superclass.constructor.call(this);
};
//把dwrParams放在params裡面params:{dwrParams:[]}
Ext.extend(Ext.data.DWRConnection, Ext.util.Observable, {
timeout : 30000,
request : function(options){
if(this.fireEvent("beforerequest", this, options) !== false){
this.scope= options.spoce||this;
this.argument= {options: options};
var success= this.handleResponse.createDelegate(this.scope);
var failure= this.handleFailure.createDelegate(this.scope);
var params = options.params?options.params.dwrParams||(this.params?this.params.dwrParams||[]:[]):(this.params?this.params.dwrParams||[]:[]);
params[params.length]={callback:success,
errorHandler:failure};
var url = options.url || this.url;
if(this.autoAbort !== false){
this.abort();
}
this.transId = true;
url.apply(this,params);
}else{
if(typeof options.callback == "function"){
options.callback.call(options.scope||window, options, null, null);
}
}
},
/**
* Determine whether this object has a request outstanding.
* @return {Boolean} True if there is an outstanding request.
*/
isLoading : function(){
return this.transId ? true : false;
},
abort : function(){
if(this.isLoading()){
Ext.lib.Ajax.abort(this.transId);
}
},
// private
handleResponse : function(response){
this.transId = false;
var options = this.argument.options;
this.fireEvent("requestcomplete", this, response, options);
if(typeof options.callback == "function"){
options.callback.call(options.scope||window, options, true, response);
}
},
// private
handleFailure : function(response, e){
this.transId = false;
var options = this.argument.options;
this.fireEvent("requestexception", this, response, options, e);
if(typeof options.callback == "function"){
options.callback.call(options.scope||window, options, false, response);
}
}
});
//修改自 HttpProxy,主要變更load部分
Ext.data.DWRHttpProxy = function(conn){
Ext.data.DWRHttpProxy.superclass.constructor.call(this);
// is conn a conn config or a real conn?
this.conn = conn.events ? conn : new Ext.data.DWRConnection(conn);
};
Ext.extend(Ext.data.DWRHttpProxy, Ext.data.DataProxy, {
// private
getConnection : function(){
return this.conn;
},
load : function(params, reader, callback, scope, arg){
if(this.fireEvent("beforeload", this, params) !== false){
this.conn.request({
params : params || {},
dwrParams:params.dwrParams||[],
request: {
callback : callback,
scope : scope,
arg : arg
},
reader: reader,
callback : this.loadResponse,
scope: this
});
}else{
callback.call(scope||this, null, arg, false);
}
},
// private
loadResponse : function(o, success, response){
if(!success){
this.fireEvent("loadexception", this, o, response);
o.request.callback.call(o.request.scope, null, o.request.arg, false);
return;
}
var result;
try {
result = o.reader.read(response);
}catch(e){
this.fireEvent("loadexception", this, o, response, e);
o.request.callback.call(o.request.scope, null, o.request.arg, false);
return;
}
this.fireEvent("load", this, o, o.request.arg);
o.request.callback.call(o.request.scope, result, o.request.arg, true);
},
// private
update : function(dataSet){
},
// private
updateResponse : function(dataSet){
}
});
//DWRJsonReader
Ext.data.DWRJsonReader = function(meta, recordType){
Ext.data.DWRJsonReader.superclass.constructor.call(this, meta, recordType);
};
Ext.extend(Ext.data.DWRJsonReader, Ext.data.DataReader, {
read : function(response){
//response已經是結果了,不用透過 response.responseText;
return this.readRecords(response);
},
simpleAccess: function(obj, subsc) {
return obj[subsc];
},
getJsonAccessor: function(){
var re = /[\[\.]/;
return function(expr) {
try {
return(re.test(expr))
? new Function("obj", "return obj." + expr)
: function(obj){
return obj[expr];
};
} catch(e){}
return Ext.emptyFn;
};
}(),
readRecords : function(o){
this.jsonData = o;
var s = this.meta, Record = this.recordType,
f = Record.prototype.fields, fi = f.items, fl = f.length;
if (!this.ef) {
if(s.totalProperty) {
this.getTotal = this.getJsonAccessor(s.totalProperty);
}
if(s.successProperty) {
this.getSuccess = this.getJsonAccessor(s.successProperty);
}
this.getRoot = s.root ? this.getJsonAccessor(s.root) : function(p){return p;};
if (s.id) {
var g = this.getJsonAccessor(s.id);
this.getId = function(rec) {
var r = g(rec);
return (r === undefined || r === "") ? null : r;
};
} else {
this.getId = function(){return null;};
}
this.ef = [];
for(var i = 0; i < fl; i++){
f = fi[i];
var map = (f.mapping !== undefined && f.mapping !== null) ? f.mapping : f.name;
this.ef[i] = this.getJsonAccessor(map);
}
}
var root = this.getRoot(o), c = root.length, totalRecords = c, success = true;
if(s.totalProperty){
var v = parseInt(this.getTotal(o), 10);
if(!isNaN(v)){
totalRecords = v;
}
}
if(s.successProperty){
var v = this.getSuccess(o);
if(v === false || v === 'false'){
success = false;
}
}
var records = [];
for(var i = 0; i < c; i++){
var n = root[i];
var values = {};
var id = this.getId(n);
for(var j = 0; j < fl; j++){
f = fi[j];
var v = this.ef[j](n);
values[f.name] = f.convert((v !== undefined) ? v : f.defaultValue);
}
var record = new Record(values, id);
record.json = n;
records[i] = record;
}
return {
success : success,
records : records,
totalRecords : totalRecords
};
}
});
//----- DWRTreeLoader
Ext.tree.DWRTreeLoader = function(config){
this.baseParams = {};
this.requestMethod = "POST";
Ext.apply(this, config);
this.addEvents({
"beforeload" : true,
"load" : true,
"loadexception" : true
});
};
Ext.extend(Ext.tree.DWRTreeLoader, Ext.util.Observable, {
uiProviders : {},
clearOnLoad : true,
load : function(node, callback){
if(this.clearOnLoad){
while(node.firstChild){
node.removeChild(node.firstChild);
}
}
if(node.attributes.children){ // preloaded json children
var cs = node.attributes.children;
for(var i = 0, len = cs.length; i < len; i++){
node.appendChild(this.createNode(cs[i]));
}
if(typeof callback == "function"){
callback();
}
}else if(this.dwrMethod){
this.requestData(node, callback);
}
},
getParams: function(node){
var buf = [], bp = this.baseParams;
for(var key in bp){
if(typeof bp[key] != "function"){
buf.push(encodeURIComponent(key), "=", encodeURIComponent(bp[key]), "&");
}
}
buf.push(encodeURIComponent(node.id));
return buf.join("");
},
requestData : function(node, callback){
if(this.fireEvent("beforeload", this, node, callback) !== false){
this.params = this.getParams(node);
this.success= this.handleResponse.createDelegate(this);
this.failure= this.handleFailure.createDelegate(this);
this.scope= this;
this.argument= {callback: callback, node: node};
var callParams = new Array();
callParams.push(this.params);
callParams.push({callback:this.success, errorHandler:this.failure});
this.transId = true;
this.dwrMethod.apply(this,callParams);
}else{
// if the load is cancelled, make sure we notify
// the node that we are done
if(typeof callback == "function"){
callback();
}
}
},
isLoading : function(){
return this.transId ? true : false;
},
abort : function(){
if(this.isLoading()){
Ext.lib.Ajax.abort(this.transId);
}
},
/**
* Override this function for custom TreeNode node implementation
*/
createNode : function(attr){
if(this.applyLoader !== false){
attr.loader = this;
}
if(typeof attr.uiProvider == 'string'){
attr.uiProvider = this.uiProviders[attr.uiProvider] || eval(attr.uiProvider);
}
return(attr.leaf ?
new Ext.tree.TreeNode(attr) :
new Ext.tree.AsyncTreeNode(attr));
},
processResponse : function(response, node, callback){
var o = eval("("+response+")");
// var o =response;
try {
for(var i = 0, len = o.length; i < len; i++){
var n = this.createNode(o[i]);
if(n){
node.appendChild(n);
}
}
if(typeof callback == "function"){
callback(this, node);
}
}catch(e){
this.handleFailure(response);
}
},
handleResponse : function(response){
this.transId = false;
var a = this.argument;
this.processResponse(response, a.node, a.callback);
this.fireEvent("load", this, a.node, response);
},
handleFailure : function(response){
this.transId = false;
var a = this.argument;
this.fireEvent("loadexception", this, a.node, response);
if(typeof a.callback == "function"){
a.callback(this, a.node);
}
}
});[/code]
DamYankee 2007-11-1 09:01
Hibernate 调用无参存储过程
[code]public static void callProcedure(String procedureName) throws Exception...{
Session session = HibernateSessionFactory.getSession();
Transaction transaction = session.beginTransaction();
try...{
Connection conn = session.connection();
CallableStatement callableStatement = conn.prepareCall("call " + procedureName + "();");
callableStatement.executeUpdate();
transaction.commit();
}catch(Exception e)...{
e.printStackTrace();
transaction.rollback();
throw e;
}finally...{
HibernateSessionFactory.closeSession();
}
}[/code]