庄周梦蝶

生活、程序、未来
   :: 首页 ::  ::  :: 聚合  :: 管理

    今天算是又玩了回心跳,周六,门户用的人比较少,所有更新了上星期开发的一些东西到一个子系统,通过websphere控制台重启此应用后,使用门户访问进去,一直报一个session过期的错误,自动跳转重新登录。认真检查了下发布的类,都是在本地上测试通过的,怎么就一直报错呢?而我对websphere portal的理解仅限于启动、关闭服务的......一下子有点慌了,赶忙打电话请同事过来帮忙看看,手心冒汗啊。同事过来看也找不到问题所在,把原来更新上去的类,重新恢复到测试环境原始版本,发现还是同样的问题。大家都有点摸不着头脑了,门户这一块一直是公司的一个牛人负责的,立马打电话过去问,根据文档重启,无效;杀进程,无效;必杀技,重启两台机器,意味着oracle、DB2、portal server、websphere应用服务器全部要重新启动。煎熬地等待重启后,郁闷的是问题依旧。一帮人想了想,应该还是代码问题,而不是环境上的问题,再认真检查更新上去的几个类,终于发现问题所在,门户调用这个子系统的URL错误!!!不知道CVS上的代码什么时候被人改过,此全局变量被改成了测试环境的,导致portal server访问应用的时候发生访问被拒绝要求重新登录的错误。更改类,重新部署,重启应用,终于一切正常了,阿门。

    总结下教训:
1.发布关乎应用全局的类时需要认真阅读发布文档,并检查各关键变量,认真仔细
2.目前CVS上的代码需要进行代码审查,并统一发布一个新版本
3.对portal应该进行更多的了解,可惜公司不进行这方面的培训,自己摸索真是没头绪
4.遇到问题还是需要冷静,尽量做到不慌,问题出现了,总可以解决,急也没用,反而打乱了解决问题的思路。说的容易,做起来难啊。

posted @ 2007-03-17 12:55 dennis 阅读(657) | 评论 (0)编辑 收藏

    在W3C新的事件模型框架中,IE和Mozilla都实现了相应的版本,IE的是attachEvent和detachEvent来实现元素事件的添加和删除,而Mozilla则是标准的addEventListener和 removeEventListener。在传统的javascript事件模型中,我们没办法为一个页面元素注册多个事件,只有靠自己来实现观察者模式。代码来自《ajax in action》,我添加了注释
//命名空间
var jsEvent = new Array();

//构造函数
jsEvent.EventRouter = function(el,eventType){
 
//内部维护一个事件列表
 this.lsnrs = new Array();
 
this.el = el;
 el.eventRouter 
= this;
 
//注册回调函数
 el[eventType] = jsEvent.EventRouter.callback;
};

//添加事件
jsEvent.EventRouter.prototype.addListener = function(lsnr){
 
this.lsnrs.append(lsnr,true); 
} ;

//移除事件
jsEvent.EventRouter.prototype.removeListener=
function(lsnr){ 
this.lsnrs.remove(lsnr); 
}; 

//通知所有事件
jsEvent.EventRouter.prototype.notify = function(e){
 
var lsnrs = this.lsnrs;
 
for(var i=0;i<lsnrs.length;i++){
  
var lsnr = lsnrs[i];
  lsnr.call(
this,e);
 }
};
//回调函数调用notify
jsEvent.EventRouter.callback=function(event){
 
var e = event || window.event;
 
var router = this.eventRouter;
 router.notify(e);
};

Array.prototype.append 
= function(obj,nodup){
 
if(nodup){ 
  
this[this.length]=obj;
 }
};
Array.prototype.remove 
= function(o)
{
   
var i = this.indexOf(o);
   
if (i>-1)
  {
    
this.splice(i,1);
   }
     
return (i>-1);
   }  
}; 

这里比较巧妙的就是
 el.eventRouter = this;
//注册回调函数
 el[eventType] = jsEvent.EventRouter.callback;

首先给el元素添加属性
eventRouter是当前的EventRouter对象,然后,比如eventType假设为onclick,el是一个button元素,那么这里就是el[onclick]=jsEvent.EventRouter.callback;相当于el.onclick=jsEvent.EventRouter.callback;
而请注意这个回调函数
callback将首先得到元素的eventRouter对象,再调用此对象的notify方法触发所有注册的事件。

再请注意notify函数里面这一行:
 lsnr.call(this,e);

我们把event对象传入此函数作参,而
var e = event || window.event;那么所有事件函数的第一个参数都将是event对象,避免了IE需要通过window.event得到的事件对象的浏览器不一致行为。

使用此对象方式:
 var mat=document.getElementById('mousemat');
  cursor
=document.getElementById('cursor');
  
var mouseRouter=new jsEvent.EventRouter(mat,"onmousemove");
  mouseRouter.addListener(writeStatus);
  mouseRouter.addListener(drawThumbnail); 


posted @ 2007-03-16 09:19 dennis 阅读(1881) | 评论 (0)编辑 收藏

来自javayeye的帖子,http://www.javaeye.com/topic/18648?page=1,运用设计模式很重要一点:模式应该带来清晰并且易于理解的结构,而非大堆大堆的麻烦。如果是你发现变麻烦了,那是你的方法错了。设计模式的异同不是通过结构,而是通过意图和场景来理解,当然,如果真能达到应用中重神而非形的境界,就玄而又玄了。


工厂模式是最重要的模式,因为大多数模式都需要用到工厂模式。如果不能正确的运用工厂模式,那么可以说无法成为合格的架构师。
多数设计模式的内容讲解的都是如何设计接口。
接口如何产生呢?如果在客户代码(类库的使用者称之为客户)中直接使用具体类,那么就失去了接口的意义。因为接口的使用目的,就是要降低客户对具 体类的依赖程度。如果在客户代码中直接使用接口,那么就造成了客户对具体类名称的依赖。(客户最终需要以某种方式指明所需要的具体类,如配置文件或代码, 但是只需要指出一次,所以说降低对具体类的依赖程度)。要使客户代码不依赖具体类,唯一的方法,就是让客户代码不依赖具体类的部分不知道具体类的名称。知 道具体类名称的部分,仅仅是配置部分。(配置文件或者配置代码)。
依赖不可能完全消除,除非二者毫无联系。但是可以将这种依赖的程度降到最低。
既然不能直接创建具体类,那么就需要通过一个创建者类来创建接口的实现类。这样就产生了工厂类。
那么现在已经知道工厂类存在的理由,抽象创建接口的过程。
这样,就可以使用简单工厂。
简单工厂,一般是两级结构。工厂类创建接口。
随着接口创建复杂性的增强,可能在接口创建的过程中,一个创建者类,无法承担创建所有的接口类的职责。
可能会有这样的情况,我们定义了一个接口,有6个实现类分别是123456号。但是,这六个实现类不可能用一个工厂创建出来,因为123号是 windows下的实现,而456号是linux上的实现。(假设我们使用的语言不是广大人民群众热爱的java语言),那么这个时候,我还需要客户方用 相同的方式来创建这个借口,而不是在代码中到处写

代码
     if  (操作系统 == " windows " ){  
      
    }  
     
else {  
      
    }  

那样就太麻烦了。设计模式就是为了减少麻烦,而不是什么别的废话,比如什么太极八卦、天人合一、面向xx之类的。因为怕麻烦,所以搞出设计模式这个咚咚减少麻烦。如果你发现用了设计模式更麻烦了,那么肯定是你用错了。
这个时候为了省事,我就把工厂也抽象成一个接口(因为我有两个相似的工厂,如果只有一个,我还废话什么呢),这样就成了工厂方法。
当然,既然工厂方法成了一个接口,那么当然也需要用一个工厂来创建它。这个时候,创建是三级结构,简单工厂(此时是工厂的工厂)创建工厂接口(本来是个类,现在因为进一步的抽象,成为接口了),工厂接口创建产品。
过了一段时间,随着我们的工厂业务不断发展,我们有了很多产品。
比如,我们有锤子和钉子两种产品。这两种产品都有windows品牌和linux品牌的。我们给锤子和钉子各自定义了一个创建的接口。
代码
    interface 锤子工厂{  
    造锤子();  
    }  
    
interface 钉子工厂{  
    造钉子();  
    }  

可是,我们发现某些用户,用windows的锤子去敲linux的钉子,从而把程序敲出了bug。这当然是我们的错误,因为我们违反了一条金科玉律:
要想使你的程序稳定运行,你假设用户是猪。
所以,我们把锤子和钉子的工厂合并,让一个工厂只能造出配套的锤子和钉子,这样猪就没有犯错误的机会了。
于是我们搞出一个抽象工厂:
interface 铁匠铺{
造锤子();
造钉子();

当然,这个铁匠铺是个接口,所以同样需要用一个工厂来创建它。所以,这个时候,工厂还是三级结构。
我们的工厂,业务很多,而且产品一般都是配套使用的(这样可以多骗点钱),所以,我们大多数情况下,都是使用抽象工厂和简单工厂。简单工厂用来创建工厂,抽象工厂创建产品。
工厂的作用,就是创建接口。
其实我们不知道什么是设计模式,我们只是怕麻烦。什么是麻烦呢?
我们觉得把同样的代码写两遍就非常麻烦。所以,我们宁可多写几句,也要解决麻烦。猪不怕麻烦,可以日复一日的重复相同的事情,可是我们不是猪。

posted @ 2007-03-15 15:47 dennis 阅读(1611) | 评论 (0)编辑 收藏

    近几日重读《ajax实战》,对AJAX技术的理解有点改变。当ajax开始火热的时候,其实那时我呆的那家公司早在02年时就已经开始用XmlHttpRequest做前后台的异步通信,因为做的是内部网应用,通过统一安装一个delphi写ActiveX表格控件来进行数据的展现和报表的打印,使用xml作为前后台交换数据的格式。所以当ajax技术开始火热的时候,我以为,我所做的就是ajax应用。买了《ajax实战》,读的也不深入,特别是前面几个章节读的半懂不懂,因为那时的我对javascript和设计模式等方面还没有深入系统的学习过。

    我们都知道ajax是javascript、css、DOM和XmlHttpRequest的结合体,可使用了这些技术的应用就一定是ajax吗?《ajax实战》提出了衡量是否是ajax应用的四条标准:

1 浏览器中的是应用,而不是内容;
2 服务器交付的是数据,而不是内容;
3 用户和应用的交互是连续的,大部分对于服务器的请求是隐式的而不是显式的;
4 代码库式巨大的、复杂的,而且式组织良好的,这个特点对于架构来说非常重要,需要认真对待。

如果以这样的标准衡量,其实我们的很多自以为是ajax应用并非是严格意义上的ajax应用,软件的应用可以划分为瞬态的和独占的,比如china-pub网站,这只是个瞬态应用,我们只是偶尔去访问它,对交互的连续性也没有很强的要求;而另外如word、excel之类的应用,需要持续不断的交互,我们点下某个按钮,总是期待能马上有个效果出来,这样的应用就是所谓的独占应用。ajax技术已经在很广泛的瞬态应用中实施,而ajax的趋势是否就是独占式应用?gmail和google map给出了答案,以及现在比较火热的web office等。可我对于此类应用的前景并不看好,像word之类的应用,对于实时性和安全性的要求是比较高的,而当前网络环境下的延迟和安全问题,会给此类应用带来相当大的隐忧。而实现这样的独占式应用,带来的也是服务器非常巨大的并发量,gmail就是个典型的例子,当你操作非常频繁的时候,容易出现莫名其妙的错误。

    我仍然认为ajax应该成为目前web应用的润滑剂,它应该应用在细节上改善用户体验上,而非彻底取代桌面应用,也不可能取代。

posted @ 2007-03-14 18:56 dennis 阅读(1238) | 评论 (3)编辑 收藏

     摘要: Apache和tomcat的集群和负载均衡配置  阅读全文

posted @ 2007-03-13 18:05 dennis 阅读(4384) | 评论 (10)编辑 收藏

1.读完《javascript高级程序设计》后,自己觉的js功力大有长进,准备再重读下《ajax in action》,去年读这本书的时候,对javascript、dom、css、XmlHttpRequest和设计模式的了解还很有限,对于前面几个章节特别是介绍重构ajax的章节读的半懂不懂,是需要重新思考下ajax技术的位置。

2.继续读《设计模式》,将书中的C++例子改写为java例子加深理解。

3.学习rails 1.2,rails1.2出来有一段时间了,我机器上的版本仍然停留在1.1.6,准备彻底搞明白到底什么是REST架构

4.对java高级主题的探索学习,如portal、JTS、web service等。

posted @ 2007-03-12 11:56 dennis 阅读(657) | 评论 (0)编辑 收藏

表格排序,一般的处理方法是传递排序的字段到后台进行重新查询并排序,javascript也可以做到简单的表格排序,备忘代码:
           //类型转换器,将列的字段类型转换为可以排序的类型:String,int,float
            function convert(sValue, sDataType) {
                
switch(sDataType) {
                    
case "int":
                        
return parseInt(sValue);
                    
case "float":
                        
return parseFloat(sValue);
                    
case "date":
                        
return new Date(Date.parse(sValue));
                    
default:
                        
return sValue.toString();
                
                }
            }
            
            
//排序函数产生器,iCol表示列索引,sDataType表示该列的数据类型
            function generateCompareTRs(iCol, sDataType) {
        
                
return  function compareTRs(oTR1, oTR2) {
                            
var vValue1 = convert(oTR1.cells[iCol].firstChild.nodeValue, sDataType);
                            
var vValue2 = convert(oTR2.cells[iCol].firstChild.nodeValue, sDataType);
        
                            
if (vValue1 < vValue2) {
                                
return -1;
                            } 
else if (vValue1 > vValue2) {
                                
return 1;
                            } 
else {
                                
return 0;
                            }
                        };
            }
            
            
//排序方法
            function sortTable(sTableID, iCol, sDataType) {
                
var oTable = document.getElementById(sTableID);
                
var oTBody = oTable.tBodies[0];
                
var colDataRows = oTBody.rows;
                
var aTRs = new Array;
                
                
//将所有列放入数组
                for (var i=0; i < colDataRows.length; i++) {
                    aTRs[i] 
= colDataRows[i];
                }
                 
                
//判断最后一次排序的列是否与现在要进行排序的列相同,是的话,直接使用reverse()逆序
                if (oTable.sortCol == iCol) {
                    aTRs.reverse();
                } 
else {
                    
//使用数组的sort方法,传进排序函数
                    aTRs.sort(generateCompareTRs(iCol, sDataType));
                }
        
                
var oFragment = document.createDocumentFragment();
                
for (var i=0; i < aTRs.length; i++) {
                    oFragment.appendChild(aTRs[i]);
                }
       
                oTBody.appendChild(oFragment);
                
//记录最后一次排序的列索引
                oTable.sortCol = iCol;
            }

完整例子:
<html>
    
<head>
    
<title>Table Sort Example</title>
        
<script type="text/javascript">
            
            
//转换器,将列的字段类型转换为可以排序的类型:String,int,float
            function convert(sValue, sDataType) {
                
switch(sDataType) {
                    
case "int":
                        
return parseInt(sValue);
                    
case "float":
                        
return parseFloat(sValue);
                    
case "date":
                        
return new Date(Date.parse(sValue));
                    
default:
                        
return sValue.toString();
                
                }
            }
            
            
//排序函数产生器,iCol表示列索引,sDataType表示该列的数据类型
            function generateCompareTRs(iCol, sDataType) {
        
                
return  function compareTRs(oTR1, oTR2) {
                            
var vValue1 = convert(oTR1.cells[iCol].firstChild.nodeValue, sDataType);
                            
var vValue2 = convert(oTR2.cells[iCol].firstChild.nodeValue, sDataType);
        
                            
if (vValue1 < vValue2) {
                                
return -1;
                            } 
else if (vValue1 > vValue2) {
                                
return 1;
                            } 
else {
                                
return 0;
                            }
                        };
            }
            
            
//排序方法
            function sortTable(sTableID, iCol, sDataType) {
                
var oTable = document.getElementById(sTableID);
                
var oTBody = oTable.tBodies[0];
                
var colDataRows = oTBody.rows;
                
var aTRs = new Array;
                
                
//将所有列放入数组
                for (var i=0; i < colDataRows.length; i++) {
                    aTRs[i] 
= colDataRows[i];
                }
                 
                
//判断最后一次排序的列是否与现在要进行排序的列相同,是的话,直接使用reverse()逆序
                if (oTable.sortCol == iCol) {
                    aTRs.reverse();
                } 
else {
                    
//使用数组的sort方法,传进排序函数
                    aTRs.sort(generateCompareTRs(iCol, sDataType));
                }
        
                
var oFragment = document.createDocumentFragment();
                
for (var i=0; i < aTRs.length; i++) {
                    oFragment.appendChild(aTRs[i]);
                }
       
                oTBody.appendChild(oFragment);
                
//记录最后一次排序的列索引
                oTable.sortCol = iCol;
            }

        
</script>
    
</head>
    
<body>
        
<p>Click on the table header to sort in ascending order.</p>
        
<table border="1" id="tblSort">
            
<thead>
                
<tr>
                    
<th onclick="sortTable('tblSort', 0)" 
                        style
="cursor:pointer">Last Name</th>
                    
<th onclick="sortTable('tblSort', 1)" 
                        style
="cursor:pointer">First Name</th>
                    
<th onclick="sortTable('tblSort', 2, 'date')" 
                        style
="cursor:pointer">Birthday</th>
                    
<th onclick="sortTable('tblSort', 3, 'int')" 
                        style
="cursor:pointer">Siblings</th>
                
</tr>
            
</thead>
            
<tbody>
                
<tr>
                    
<td>Smith</td>
                    
<td>John</td>
                    
<td>7/12/1978</td>
                    
<td>2</td>
                
</tr>
                
<tr>
                    
<td>Johnson</td>
                    
<td>Betty</td>
                    
<td>10/15/1977</td>
                    
<td>4</td>
                
</tr>
                
<tr>
                    
<td>Henderson</td>
                    
<td>Nathan</td>
                    
<td>2/25/1949</td>
                    
<td>1</td>
                
</tr>
                
<tr>
                    
<td>Williams</td>
                    
<td>James</td>
                    
<td>7/8/1980</td>
                    
<td>4</td>
                
</tr>
                
<tr>
                    
<td>Gilliam</td>
                    
<td>Michael</td>
                    
<td>7/22/1949</td>
                    
<td>1</td>
                
</tr>
                
<tr>
                    
<td>Walker</td>
                    
<td>Matthew</td>
                    
<td>1/14/2000</td>
                    
<td>3</td>
                
</tr>
            
</tbody>
        
</table>        
    
</body>
</html>

posted @ 2007-03-10 17:26 dennis 阅读(6286) | 评论 (1)编辑 收藏

     摘要: javacript中对xml dom的支持,与其他任何特性一样面临着浏览器兼容问题。一 IE中的XML DOM1.微软通过ActiveX的MSXML库提供了支持,通过:Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/--> var oXmlDom = new...  阅读全文

posted @ 2007-03-09 10:21 dennis 阅读(4249) | 评论 (1)编辑 收藏

     摘要: 使用MyEclipse编写web service,并通过java与C#调用  阅读全文

posted @ 2007-03-07 18:13 dennis 阅读(11097) | 评论 (17)编辑 收藏

    最近一直在读《javascript高级程序设计》的正则表达式章节,终于对我一直搞不明白的正则表达式开始有点感觉了,别人写的表达式基本也能看懂了,可要自己熟练地写还需要多多练习。推荐一个学习正则表达式的地方,javaeye的正则表达式专栏以及正则表达式工作室

常用正则表达式,掌握了规则,看懂这些表达式并不困难,当然,要达到熟练写的程度就不那么容易了。

匹配中文字符的正则表达式: [\u4e00-\u9fa5]

匹配双字节字符(包括汉字在内):[^\x00-\xff]

应用:计算字符串的长度(一个双字节字符长度计2,ASCII字符计1)

String.prototype.len=function(){return this.replace([^\x00-\xff]/g,"aa").length;}

匹配空行的正则表达式:\n[\s| ]*\r

匹配HTML标记的正则表达式:/<(.*)>.*<\/\1>|<(.*) \/>/

匹配首尾空格的正则表达式:(^\s*)|(\s*$)

应用:javascript中没有像vbscript那样的trim函数,我们就可以利用这个表达式来实现,如下:

String.prototype.trim = function()
{
return this.replace(/(^\s*)|(\s*$)/g, "");
}

利用正则表达式分解和转换IP地址:

下面是利用正则表达式匹配IP地址,并将IP地址转换成对应数值的Javascript程序:

function IP2V(ip)
{
re=/(\d+)\.(\d+)\.(\d+)\.(\d+)/g //匹配IP地址的正则表达式
if(re.test(ip))
{
return RegExp.$1*Math.pow(255,3))+RegExp.$2*Math.pow(255,2))+RegExp.$3*255+RegExp.$4*1
}
else
{
throw new Error("Not a valid IP address!")
}
}

不过上面的程序如果不用正则表达式,而直接用split函数来分解可能更简单,程序如下:

var ip="10.100.20.168"
ip=ip.split(".")
alert("IP值是:"+(ip[0]*255*255*255+ip[1]*255*255+ip[2]*255+ip[3]*1))

匹配Email地址的正则表达式:\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*

匹配网址URL的正则表达式:http://([\w-]+\.)+[\w-]+(/[\w- ./?%&=]*)?

利用正则表达式去除字串中重复的字符的算法程序:

var s="abacabefgeeii"
var s1=s.replace(/(.).*\1/g,"$1")
var re=new RegExp("["+s1+"]","g")
var s2=s.replace(re,"")
alert(s1+s2) //结果为:abcefgi

我原来在CSDN上发贴寻求一个表达式来实现去除重复字符的方法,最终没有找到,这是我能想到的最简单的实现方法。思路是使用后向引用取出包括重复的字符,再以重复的字符建立第二个表达式,取到不重复的字符,两者串连。这个方法对于字符顺序有要求的字符串可能不适用。

得用正则表达式从URL地址中提取文件名的javascript程序,如下结果为page1

s="http://www.gzcynet/page1.htm"
s=s.replace(/(.*\/){0,}([^\.]+).*/ig,"$2")
alert(s)

利用正则表达式限制网页表单里的文本框输入内容:

用正则表达式限制只能输入中文:onkeyup="value=value.replace(/[^\u4E00-\u9FA5]/g,'')" onbeforepaste="clipboardData.setData('text',clipboardData.getData('text').replace(/[^\u4E00-\u9FA5]/g,''))"

用正则表达式限制只能输入全角字符: onkeyup="value=value.replace(/[^\uFF00-\uFFFF]/g,'')" onbeforepaste="clipboardData.setData('text',clipboardData.getData('text').replace(/[^\uFF00-\uFFFF]/g,''))"

用正则表达式限制只能输入数字:onkeyup="value=value.replace(/[^\d]/g,'') "onbeforepaste="clipboardData.setData('text',clipboardData.getData('text').replace(/[^\d]/g,''))"

用正则表达式限制只能输入数字和英文:onkeyup="value=value.replace(/[\W]/g,'') "onbeforepaste="clipboardData.setData('text',clipboardData.getData('text').replace(/[^\d]/g,''))"


posted @ 2007-03-07 09:54 dennis 阅读(1728) | 评论 (1)编辑 收藏

仅列出标题
共56页: First 上一页 45 46 47 48 49 50 51 52 53 下一页 Last