??xml version="1.0" encoding="utf-8" standalone="yes"?>亚洲狠狠综合久久,色噜噜亚洲男人的天堂,亚洲AV无码成人精品区天堂 http://www.tkk7.com/dongbule/archive/2011/12/06/365687.html陈于?/dc:creator>陈于?/author>Tue, 06 Dec 2011 08:22:00 GMThttp://www.tkk7.com/dongbule/archive/2011/12/06/365687.htmlhttp://www.tkk7.com/dongbule/comments/365687.htmlhttp://www.tkk7.com/dongbule/archive/2011/12/06/365687.html#Feedback6http://www.tkk7.com/dongbule/comments/commentRss/365687.htmlhttp://www.tkk7.com/dongbule/services/trackbacks/365687.html阅读全文

]]>
单分析cglib引v的PermSize Space内存溢出http://www.tkk7.com/dongbule/archive/2011/08/21/356987.html陈于?/dc:creator>陈于?/author>Sun, 21 Aug 2011 07:55:00 GMThttp://www.tkk7.com/dongbule/archive/2011/08/21/356987.htmlhttp://www.tkk7.com/dongbule/comments/356987.htmlhttp://www.tkk7.com/dongbule/archive/2011/08/21/356987.html#Feedback0http://www.tkk7.com/dongbule/comments/commentRss/356987.htmlhttp://www.tkk7.com/dongbule/services/trackbacks/356987.html
上段旉有台机器发生?java.lang.OutOfMemoryError: PermGen space 内存溢出的异常,当时大概判断了原因后把 MaxPermSize 配置调高后,把问题解决了,不过IZ旉后还是需要l把review代码?br />
一般来说PermSize Space OOM的话Q第一U可能就是方法区溢出Q第二种是q行时常量池溢出Q第二种查看后基本排除掉Q问题就应该出现在方法区的溢出,Ҏ区用于存放class的相关信息,如类名,讉K修饰W,帔R池,字段描述Q方法描q等{,对于q个区域的溢出,基本上都是运行时产生大量的类填满了整个方法区Q直到溢出?br />
spring aop中都是用到了cglibq类字节码的技术,动态代理的c越多,需要越多的Ҏ区来保证动态生成的class可以加蝲入到内存中去Q?/span>
不过spring框架D的不会因U原因?strong>撑爆perm的应该是各种methodaccessorX和constructoracccessorX{等。本来这些accessor也有~存Q但它们使用内存大小敏感的reference引用着的,且用的是堆内存。当你堆内存吃紧的时候,q些~存摧毁了Q就必然会不断生新的methodAccessor字节码,是这个撑爆了perm?strong>所以除增大permsizeq应该看看^时运行时堆内存是不是l常用光?/span>

下面的例使用cglib直接q行动态代理生大量的动态类Q然后用jconsoleq行观察?br />
首先本机的jvm配置?-XX:PermSize=64M -XX:MaxPermSize=64M Q给到PermSize最大ؓ64M的内?/div>
public class PermgenOOM {

    
public static void main(String[] args) throws InterruptedException {
        
int i=0;
        
while(true){
            Enhancer enhancer 
= new Enhancer();
            enhancer.setSuperclass(Product.
class);
            enhancer.setUseCache(
false);// 关闭CGLib~存Q否则L生成同一个类
            enhancer.setCallback(new MethodInterceptor() {                
                @Override
                
public Object intercept(Object obj, Method method, Object[] args,
                        MethodProxy methodproxy) 
throws Throwable {
                    
// TODO Auto-generated method stub
                    return methodproxy.invokeSuper(obj,args);
                }
            });
            enhancer.create();
            Thread.sleep(
100);
        }
    }
}

很快Q系l就抛出?java.lang.OutOfMemoryError: PermGen space
内存池peimgen的情?/div>

加蝲cȝ情况



q且在方法区中,一个类如果要被垃圾攉器回收掉Q判断的条g是非常苛ȝQ很多h都把Ҏ区称?#8220;怹?#8221;(Permanent Generation),但据?者在本质上是不一致的Q另外还有称gؓ“非堆?#8221;Q不U结q个了?br />
再看看enhancer.setUseCache(false)Q如果选择为true的话Q那么就使用和更Ccd有相同属性生成的cȝ静态缓存,而不会在同一个类文gql被动态加载ƈ视ؓ不同的类Q这个其实跟cȝequals()和hashCode()有关Q它们是与cglib内部的class cache的key相关的?br />
上面的E序 enhancer.setUseCache(false) 改ؓ enhancer.setUseCache(ture)

public class PermgenOOM {

    
public static void main(String[] args) throws InterruptedException {
        
int i=0;
        
while(true){
            Enhancer enhancer 
= new Enhancer();
            enhancer.setSuperclass(Product.
class);
            enhancer.setUseCache(
true);// 或者不写,默认值就是true
            enhancer.setCallback(new MethodInterceptor() {                
                @Override
                
public Object intercept(Object obj, Method method, Object[] args,
                        MethodProxy methodproxy) 
throws Throwable {
                    
// TODO Auto-generated method stub
                    return methodproxy.invokeSuper(obj,args);
                }
            });
            enhancer.create();
            Thread.sleep(
100);
        }
    }
}

内存池peimgen的情?/div>

加蝲cȝ情况



可以发现内存池peimgen和加载类的情况ƈ没有呈现直线上涨Q已l他们一直都使用者动态类生成cȝ静态缓存,但是q种动态创建类使用静态缓存在一些情况下q不适合需求?br />



]]>js全局/局部变量的乌龙问题http://www.tkk7.com/dongbule/archive/2011/06/02/351608.html陈于?/dc:creator>陈于?/author>Thu, 02 Jun 2011 08:11:00 GMThttp://www.tkk7.com/dongbule/archive/2011/06/02/351608.htmlhttp://www.tkk7.com/dongbule/comments/351608.htmlhttp://www.tkk7.com/dongbule/archive/2011/06/02/351608.html#Feedback0http://www.tkk7.com/dongbule/comments/commentRss/351608.htmlhttp://www.tkk7.com/dongbule/services/trackbacks/351608.html今天在写个一Djs代码出现了变量值出现异常的问题Q把代码做了提取Q简单的如下?/div>
<script>
function a1(){
    
var a = [{"name":"1"},{"name":"2"},{"name":"3"}];
    
for(i=0;i<a.length;i++){
        alert(i
+" first");
        a2(a[i]);
        alert(i
+" second");
    }
}
function a2(obj){
    
for (i in obj) {
    }
    
return "hello";
}
</script>
<body onload="a1();">


在第一ơalert(i)?0 first
在第二次alert(i)?name second

Z么会出现q样的情况,明明在a2函数传进ȝ是实参,q且也没有对参数a[i]q行改写
在反复查看问题后发现是i变量的问题,在函数a1()中,i被定义成Z全局变量Q而在函数a2()中,i又是一个全局变量Q所以在a2的for (i in obj) 循环中i被重新赋值成"name"
q个乌龙是没有养成在一些时函数定义成局部变量造成的,特别是在一些forQwhileQif的操作中Q时变量必d义成局部变量否则会出现全局变量被改写的情况?br />
再回一下定义全局变量Q局部变量的规则
在函数外部,使用varQ或直接使用变量Q如var a=1;?a=1; 定义了全局变量
在函数内部,直接使用变量Q如a=1;也定义了全局变量
在函数内部,使用varq行定义是局部变?br />
修改一下上面的代码

<script>
function a1(){
    
var a = [{"name":"1"},{"name":"2"},{"name":"3"}];
    
for(var i=0;i<a.length;i++){
        alert(i
+" first");
        a2(a[i]);
        alert(i
+" second");
    }
}
function a2(obj){
    
for (var i in obj) {
    }
    
return "hello";
}
</script>
<body onload="a1();">


]]>
房地图google map的初步应用点?4)http://www.tkk7.com/dongbule/archive/2011/06/02/351597.html陈于?/dc:creator>陈于?/author>Thu, 02 Jun 2011 06:01:00 GMThttp://www.tkk7.com/dongbule/archive/2011/06/02/351597.htmlhttp://www.tkk7.com/dongbule/comments/351597.htmlhttp://www.tkk7.com/dongbule/archive/2011/06/02/351597.html#Feedback1http://www.tkk7.com/dongbule/comments/commentRss/351597.htmlhttp://www.tkk7.com/dongbule/services/trackbacks/351597.html房地图google map的初步应用点?1)

google map距的实现和分析

不断有传闻google map在今q的7?号之后在大陆停止q营Q具体原因是因ؓ天朝的牌照问题,q个׃多讲了,可以发现现在搜房|的地图Q和安居客等的地囄U都撤下 google mapQ而重新选择了mapabc或baiduQ当然网易房产地图也不例外,现在也在使用mapabc作ؓ|易房地图的开发,预计在6月底前上U,?时再跟大家分享一下mapabc的一些开发实c?br />
q是说回google map的开发,自从上次Z个qq就有不h在问距怎么实现Q当然很多h想的是拿来主义的Q当时是拿http://xf.house.163.com /gz/map/000B.html的例子出来,但确实页面上q行了封装也写得比较乱,所以还是比较难以抽,先给个简单实现的例子Q?/div>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=GBK"/>
<title>163|易房</title>
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>
<script type="text/javascript">
  
var map;
  
function initialize() {
    
var myLatlng = new google.maps.LatLng(23.116193,113.374525);
    
var myOptions = {
      zoom: 
15,
      center: myLatlng,
      mapTypeId: google.maps.MapTypeId.ROADMAP
    }
    map 
= new google.maps.Map(document.getElementById("map_canvas"), myOptions);
  }
var polyline;
var polylinesArray = [];
//距离标记数组
var lenArray = []; 
var rule = null
 
//距离
function getDistance(){
    
//启动整个地图的click侦听
    rule = google.maps.event.addListener(map,"click",function(event){
        addMarker(event.latLng);
    });
}
//d新标?/span>
function addMarker(location){
    
//标记选项
    var myOptions = {
        position : location,
        draggable :
false,
        map : map,
    };
    marker 
= new google.maps.Marker(myOptions);
    
//标记压入数l?/span>
    lenArray.push(marker);
    
//计算距离 
    drawOverlay();
}
//d路径覆盖?/span>
    function drawOverlay(){
    
//路线数组
    var flightPlanCoordinates = [];
    
//坐标压入\U数l?/span>
    if (lenArray) {
        
for (i in lenArray) {
            flightPlanCoordinates.push(lenArray[i].getPosition());
        }
    }
    
//路径选项
    var polylineOptions = {
        path : flightPlanCoordinates,
        map : map,
        strokeColor : 
"#FF0000",
        strokeOpacity : 
1.0,
        strokeWeight : 
2
    };
    polyline 
= new google.maps.Polyline(polylineOptions);
    
//清除原有折线路径
    if (polylinesArray) {
        
for (i in polylinesArray) {
            polylinesArray[i].setMap(
null);
        }
        polylinesArray 
= [];
    }
    polyline.setMap(map);
    polylinesArray.push(polyline);
    alert((polyline.getLength()
/1000).toFixed(3+ "km");
}
google.maps.LatLng.prototype.distanceFrom 
= function(latlng) {
    
var lat = [this.lat(), latlng.lat()]
    
var lng = [this.lng(), latlng.lng()] 
    
var R = 6378137;
    
var dLat = (lat[1- lat[0]) * Math.PI / 180;
    
var dLng = (lng[1- lng[0]) * Math.PI / 180;
    
var a = Math.sin(dLat / 2* Math.sin(dLat / 2+ Math.cos(lat[0* Math.PI / 180* Math.cos(lat[1* Math.PI / 180* Math.sin(dLng / 2* Math.sin(dLng / 2);
    
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
    
var d = R * c;
    
return Math.round(d);

google.maps.Marker.prototype.distanceFrom 
= function(marker) {
    
return this.getPosition().distanceFrom(marker.getPosition());
}
google.maps.Polyline.prototype.getLength 
= function() {
    
var d = 0;
    
var path = this.getPath();
    
var latlng;
    
for (var i = 0; i < path.getLength() - 1; i++) {
        latlng 
= [path.getAt(i), path.getAt(i + 1)];
        d 
+= latlng[0].distanceFrom(latlng[1]);
    }
    
return d;
}
</script>
</head>
<body onload="initialize()">
  
<div id="map_canvas" style="width: 500px; height: 400px"></div>
  
<href="#this" onclick="getDistance();">开始测?/span></a>
</body>
</html>



例子l完了,其中距的计是抄了google的示例,想简单拿来应用的到这里就可以l束了,q有点兴的可以看看下面的简单分析:

说到距无非是U的计算Q根据google map apiQ测距的U性实现我们采?strong>Polylinec,Polyline是折U是地图上的q接U段的线性叠加层Q扩展自MVCObject?/div>
距是由U组成,然后Ҏ一l线的长短计出U的启动和终点线的距,Ҏq个思\Q我们定义出
var polyline;
var polylinesArray = [];
其中polyline是当前画出来q条U,polylinesArray是一个数l,当每话出一条线将q条Upush到polylinesArrayq个数组中去?/div>
另外一条线其实是由两个点,始点和终Ҏl成Q所以我们也定义一?br />var lenArray = [];
lenArray是一个数l,用来记录鼠标点过的每一个点的信?br />也就是说整个距是由每一条线所l成Q而一条线是由2个点l成?br />
思\理清楚了Q接着一步一步看

当我们点M开始测距时Q就需要启动一个事件的监听Q对整个map的click事g监听
    rule = google.maps.event.addListener(map,"click",function(event){
        addMarker(event.latLng);
    });
当我们在地图上进行点LQ就会新增一个maker点,q且这个maker压入lenArray数组Q以便于后面的计?br />function addMarker(location){
...
marker = new google.maps.Marker(myOptions);
...
lenArray.push(marker);
drawOverlay();
接着会调用drawOverlay();使用polyline来画U?br />    var flightPlanCoordinates = [];
    //坐标压入\U数l?br />    if (lenArray) {
        for (i in lenArray) {
            flightPlanCoordinates.push(lenArray[i].getPosition());
        }
    }
    var polylineOptions = {
        path : flightPlanCoordinates,
        map : map,
        strokeColor : "#FF0000",
        strokeOpacity : 1.0,
        strokeWeight : 2
    };
    polyline = new google.maps.Polyline(polylineOptions);

其中polylineOptions的path参数是折U坐标的有序序列。可以用一个简单的 LatLng 数组或?LatLng ?MVCArray 指定此\径。请注意Q如果您?br />
递简单的数组Q则它会转换?MVCArray。在 MVCArray 中插入或删除 LatLng 自动更新地图上的折Uѝ?br />flightPlanCoordinates数组用于存储在上面我们定义的lenArray数组的坐标|每点Mơ就压入一对坐标倹{?br />strokeColor和strokeOpacityQstrokeWeight是一些样式的参数Q如指定U条的宽度等{?br />最后我们将定义的polylineq行setMapQ在地图上展玎ͼq将polyline压入到polylinesArray数组中去?br />    polyline.setMap(map);
    polylinesArray.push(polyline);
到这里,U和点的展现已经完成了,接下来是需要将q些点线转换成我们需要的距离倹{?br />
google.maps.Polyline.prototype.getLength = function() {
    var d = 0;
    var path = this.getPath();
    var latlng;
    for (var i = 0; i < path.getLength() - 1; i++) {
        latlng = [path.getAt(i), path.getAt(i + 1)];
        d += latlng[0].distanceFrom(latlng[1]);
    }
    return d;
}

q里需要讲明的是this.getPath();它的说明是检索第一条\径。ƈ且返回值是一lMVCArray.<LatLng>Q也是实际存储了一条线的坐标|在这里取些坐标的数组Qƈ且进行@环distanceFrom计算

google.maps.LatLng.prototype.distanceFrom = function(latlng) {
    var lat = [this.lat(), latlng.lat()]
    var lng = [this.lng(), latlng.lng()]
    var R = 6378137;
    var dLat = (lat[1] - lat[0]) * Math.PI / 180;
    var dLng = (lng[1] - lng[0]) * Math.PI / 180;
    var a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.cos(lat[0] * Math.PI / 180) * Math.cos(lat[1] * Math.PI / 180) * Math.sin(dLng / 2) * Math.sin(dLng / 2);
    var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
    var d = R * c;
    return Math.round(d);
}
q段计算实际上是抄自google mapCZ的,是将我们的坐标D{换成我们需要计的距离|q里׃分析Q有兴趣可以玩玩Q没兴趣q接抄q去吧?br />
l果出来了,q个是我们需要的距的距,当然你也可以用其他方式进行展?br />
alert((polyline.getLength()/1000).toFixed(3) + "km");
只要阅读google api和自己思\清楚Q一个测距的demo很快完成了Q稍加装饰基本就可以应用于生产上

如果你也在进行google map的开发,Ƣ迎赐教和讨论,Z个qq:11029590


]]>解答一下几道笔试题http://www.tkk7.com/dongbule/archive/2011/04/21/348723.html陈于?/dc:creator>陈于?/author>Thu, 21 Apr 2011 09:23:00 GMThttp://www.tkk7.com/dongbule/archive/2011/04/21/348723.htmlhttp://www.tkk7.com/dongbule/comments/348723.htmlhttp://www.tkk7.com/dongbule/archive/2011/04/21/348723.html#Feedback9http://www.tkk7.com/dongbule/comments/commentRss/348723.htmlhttp://www.tkk7.com/dongbule/services/trackbacks/348723.html
    1.cookie和session的作用以及他们的应用场合
    2.怎样让jvm加蝲一个Class的同时执行一D代?br />     3.post和get区别
    4.事务的属性有哪些Q写出spring或jdbc理事务的例?br />     5.实现一个高q发、高性能的hashmap。写Z代码
    6.解析一DxmlQ拼接成一个url?br />     7.怎么解决q发Q怎么解决集群环境下的q发?
    8.java GC的原?
    9.mysql支持事务吗?mysql存储引擎有哪些?
    10.数据库数据查找比较慢的时候,如何解决Q?br />     11.学生 评 选课的一个sql语句书写
    12.查找日志文g中某一个信息出现的ơ数
    13.32位linux操作pȝ中,最多支持多个U程Q?br />     14.关于TreeMap操作?br />     15.重写cA的equals和hascodeҎ。类A有个属性private B bQ?br />     16.实现一个mysql的sequence?br />
下面是我的一点解{,也不知道对不对,现在的笔试要你白UR字写些东西真是难啊!

1)cookie和session的作用以及他们的应用场合
两者都是记录用戯问网站信息,但他们的保持状态不同,cookie是采用客L保持Q而session是采用服务端保持Q一般来说cookie不是很安全,因ؓ别h可以分析本地的cookieq行cookieƺ骗Q考虑到安全的问题应该使用sessionQsession是保持在服务端,但当讉K增多Ӟ会增加服务器的压力?br /> 在应用场合中Q徏议徏用户dQ交易重要信息存放sessionQ其他信息可以存攑֜cookie中,Ҏ实际需求两者可以交替搭配用?br />
2)怎样让jvm加蝲一个Class的同时执行一D代?/strong>
使用Class.forName()动态加载类Q题目中?同时"Q是否启用另一U程Q)

3)post和get区别
从http动词协议来看Qget是从服务器获取数据,post是向服务器上传数?br /> get方式会把数据出现在url中,post则不?br /> get提交的数据有大小限制Qpost则无

4)事务的属性有哪些Q写出spring或jdbc理事务的例?/strong>
有原子性,一致性,隔离性,持久?br /> spring提供了丰富的事务模型Q主要是针对jdbc事务Qjta事务Q还有一些自定义事务Q如果有从一张白U写出spring transaction的例子,那真是佩服之极)
q是写一个简单jdbc事务
try{
class.forName("***");
...
conn=DriverManager.getConnection(url,user,password);
conn.createStartement().executeUpdate("****");//更新操作
conn.commit();//事务提交
}catch(Exception e){
..
conn.rollback();//事务回滚
..
}

5)实现一个高q发、高性能的hashmap。写Z代码
什么叫做高性能Q高q发的hashmap? 是要考hashmap的数据结??

6)解析一DxmlQ拼接成一个url
xml,url???q两者有什么联pd?

7)怎么解决q发Q怎么解决集群环境下的q发?
Q有很多点可以ƈ发,webh可以q发Q数据库h可以q发Q怎么那么I泛Q?br /> 高ƈ发最重要的还是考虑到锁的问题,如数据库该用表锁用表锁,该用排他锁用排它锁,E序中要注意非线E安全的问题
高ƈ发还有带来性能问题Q缓存,负蝲均衡Q这些看情况而定

8)java GC的原?
又来Q不回答?br />
9)mysql支持事务吗?mysql存储引擎有哪些?
支持Q常用的是inndb和myisam

10)数据库数据查找比较慢的时候,如何解决Q?/strong>
假如是mysql
1.漏了索引,用explain看看查询语句是不是没使用索引或者烦引用有问题
2.使用show processlist看看是不是有sql卡住?br /> 3.q有一U情况就是sql写得q于复杂Q如goroupbyQ多表关联等{,使用desc来进行分?br /> 4.q有是配置的问题,如key_buffer{参敎ͼq个看文档吧
5.最后一U就是机器负药高,调整l构来解军_Q比如用mysql-proxy代理{等

11)学生 评 选课的一个sql语句书写
??

12)查找日志文g中某一个信息出现的ơ数
cat 日志 | grep 信息 | wc -l

13) 32位linux操作pȝ中,最多支持多个U程Q?/strong>
上网查了Q写得很复杂Q附上文?br /> http://www.517sou.net/Article/Linux-maximum-number-of-threads-and-the-maximum-number-of-processes.aspx

14)关于TreeMap操作?/strong>
TreeMap是一颗^衡排序二叉树Q操作的。。后面是什??

15)重写cA的equals和hascodeҎ。类A有个属性private B bQ?/strong>
??

16)实现一个mysql的sequence
mysql的last_insert_id()大致可以满Q如果不行就写触发器?br />


]]>
房地图google map的初步应用点?3)http://www.tkk7.com/dongbule/archive/2011/03/30/347304.html陈于?/dc:creator>陈于?/author>Wed, 30 Mar 2011 08:58:00 GMThttp://www.tkk7.com/dongbule/archive/2011/03/30/347304.htmlhttp://www.tkk7.com/dongbule/comments/347304.htmlhttp://www.tkk7.com/dongbule/archive/2011/03/30/347304.html#Feedback0http://www.tkk7.com/dongbule/comments/commentRss/347304.htmlhttp://www.tkk7.com/dongbule/services/trackbacks/347304.html阅读全文

]]>
房地图google map的初步应用点?2)http://www.tkk7.com/dongbule/archive/2011/03/05/345786.html陈于?/dc:creator>陈于?/author>Sat, 05 Mar 2011 08:02:00 GMThttp://www.tkk7.com/dongbule/archive/2011/03/05/345786.htmlhttp://www.tkk7.com/dongbule/comments/345786.htmlhttp://www.tkk7.com/dongbule/archive/2011/03/05/345786.html#Feedback2http://www.tkk7.com/dongbule/comments/commentRss/345786.htmlhttp://www.tkk7.com/dongbule/services/trackbacks/345786.html阅读全文

]]>
房地图google map的初步应用点?1)http://www.tkk7.com/dongbule/archive/2011/02/12/344141.html陈于?/dc:creator>陈于?/author>Sat, 12 Feb 2011 07:57:00 GMThttp://www.tkk7.com/dongbule/archive/2011/02/12/344141.htmlhttp://www.tkk7.com/dongbule/comments/344141.htmlhttp://www.tkk7.com/dongbule/archive/2011/02/12/344141.html#Feedback6http://www.tkk7.com/dongbule/comments/commentRss/344141.htmlhttp://www.tkk7.com/dongbule/services/trackbacks/344141.html 房地图google map的初步应用点?1)
房地图google map的初步应用点?2)
房地图google map的初步应用点?3)


以前的房产地图一直都是用有道地图,虽然有道地图是很好,但是Z更好Q还是决定用google地图来重新开发^_^Q下面是一个开发完毕的单应用http://xf.house.163.com/gz/map/000B.html

1)整合Google Maps JavaScript API V3 ?Google Local Search API

Google Maps JavaScript API V3
地址 http://code.google.com/intl/zh-CN/apis/maps/documentation/javascript/

Google Maps JavaScript API V3 文档读v来真的是很清晎ͼ各种demo也很齐全Qƈ且论坛的拥有巨大的论坛支持,Ҏ了一下Google Maps JavaScript API V3 ?V2 的版本,虽然W?版的 Google Maps API 看上去跟W?版挺相识Q但在内在机制上有了较大的变化,其在对Ud览器的支持上,专门针对iphone和android讑֤的开发。V2版本google已经宣布不再予以l箋支持Q所以还是选择了V3版本?br />
Google Local Search API
地址 http://code.google.com/intl/zh-CN/apis/maps/documentation/localsearch/index.html

上面的地址是目前Local Search的最新地址Q但郁闷的是居然挂上?Deprecated Q一L文档也相当齐全,在应用之前需要先Z的域名申请一个API keyQ这个是注册地址http://code.google.com/intl/zh-CN/apis/maps/signup.htmlQ很单,按照提示很快搞定了?br />

在整合Google Maps JavaScript API V3和Google Local Search API发现q两个版本是不兼容的QLocal Search API实际上还是沿用了Maps V2的接口,Z解决q个问题Q需要中间一个蟩板得两者兼容,所以选择了iframeQ父面使用Google Maps V3Q子面使用Local Search APIQ当需要应用到本地搜烦Ӟ爉面向子页面传递查询条Ӟ子窗口应用Local Search API获得查询的result后返回给爉面,q样Ş成一个蟩板,避免了两者因为版本问题而生的冲突Q当然还有其他的办法Q不qiframe应该是比较简单处理,下面是一个demo



爉?: 使用的是Google Maps JavaScript API V3Qhttp://maps.google.com/maps/api/js |址指向 Javascript 文g所在的位置Q该文g会蝲入用第 3 ?Google Maps API 所需的全部符号和定义?br />
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type" content="text/html; charset=GBK"/>
<title>Google AJAX Search API Sample</title>
<style type="text/css"> 
@import url("http://www.google.com/uds/css/gsearch.css");
@import url("http://www.google.com/uds/solutions/localsearch/gmlocalsearch.css");
@import url("http://www.google.com/uds/css/gsearch.css");
@import url("http://www.google.com/uds/solutions/localsearch/gmlocalsearch.css");

</style>
<script type="text/javascript" src="http://xf.house.163.com/product/js/jquery.js"></script>
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>
<script type="text/javascript">
      
var map;
      
var lat = 23.116193;
      
var lng = 113.374525;
      
var markersArray = [];
      
var windowArray = [];
      
function initialize() {
        
var mapDiv = document.getElementById('map-canvas');
          map 
= new google.maps.Map(mapDiv, {
          center: 
new google.maps.LatLng(lat,lng),
          zoom: 
15,
          mapTypeId: google.maps.MapTypeId.ROADMAP
        });
      }
 
      
//删除叠加?/span>
      function deleteOverlays() {
          
if (markersArray) {
            
for (i in markersArray) {
              markersArray[i].setMap(
null);
            }
            markersArray.length 
= 0;
          }
      }
 
      
//关闭信息提示H口
      function closeWindows() {
          
if (windowArray) {
            
for (i in windowArray) {
                windowArray[i].close();
            }
          }
         }
      
      
function show(results){
          parent.deleteOverlays();
          windowArray.length 
= 0;
          
for (var i = 0; results && i < results.length; i++) {
              showOne(results[i]);
          }
      }
      
function showOne(result){
          
//console.debug(result.title+","+result.lat+":" + result.lng +","+result.streetAddress+","+result.city+","+result.url);
          var infowindow = new google.maps.InfoWindow({
              content: result.html
            });
            
var marker = new google.maps.Marker({
                position: 
new google.maps.LatLng(result.lat,result.lng),
              map: map
            });
            markersArray.push(marker);
            windowArray.push(infowindow);
            google.maps.event.addListener(marker, 'click', 
function() {
              closeWindows();
                infowindow.open(map,marker);
            });
      }

      
function searchMap(){
          
var keyWord = document.getElementById("keyWord").value;
          mapIframe.window.loadMap(
23.116193,113.374525,keyWord);
      }
      google.maps.event.addDomListener(window, 'load', initialize);
    
</script>
</head>
<body style="">
<div id="map-canvas" style="width: 600px; height: 500px"></div>
<input type="text" name="keyWord" id="keyWord"/>
<input type="button" onclick="searchMap();" value="查询" id="btn"/>
<iframe name="mapIframe" id="mapIframe" style="display:none" src="local.html"></iframe>
</body>
</html>


子页面:http://www.google.com/jsapi?key 需要在googleq行甌与域名绑?br />
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type" content="text/html; charset=GBK"/>
<script src="http://www.google.com/jsapi?key=ABQIAAAAtV_DTJOYJT-9cvTO-5KJ2BSnjw5qeDlzCnItJoREFggHbBwu_RQBEyFqvq_vMlzqsS4afIB8ZIvMkw" type="text/javascript"></script>
<script type="text/javascript"> 
    google.load('search', '
1');
    google.load('maps', '
2');
 
    
function loadMap(lat,lng,keyWord) {
        
var point = new GLatLng(lat,lng);
        console.debug(keyWord
+"-"+lat+","+lng);
        searchMap(point,keyWord);
    }
        
    
function searchMap(point,keyWord){
        
var searcher = new google.search.LocalSearch();
        searcher.setCenterPoint(point);
        searcher.setResultSetSize(GSearch.LARGE_RESULTSET);
        searcher.setSearchCompleteCallback(
thisfunction() {
          parent.show(searcher.results); 
        });
        searcher.execute(keyWord);
    }
</script>
</head>
<body></body>
</html>


摘录几个常用的Local Search API Reference

new google.search.LocalSearch() : 创徏了一个LocalSearch的Service

searcher.setCenterPoint(point) : 它接受单一变量Q该变量可以是字W串、google.maps.Map2 或google.maps.LatLng。如果是字符Ԍ会尝试将字符串解析ؓ google.maps.LatLng

searcher.setResultSetSize(8) : 调用此方法以选择由每个搜索器q回的结果数

searcher.setRestriction() : 讄搜烦l构cd

searcher.setSearchCompleteCallback() : 此方法用于注册对象和Ҏ以通知搜烦完成。应用程序可以通过使用 opt_arguments之后随意传入环境参数

searcher.execute(keyWord) :  调用此方法以开始新的搜索 

W一步解决了map和local search的版本冲H后Q下面可以进行全部的开发,Google Maps JavaScript API提供的UIQEVENT相关接口非常之多Q但不一定就能直接适用我们的需求,q需要用承基cMVCObjectQOverlayView{l封装?br />
如果你也在进行google map的开发,Ƣ迎赐教和讨论,Z个qq:11029590

----------------------------------------

by 陈于?
QQ:34174409
Mail: dongbule@163.com

]]>
Minimal POMhttp://www.tkk7.com/dongbule/archive/2010/12/29/341924.html陈于?/dc:creator>陈于?/author>Wed, 29 Dec 2010 09:50:00 GMThttp://www.tkk7.com/dongbule/archive/2010/12/29/341924.htmlhttp://www.tkk7.com/dongbule/comments/341924.htmlhttp://www.tkk7.com/dongbule/archive/2010/12/29/341924.html#Feedback0http://www.tkk7.com/dongbule/comments/commentRss/341924.htmlhttp://www.tkk7.com/dongbule/services/trackbacks/341924.html
project root
modelVersion - should be set to 4.0.0
groupId - the id of the project's group.
artifactId - the id of the artifact (project)
version - the version of the artifact under the specified group

Here's an example:

<project>
   
<modelVersion>4.0.0</modelVersion>  
   
<groupId>com.juvenxu.mvnbook</groupId>  
   
<artifactId>hello-world</artifactId>  
   
<version>1.0-SNAPSHOT</version>  
</project>  

A POM requires that its groupId, artifactId, and version be configured. These three values form the project's fully qualified artifact name.

modelVersion指定了当前POM模型的版本,对于Maven2及Maven 3来说Q它只能?.0.0
groupId定义了项目属于哪个组Q这个组往往和项目所在的l织或公司存在关?如果你的公司是mycomQ有一个项目ؓmyappQ那么groupId应该是com.mycom.myapp
artifactId定义了当前Maven目在组中唯一的ID
version指定了项目当前的版本,SNAPSHOT意ؓ快照Q说明该目q处于开发中Q是不稳定的版本
此外,如果配置的其他细节没有被指定,Maven会用它们的默认?br /> Furthermore,你可以看?在Minimal POM中未指定仓库,如果你的目是采用最的pom,那么它是会承所谓的Super POM,所以就你没有指定仓库,maven也知道所有的依赖直接从网?http://repo1.maven.org/maven2)下蝲





]]>
解决hessianq程调用q接时的问?/title><link>http://www.tkk7.com/dongbule/archive/2010/12/16/340894.html</link><dc:creator>陈于?/dc:creator><author>陈于?/author><pubDate>Thu, 16 Dec 2010 06:46:00 GMT</pubDate><guid>http://www.tkk7.com/dongbule/archive/2010/12/16/340894.html</guid><wfw:comment>http://www.tkk7.com/dongbule/comments/340894.html</wfw:comment><comments>http://www.tkk7.com/dongbule/archive/2010/12/16/340894.html#Feedback</comments><slash:comments>10</slash:comments><wfw:commentRss>http://www.tkk7.com/dongbule/comments/commentRss/340894.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/dongbule/services/trackbacks/340894.html</trackback:ping><description><![CDATA[目前几套pȝ中主要用的hessianq行q程调用webservice服务的有hessian的HessianProxyFactory(com.caucho.hessian.client.HessianProxyFactory)和spring的HessianProxyFactoryBean(org.springframework.remoting.caucho.HessianProxyFactoryBean).<br /> <br /> <strong>1.HessianProxyFactory</strong><br /> 查看HessianProxyFactory源码后发?hessian在创建httphq接webservice服务q没有对q接时q行相关的参数设|?所以当|络出现问题׃造成整个hessian处理的阻?q而阻塞整个线E后l的处理<br /> 以下是HessianProxyFactory对连接处理的源码<br /> <br /> <div style="background-color: rgb(238, 238, 238); font-size: 13px; border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; width: 98%;"><!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --><span style="color: rgb(0, 0, 255);">protected</span><span style="color: rgb(0, 0, 0);"> URLConnection openConnection(URL url)<br />     </span><span style="color: rgb(0, 0, 255);">throws</span><span style="color: rgb(0, 0, 0);"> IOException<br />   {<br />     URLConnection conn </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> url.openConnection();<br /> <br />     conn.setDoOutput(</span><span style="color: rgb(0, 0, 255);">true</span><span style="color: rgb(0, 0, 0);">);<br /> <br />     </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> (_readTimeout </span><span style="color: rgb(0, 0, 0);">></span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">) {<br />       </span><span style="color: rgb(0, 0, 255);">try</span><span style="color: rgb(0, 0, 0);"> {<br />     conn.setReadTimeout((</span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);">) _readTimeout);<br />       } </span><span style="color: rgb(0, 0, 255);">catch</span><span style="color: rgb(0, 0, 0);"> (Throwable e) {<br />       }<br />     }<br /> <br />     conn.setRequestProperty(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">Content-Type</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">, </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">x-application/hessian</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br /> <br />     </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> (_basicAuth </span><span style="color: rgb(0, 0, 0);">!=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">null</span><span style="color: rgb(0, 0, 0);">)<br />       conn.setRequestProperty(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">Authorization</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">, _basicAuth);<br />     </span><span style="color: rgb(0, 0, 255);">else</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> (_user </span><span style="color: rgb(0, 0, 0);">!=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">null</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">&&</span><span style="color: rgb(0, 0, 0);"> _password </span><span style="color: rgb(0, 0, 0);">!=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">null</span><span style="color: rgb(0, 0, 0);">) {<br />       _basicAuth </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">Basic </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);"> base64(_user </span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);"> _password);<br />       conn.setRequestProperty(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">Authorization</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">, _basicAuth);<br />     }<br /> <br />     </span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);"> conn;<br />   }</span></div> <br /> 所以我们针Ҏ逻辑l承q写该openConnectionҎ,在创建httpq接的时候通过讄q接时旉来解军_|络问题dE序l箋的问?br /> <br /> <div style="background-color: rgb(238, 238, 238); font-size: 13px; border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; width: 98%;"><!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">class</span><span style="color: rgb(0, 0, 0);"> MyHessianProxyFactory </span><span style="color: rgb(0, 0, 255);">extends</span><span style="color: rgb(0, 0, 0);"> HessianProxyFactory {<br /> <br />     </span><span style="color: rgb(0, 0, 255);">private</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> connectTimeOut </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">10000</span><span style="color: rgb(0, 0, 0);">;<br /> <br />     </span><span style="color: rgb(0, 0, 255);">private</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> readTimeOut </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">10000</span><span style="color: rgb(0, 0, 0);">;<br /> <br />     </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> getConnectTimeOut() {<br />         </span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);"> connectTimeOut;<br />     }<br /> <br />     </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> setConnectTimeOut(</span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> connectTimeOut) {<br />         </span><span style="color: rgb(0, 0, 255);">this</span><span style="color: rgb(0, 0, 0);">.connectTimeOut </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> connectTimeOut;<br />     }<br /> <br />     </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> getReadTimeOut() {<br />         </span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);"> readTimeOut;<br />     }<br /> <br />     </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> setReadTimeOut(</span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> readTimeOut) {<br />         </span><span style="color: rgb(0, 0, 255);">this</span><span style="color: rgb(0, 0, 0);">.readTimeOut </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> readTimeOut;<br />     }<br /> <br />     </span><span style="color: rgb(0, 0, 255);">protected</span><span style="color: rgb(0, 0, 0);"> URLConnection openConnection(URL url) </span><span style="color: rgb(0, 0, 255);">throws</span><span style="color: rgb(0, 0, 0);"> IOException {<br />         URLConnection conn </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> url.openConnection();<br />         conn.setDoOutput(</span><span style="color: rgb(0, 0, 255);">true</span><span style="color: rgb(0, 0, 0);">);<br />         </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> (</span><span style="color: rgb(0, 0, 255);">this</span><span style="color: rgb(0, 0, 0);">.connectTimeOut </span><span style="color: rgb(0, 0, 0);">></span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">) {<br />             conn.setConnectTimeout(</span><span style="color: rgb(0, 0, 255);">this</span><span style="color: rgb(0, 0, 0);">.connectTimeOut);<br />         }<br />         </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> (</span><span style="color: rgb(0, 0, 255);">this</span><span style="color: rgb(0, 0, 0);">.readTimeOut </span><span style="color: rgb(0, 0, 0);">></span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">) {<br />             conn.setReadTimeout(</span><span style="color: rgb(0, 0, 255);">this</span><span style="color: rgb(0, 0, 0);">.readTimeOut);<br />         }<br />         conn.setRequestProperty(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">Content-Type</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">, </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">x-application/hessian</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br />             </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> (_basicAuth </span><span style="color: rgb(0, 0, 0);">!=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">null</span><span style="color: rgb(0, 0, 0);">)<br />                   conn.setRequestProperty(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">Authorization</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">, _basicAuth);<br />             </span><span style="color: rgb(0, 0, 255);">else</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> (_user </span><span style="color: rgb(0, 0, 0);">!=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">null</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">&&</span><span style="color: rgb(0, 0, 0);"> _password </span><span style="color: rgb(0, 0, 0);">!=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">null</span><span style="color: rgb(0, 0, 0);">) {<br />                   _basicAuth </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">Basic </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);"> base64(_user </span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);"> _password);<br />                   conn.setRequestProperty(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">Authorization</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">, _basicAuth);<br />             }<br />         </span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);"> conn;<br />     }<br /> }</span></div> <br /> <strong>2.HessianProxyFactoryBean</strong><br /> 查看spring的HessianProxyFactoryBean源码发现,它在装hessian是直接创Z个HessianProxyFactory实例,然后利用该实例完成创E服?br /> <br /> <div style="background-color: rgb(238, 238, 238); font-size: 13px; border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; width: 98%;"><!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">class</span><span style="color: rgb(0, 0, 0);"> HessianProxyFactoryBean </span><span style="color: rgb(0, 0, 255);">extends</span><span style="color: rgb(0, 0, 0);"> HessianClientInterceptor </span><span style="color: rgb(0, 0, 255);">implements</span><span style="color: rgb(0, 0, 0);"> FactoryBean {<br /> <br />     </span><span style="color: rgb(0, 0, 255);">private</span><span style="color: rgb(0, 0, 0);"> Object serviceProxy;<br /> <br /> <br />     </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> afterPropertiesSet() {<br />         </span><span style="color: rgb(0, 0, 255);">super</span><span style="color: rgb(0, 0, 0);">.afterPropertiesSet();<br />         </span><span style="color: rgb(0, 0, 255);">this</span><span style="color: rgb(0, 0, 0);">.serviceProxy </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> ProxyFactory.getProxy(getServiceInterface(), </span><span style="color: rgb(0, 0, 255);">this</span><span style="color: rgb(0, 0, 0);">);<br />     }<br />     <br /> <br />     </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> Object getObject() {<br />         </span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">this</span><span style="color: rgb(0, 0, 0);">.serviceProxy;<br />     }<br /> <br />     </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> Class getObjectType() {<br />         </span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);"> getServiceInterface();<br />     }<br />     <br />     </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">boolean</span><span style="color: rgb(0, 0, 0);"> isSingleton() {<br />         </span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">true</span><span style="color: rgb(0, 0, 0);">;<br />     }<br /> <br /> }</span></div> <br /> 所以对此的解决Ҏ与上面差不多,l承HessianProxyFactoryBean然后加入相应的连接超时和d时的变?重写afterPropertiesSetҎ,q且同时完成上面W一步对HessianProxyFactory的改?q样p保证q接q程webserver服务器时不会因ؓ|络原因dE序的执?br /> <br /> <div style="background-color: rgb(238, 238, 238); font-size: 13px; border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; width: 98%;"><!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">class</span><span style="color: rgb(0, 0, 0);"> MyHessianProxyFactoryBean </span><span style="color: rgb(0, 0, 255);">extends</span><span style="color: rgb(0, 0, 0);"> HessianProxyFactoryBean {<br /> <br />     </span><span style="color: rgb(0, 0, 255);">private</span><span style="color: rgb(0, 0, 0);"> MyHessianProxyFactory proxyFactory </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);"> MyHessianProxyFactory();<br /> <br />     </span><span style="color: rgb(0, 0, 255);">private</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> readTimeOut </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">10000</span><span style="color: rgb(0, 0, 0);">;<br /> <br />     </span><span style="color: rgb(0, 0, 255);">private</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> connectTimeOut </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">10000</span><span style="color: rgb(0, 0, 0);">;<br /> <br />     </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> getReadTimeOut() {<br />         </span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);"> readTimeOut;<br />     }<br /> <br />     </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> setReadTimeOut(</span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> readTimeOut) {<br />         </span><span style="color: rgb(0, 0, 255);">this</span><span style="color: rgb(0, 0, 0);">.readTimeOut </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> readTimeOut;<br />     }<br /> <br />     </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> getConnectTimeOut() {<br />         </span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);"> connectTimeOut;<br />     }<br /> <br />     </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> setConnectTimeOut(</span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> connectTimeOut) {<br />         </span><span style="color: rgb(0, 0, 255);">this</span><span style="color: rgb(0, 0, 0);">.connectTimeOut </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> connectTimeOut;<br />     }<br /> <br />     </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> afterPropertiesSet() {<br />         proxyFactory.setReadTimeout(readTimeOut);<br />         proxyFactory.setConnectTimeOut(connectTimeOut);<br />         setProxyFactory(proxyFactory);<br />         </span><span style="color: rgb(0, 0, 255);">super</span><span style="color: rgb(0, 0, 0);">.afterPropertiesSet();<br />     }<br /> }</span></div> <br /> <br /> <img src ="http://www.tkk7.com/dongbule/aggbug/340894.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/dongbule/" target="_blank">陈于?/a> 2010-12-16 14:46 <a href="http://www.tkk7.com/dongbule/archive/2010/12/16/340894.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Javascript eval()使用上需要注意的安全问题http://www.tkk7.com/dongbule/archive/2010/12/15/340755.html陈于?/dc:creator>陈于?/author>Wed, 15 Dec 2010 03:31:00 GMThttp://www.tkk7.com/dongbule/archive/2010/12/15/340755.htmlhttp://www.tkk7.com/dongbule/comments/340755.htmlhttp://www.tkk7.com/dongbule/archive/2010/12/15/340755.html#Feedback0http://www.tkk7.com/dongbule/comments/commentRss/340755.htmlhttp://www.tkk7.com/dongbule/services/trackbacks/340755.html
     function parsePost(data, action) {
         
try {
             
var postData = eval("(" + data + ")");
             
             
// TO DO1
         } catch (e) {
             
             
// TO DO2
         }
     }


q是一D页面的老代?data是数据库body字段,既是用户录入q取出的数据,׃业务的关p?data是以json格式保存?Z使数据能实现兼容,q里使用try...catch...方式处理,如果变量data能被转换成对?则执行TO DO1,否则执行TO DO2.
我们知道eval的作用很?是把一D字W串传递给js解析?由javascript解析器将q段字符串解释成为javascript代码,q且执行.不过q也是非常危?其是在l它传递用戯入的数据?q往往是恶意用户的一个切入点.
安装上面的代?如果用户输入的data是一Djs代码,?alert('hello')",那么q段代码用数据库出来后显C部分就会eval("alert('hello')"),q时我的面׃以alert提示框的方式弹了出来.

好了,q个是大家都知道的 Cross-site scripting (XSS)Q中文翻译是跨站脚本d?br />
Cross-site scripting (XSS) is a type of computer security vulnerability typically found in web applications which allow code injection by malicious web users into the web pages viewed by other users. Examples of such code include HTML code and client-side scripts. Q摘自《Cross-site scripting》http://en.wikipedia.org/wiki/Cross- site_scriptingQ这里介l了 XSS 的背景,cdQ利用和防范{几斚w内容?br />
下面开始修复工作。这D代码显然没能对 data 作好严格的判断工作,data 不但是用戯入的内容Q还要被g万恶?eval() 函数执行Q而整个过E没有对 用户输入?data q行一个校验工作,q就是问题所在,而且问题相当严重?br />
针对跟脓pȝ此段代码的业务逻辑Q可以通过判断 data 的数据类型来定光辑l构Q更改后的代码如下∶

     function parsePost(data, action) {
         
if (typeof(data) == 'string') {
             
             
// TO DO2
         }
         
else {
             
// TO DO1
         }
     }


代码在主体上修改如上Q我们的选择是,l开 eval() 函数Q把 body 的原型赋l?Javascript 的变?dataQ然后?typeof() 来对 data 作判断处理,q且Ҏ此判断l下一步的处理?br /> 另外也可以是使用 JSON 解析器对 JSON q行解析Q可从http: //www.json.org/json.js 下蝲的参考实现脚本。JSON 是一U基于文本的开攑ּ数据交换格式Q请参见 RFC 4627Q?br />
ps:此bug发生?008q?跟帖受xssd


]]>
memcached一些应用点?/title><link>http://www.tkk7.com/dongbule/archive/2010/12/08/340066.html</link><dc:creator>陈于?/dc:creator><author>陈于?/author><pubDate>Wed, 08 Dec 2010 07:00:00 GMT</pubDate><guid>http://www.tkk7.com/dongbule/archive/2010/12/08/340066.html</guid><wfw:comment>http://www.tkk7.com/dongbule/comments/340066.html</wfw:comment><comments>http://www.tkk7.com/dongbule/archive/2010/12/08/340066.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.tkk7.com/dongbule/comments/commentRss/340066.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/dongbule/services/trackbacks/340066.html</trackback:ping><description><![CDATA[大名鼎鼎的分布式~存pȝmemcachedQ在开源社Z可谓是无Z知无Z晓,memcached支持分布式的横向扩展Q但memcached的服务端却是单实例,q无"分布?的功能,所谓的分布式只是客L在存储的主键做分布的存储Q还有memcachedlg~存对象Q如果组件无q行序列化必定无法正取得数据;如何使用memcached的javalg来监控memcached的运行状态;以上{等的问题是我在日常的工作中到q解决的,拿出来跟大家做个分n^_^<br /> <br /> <hr width="100%" size="2" /> <br /> <strong>对象的序列化</strong><br /> 首先memcached是独立的服务器组?独立于应用系l?从客L保存和读取对象到memcached是必通过|络传输,因ؓ|络传输都是二进制的数据,所以所有的对象都必ȝq序列化,否则无法存储到memcahced的服务器?<br /> 正如我们以往在集中应用的序列化一?memcached的序列化的性能也是往往让大家头?如果我们Ҏ们的domainc进行对象的序列?W一ơ序列化旉会比较长,但后l会优化,也就是说序列化最大的消耗不是对象的序列?而是cȝ序列?如果存储的只是一个String对象,q种情况是最理想?省去了序列化的操?实际上String对象本n已经实现了序列化接口,无法我们再次去进行序列化操作.<br /> <br /> <hr width="100%" size="2" /> <br /> <strong>memcached的原子加?/strong><br /> 记录一下上ơ犯得一个错?br /> <div style="background-color: #eeeeee; font-size: 13px; border: 1px solid #cccccc; padding: 4px 5px 4px 4px; width: 98%;"><!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --><span style="color: #000000;"><%</span><span style="color: #000000;"><br /> </span><span style="color: #0000ff;">static</span><span style="color: #000000;"> </span><span style="color: #0000ff;">int</span><span style="color: #000000;"> count </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #000000;">0</span><span style="color: #000000;">;<br /> count</span><span style="color: #000000;">++</span><span style="color: #000000;">;<br /> MemCachedClient mcc </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #0000ff;">new</span><span style="color: #000000;"> MemCachedClient();<br /> mcc.add(</span><span style="color: #000000;">"</span><span style="color: #000000;">test.html</span><span style="color: #000000;">"</span><span style="color: #000000;">, count);<br /> </span><span style="color: #000000;">%></span></div> <br /> q段代码的作用是test.html的用戯问次C存到memcached?_劣一看好像ƈ无错?但在高ƈ发时的出来的讉K数据一定是于实际的访问数?当然q里q不是memcached对象锁的问题,主要q是E序中线E的同步问题,但是如果使用java的synchronized或lock那么在性能上肯定是无法忍受?memcached客户端组件带有原子性的加法和减?br /> <br /> <div style="background-color: #eeeeee; font-size: 13px; border: 1px solid #cccccc; padding: 4px 5px 4px 4px; width: 98%;"><!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --><span style="color: #000000;"><%</span><span style="color: #000000;"><br /> MemCachedClient mcc </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #0000ff;">new</span><span style="color: #000000;"> MemCachedClient();<br /> System.out.println(mcc.addOrIncr(</span><span style="color: #000000;">"</span><span style="color: #000000;">test.html</span><span style="color: #000000;">"</span><span style="color: #000000;">,</span><span style="color: #000000;">1</span><span style="color: #000000;">));<br /> </span><span style="color: #000000;">%></span></div> <br /> long addORIncr(String key,long inc)数器值增加inc,如果计数器不存在,则保存inc数器的?必须注意的是服务器端不会对超q??2ơ方的行行检?br /> <br /> <hr width="100%" size="2" /> <br /> <br /> <strong>分布式的mencached</strong><br /> memcached虽然是属于分布式的缓存服务器,但实际上memcached服务端之间ƈ无分布式的功?不会互相通信׃n数据,如何q行分布?q完全是取决于客L的实?br /> <br /> <img alt="" src="http://www.tkk7.com/images/blogjava_net/dongbule/memcached/2.png" width="456" height="390" /><br /> <br /> 假设我们现在有三台memcached服务器分别ؓnode1Qnode2Qnode3Q应用程序要保存键名分别?test1","test2","test3",客户端实现的法是Ҏ键名来决定保存数据的memcached服务?我们?test1"保存到node1Q?test2"保存到node2Q?test3"保存到node3Qƈ且在d~存数据也是通过一L法从各台服务器上读取相应的key,q样通过一个最单的法不同的键保存到不同的服务器?实现了memcached的分布式.<br /> 但是q种法很难保每台服务器得到较为^均的数据?我们需要改变一下客L的算?单来?是Ҏ服务器的台数的余数进行分?br /> <br /> <div style="background-color: #eeeeee; font-size: 13px; border: 1px solid #cccccc; padding: 4px 5px 4px 4px; width: 98%;"><!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --><span style="color: #000000;"><%<br /> "</span><span style="color: #000000;">test1</span><span style="color: #000000;">"</span><span style="color: #000000;">.hashCode()</span><span style="color: #000000;">%</span><span style="color: #000000;">3<br /> %><br /> </span></div> <br /> Ҏkey的java.lang.String.hashCode()取得散列?再将值模服务器的台数得到余数?我们再根据这个余数值来判定q个key要存入哪一台服务器,当key的数量越来越?对key的散列取模也会趋向^?基本可以保证几台memcached服务器所存储的缓存量向q_<br /> g很完?余数计算的方法很?数据的分散性也很优U,但也有其~点,是当需要添加或U除服务器时,~存的重l代h相当巨大?d或移除服务器?余数׃发生变化,q样无法取C原来~存时相同的服务?<br /> |上介绍的Consistent Hashing法基本上可以解册个问?q里做个单的说明,首先是求出memcached服务器节点的哈希?q将光|到0-2?2ơ方的圆?然后用同LҎ求出存储数据的键的哈希?q映到圆上.然后从数据映到的位|开始顺旉查找,数据保存到扑ֈ的第一个服务器?如果过2?2ơ方仍然找不到服务器,׃保存到第一台memcached服务器上<br /> <img alt="" src="http://www.tkk7.com/images/blogjava_net/dongbule/memcached/3.png" width="512" height="421" /><br /> <br /> 从上囄状态中d一台memcached服务器。余数分布式法׃保存键的服务器会发生巨大变化而媄响缓存的命中率,但Consistent Hashing中,只有在continuum上增加服务器的地炚w时针方向的W一台服务器上的键会受到影响<br /> <br /> <hr width="100%" size="2" /> <br /> <strong>几种q接客户端的Ҏ</strong><br /> 目前java的memcached主要有Java-Memcached-Client,Xmemached,Spymemcached三种,q三个客L的性能试可以?br /> http://xmemcached.googlecode.com/svn/trunk/benchmark/benchmark.html<br /> <br /> <img alt="" src="http://www.tkk7.com/images/blogjava_net/dongbule/memcached/4.png" width="942" height="612" /><br /> h的资源ؓ64Bytes,在低q发Java-Memcached-Client是占有一定的优势,但在q发数超q?00以后,Java-Memcached-Client是呈现直U下?q发数达?00已经无法承受,Spymemcached和Xmemached表现相对E_,特别是Xmemached无论在低q发或高q发都保持优U的性能表现<br /> <br /> <img alt="" src="http://www.tkk7.com/images/blogjava_net/dongbule/memcached/5.png" width="950" height="610" /><br /> <br /> q发数固定ؓ100?在小文g的请求Java-Memcached-Clientq是占有优势,当随着h的size来大,三者趋向于同一?br /> 如果你对memcached讉K的负载不?那么Java-Memcached-Client是一个不错的选择,如果你对memcached讉K的负载要求较?推荐使用Xmemached,如果需要异步的扚w处理,可以选择Spymemcached,如果你什么都不知?那么使用Xmemached,因ؓ无论在何U情?它都可以表现好的性能,虽然不是最?br /> <br /> <hr width="100%" size="2" /> <br /> <strong>监控memcached </strong><br /> 推荐使用nagios或cactisq行监控,nagios没有配置q?cactis是需要下载一个脚本插?br /> q里推荐一个从|上淘来的php,只要把它攑ֈ你的机器?当然你的机器要支持php环境,此php攑օ你的|页讉K|络可以访?br /> 下蝲<br /> <a href="/Files/dongbule/cacti/memcache.rar">http://www.tkk7.com/Files/dongbule/cacti/memcache.rar</a><br /> 修改php以下几个选项<br /> <br /> <div style="background-color: #eeeeee; font-size: 13px; border: 1px solid #cccccc; padding: 4px 5px 4px 4px; width: 98%;"><!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --><span style="color: #008080;">define</span><span style="color: #000000;">(</span><span style="color: #000000;">'</span><span style="color: #000000;">ADMIN_USERNAME</span><span style="color: #000000;">'</span><span style="color: #000000;">,</span><span style="color: #000000;">'</span><span style="color: #000000;">memcache</span><span style="color: #000000;">'</span><span style="color: #000000;">);    </span><span style="color: #008000;">//</span><span style="color: #008000;"> Admin Username</span><span style="color: #008000;"><br /> </span><span style="color: #008080;">define</span><span style="color: #000000;">(</span><span style="color: #000000;">'</span><span style="color: #000000;">ADMIN_PASSWORD</span><span style="color: #000000;">'</span><span style="color: #000000;">,</span><span style="color: #000000;">'</span><span style="color: #000000;">password</span><span style="color: #000000;">'</span><span style="color: #000000;">);    </span><span style="color: #008000;">//</span><span style="color: #008000;"> Admin Password</span><span style="color: #008000;"><br /> </span><span style="color: #000000;"><br /> </span><span style="color: #800080;">$MEMCACHE_SERVERS</span><span style="color: #000000;">[] </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #000000;">'</span><span style="color: #000000;">192.168.1.100:11211</span><span style="color: #000000;">'</span><span style="color: #000000;">; </span><span style="color: #008000;">//</span><span style="color: #008000;"> add more as an array</span><span style="color: #008000;"><br /> #</span><span style="color: #008000;">$MEMCACHE_SERVERS[] = 'mymemcache-server2:11211'; // add more as an array</span></div> <br /> 监控的^?br /> <br /> <img alt="" src="http://www.tkk7.com/images/blogjava_net/dongbule/memcached/6.png" width="992" height="422" /><br /> <br /> <hr width="100%" size="2" /> <br /> <strong>理解memcached的删除机?/strong><br /> memcached内部不会监视记录是否q期,而是在get时查看记录的旉?查记录是否过? q种技术被UCؓlazy(惰?expiration.因此,memcached不会在过期监视上耗费CPU旉<br /> memcached会优先用已时的记录的I间,q用LRU法来分配空?因此当memcached的内存空间不?׃最q违背用的记录中搜?q将I间分配l新的记?br /> 不过在某些情况下LRU机制会造成某些ȝ,如你q不惌淘汰已被~存q的记录,可以在memcached启动时添?-M 参数来禁止LRU,但这样在memcached的内存用时,memcached会返回错?是否使用LRU,在于你的需?br /> <br /> <br /> ----------------------------------------<br /> <br /> by 陈于?<br /> QQ:34174409<br /> Mail: dongbule@163.com<br /> <br /> <br /> <br /> <img src ="http://www.tkk7.com/dongbule/aggbug/340066.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/dongbule/" target="_blank">陈于?/a> 2010-12-08 15:00 <a href="http://www.tkk7.com/dongbule/archive/2010/12/08/340066.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>?lt;代码大全>的一点记录之1http://www.tkk7.com/dongbule/archive/2010/12/07/340008.html陈于?/dc:creator>陈于?/author>Tue, 07 Dec 2010 09:59:00 GMThttp://www.tkk7.com/dongbule/archive/2010/12/07/340008.htmlhttp://www.tkk7.com/dongbule/comments/340008.htmlhttp://www.tkk7.com/dongbule/archive/2010/12/07/340008.html#Feedback0http://www.tkk7.com/dongbule/comments/commentRss/340008.htmlhttp://www.tkk7.com/dongbule/services/trackbacks/340008.html
书读的不?不过刚开始读?00多页有一Ҏ?所以做了一点记?叫读<代码大全>的一点记录之1.

利用隐喻
隐喻通过把Y件开发与你所熟知的事情联pd一?从而你对其更有深ȝ理解,正是因ؓ如此在计机中的发展不过仅有数十q的历史,却拥有着所有科学最Z富多彩的语言

盖房子的隐喻
狗屋
霚w啪啦,木材加铁?犯错了怎么?无所?拆了再来q?br />


盖一栋房?/strong>
军_什么类型的房子-->问题定义
和某个徏{师探讨M的设?->软g架构设计
d详细的蓝?->详细设计
打地?搭徏房屋框架,砌墙,盖好屋顶,同水,?煤气-->软g构徏(~程)
Ҏ工和装修工把新盖的家q行化-->软g的优?br /> 监查人员来检查工?地基,布线-->软g的复?br />


我们会发现很多Y件工E学的名U就是从建筑学演变而来的如
软g架构(建筑?architecture)
支撑性测试代?脚手?scaffolding)
构徏(,construction)
基础c?foundation classes)

摘录
P70Q用隐d是g说不清楚的事情。你需要适当地引甛_的含义,才能从其中蕴含的深刻启发中受益。但若你q分地或者在错误的方向上引申了它的含义,它也会误g。正如h们会误用M强大的工具一P你也可能误用隐喻Q但它的强大的功效,q是会成Z智慧工具׃的一个宝贵部?br />

两条食物?/strong>
* 健康的生态环境中Qv鸥吃新鲜的鲑|鲑鱼吃新鲜的青鱼Q青鱼吃新鲜的水蝽。这是一条健L食物链?br /> * 软g开发中Q架构师吃掉需求,设计师吃掉架构,E序员,软g食物铄最后一环,消化掉设计?br /> 我们知道毒素是往上递增?如果在Y件开发中,从一开始就被污染了,那么每的污染程度将递增,而程序员在处在食物链的最高层,也是毒素累积的最高层,必L下所有犯下的错误

需求的 checklist
我们是否一定要做需求checklist?书中作者告诉我们ƈ不一定要写需求分析树,但需求分析必d大脑?口头交流上完?落下文字固然是好?但ƈ不是重点,关键在于做不?一份checklist想事一?心智健全"的检?看看你的地基是否坚固
详细的checklist包括是否详细定义了系l的全部输入Q包括来源、精度、取D围、出现频率。是否详l定义了pȝ全部输出Q包括目的,_ֺQ取D围、出现频率,格式Q是否定义了机器内存和剩余磁盘空间的最|是否详细定义了系l的可维护性,包括适应特定功能的变更、操作环境的变更、与其他软g的接口的变更能力Q?#8230;..


构徏高质量的子程?/strong>
书中作者用大篇q去介绍如何构徏高质量的子程?在此?作者用一个有问题的子E序|列Z所指出的所有引发低质量子程序问?我把以下的一个子E序认ؓ是作者最好的ȝ

Procedure HandleStuff ( Var InputRec:CORP_DATA,CrntQtr:integer,
EmpRec
:Emp_DATA, Var EstimRevenue:Real, YTDRevenue:Real, 
ScreenX
:integer,ScreenY:integer,Var NewColor:Color_TYPE,
Var PrevColor
:COLOR_TYPE,Var Status:STATUS_TYPE,
ExpenseType
:integer);
begin
for i := 1 to 100 do begin
InputRec
.revenue[1]:= 0;  
InputRec
.expense[i]:=CorpExpensse[CrntQtr,i] 
end; 
UpdateCorpDatabase(EmpRec); 
EstimRevenue
:=YTDRevenue * 4.0 /real(CrntQtr)
NewColor
:=PrevColor;
status
:=Success; 
if ExpenseTypeQ?/span>1 then begin
for i:= 1 to 12 do
Profit[i]
:= Revenue[i]-Expense.Type[i]
end
else If ExpneseType= 2 then begin
Peofit[i]
:=Revenue[i] - Expense.Type2[i]
end
else if ExpenseType= 3 then
begin
Profit[i]
:=Revenue[i] - Expense.Type3[i]
end
end



下面的问题囊括了作者在此章说明的问?br />
1.E序的名字让人困惑。HandleStuff()能告诉我们程序是q什么的吗?
2.E序没有被说?br /> 3.子程序的布局不好。代码的物理l织形式几乎没有l出光辑l织形式的Q何信息?br /> 4.布局的用过于随心所ԌE序每一部分的布局都是不一L。关于这一炏V只要比较一?nbsp;ExpenseType
=2 ?nbsp;ExpenseType=3 两个地方的风格就清楚?br /> 5.子程序的输入变量?nbsp;InputRec 被改变过。如果它作ؓ输入变量Q那它的值就不该变化。如果要变化它的|׃该称之ؓ输入变量 InputRec?br /> 6.子程序进行了全局变量的读写操作。它?nbsp;CorpExpense中读入变量ƈ写给 Profit。它应该与存取子E序通信Q而不应直接读写全局变量?br /> 7.q个子程序的功用不是单一的。它初始化了某些变量。对一个数据库q行写操作,又进行了某些计算工作Q而它们又看不ZQ何联pR一个子E序的功用应该是单一Q明了的?br /> 8.子程序中没有采取预防非法数据的措施。如?nbsp;CrntQtr 的gؓ“0” Q那么,表达式YTDRevenue*4.0Qreal(CrntQtr)׃出现被零除的错误?br /> 9.E序中用了几个常数Q?/span>1004.0122 ?nbsp;3。关?#8220;秘”(magic)数的问题?nbsp;11.1?#8220;常数”
10.在程序中仅用了域的 CORP_DATA 型参数的两个域。如果仅仅用两个域Q那p仅仅传入特定的域而不是整个结构化变量?br /> 11.子程序中的一些参数没有用过。ScreenX?nbsp;ScreenY在程序中没有涉及?br /> 12.E序中的一个参数被错误标定了。PrevColor被标定ؓ变量型参敎ͼ然而在E序中又没有对其赋倹{?br /> 13.E序中的参数太多。程序中参数个数的合理上限应该是七个左右。而这个程序中则多?1个。程序中的参数多得怕hQ恐怕没谁会仔细查它们,甚至q数一下都不愿意?


高扇??低扇?/strong>
摘录
高内聚,低耦合很容易被重视。但是高扇入低扇出有时候会被忽略。这里是_我们应该量的大量的使用某个低层ơ上l定的类(high fan-in) 而每个类都应该尽量少使用其他的类(控制?个之??br />

书中分别很详l的写了架构,设计,~程{等斚w的内?q不分巨l的讨论了函?变量,语句{编E要?q些内容基本上都是围l着软g构徏的核心就是管理复杂度来展开?产生q个Ҏ在于h脑智力同软g目复杂度的矛盾.
而解册矛盾从作者书中ȝ可能有以下几?
1.分割
pȝ分割,设计分割,代码分割....
2.清晰理解
抽象,装
3.清晰表达

----------------------------------------

by 陈于?
QQ:34174409
Mail: dongbule@163.com



]]>
开发h员与软g试http://www.tkk7.com/dongbule/archive/2010/12/03/339721.html陈于?/dc:creator>陈于?/author>Fri, 03 Dec 2010 08:00:00 GMThttp://www.tkk7.com/dongbule/archive/2010/12/03/339721.htmlhttp://www.tkk7.com/dongbule/comments/339721.htmlhttp://www.tkk7.com/dongbule/archive/2010/12/03/339721.html#Feedback3http://www.tkk7.com/dongbule/comments/commentRss/339721.htmlhttp://www.tkk7.com/dongbule/services/trackbacks/339721.html
E序员和试人员的心理差?/strong>
E序员和试人员的心理差别可以简单的归纳Z下几U?br />
成功 / 不成?/strong>
什么才是一ơ成功的试,大多数的开发h员对自己的程序测试完没发现错?׃?q是一个成功的试",如果发现某些新的错误则称"q是不成功的试";而测试h员刚好相?当然q也是因为双方的职责不同而引L

l护 / 破坏,施虐
开发h员对试往往是一U维护性的试,目标在于证明自己开发的E序没有错误,可能跟我们开发h员经常做性工?更們֐创造事?而不是将事物破坏有关;而测试h员在试更多是一U破坏的q程,甚至是一U施?摆出一U把鸡蛋打碎搅黄来挑骨头的姿?br />
做了应该做的 / 做了不该做的
开发h员在做测试更多們֐于对实现的功能进行检?当测试证明了该完成的功能全部通过时就认ؓ试完毕?但程序即使能够完成预定的功能,也可能隐藏了错误,如做了应该做的东?同时也做了不应该做的东西

建立一U信?/ 必须?/strong>
试q个东西对于开发h员来?更多的是建立一U信心的保证,例如我们可能多的单元测?很多时候就是让我们信E序的正?q让我们建立信心,而对于测试h员来?试是他们的职责所?只有可能多的把pȝ挖出错误来才证明他们的存在h?br />
试的态度
试是一Ҏ术性的工作,但同时也涉及C心里学的一些重要的因素.
作ؓE序员的我们也经怼Ҏ们的E序q行相关的测?但你x我们Z么要Ҏ们的pȝ做测?原因大概有以下的几种

1.试是Z证明我们的系l是不存在错误的.
2.试的目的是惌明系l能够正完成预定的功能.
3.试是保证一个系l强壮性的信心q程.
4.试是上U规定要做的.

站在试人员的角度来?除了最后一?其他的都是本末倒置(难怪他们会抱怨我们做的测试很?

"试是Z证明我们的系l是不存在错误的",试想一?如果我们的目标是证明E序中不存在错误,那么我们的潜意识׃們֐于这个目?我们会們֐选择可能较少D出现E序失效的测试数?如果我们的测试目标证明程序中存在错误,我们设计的测试数据就可能更多的发现问?于前一U方法相?后一U方法会更多地增加程序的价?
每当试一个程?都是想ؓE序增加多一些的价?通过试发现pȝ的更多错误来增加E序的可靠性质?提高了程序的可靠?是指出ƈ最l修改程序的错误.?试是Z证明我们的系l是不存在错误的"比较,更适合的定义是
试时ؓ了发现错误而执行的q程

"试的目的是惌明系l能够正完成预定的功能",q个定义又会带来另一个问?E序即能够完成预定的功?也依然可能隐藏错?也就是说,当程序没有实现预期的功能,错误时能够清晰显C出?但程序做了不应该做的?q同样也是一个错?如我们程序实C一个除法计器,即我们通过各种数据正确的完成了计算d,但在完成了不应执行的d(除数?),E序依然是错误的,如果我们Y件测试作为发现错误的q程,而不是只是证?pȝ能够正确完成预定的功?,我们发现q类的错误可能性会打很?所以更好的定义?br /> 试是建立E序即能完成预定功?也发现存在完成非预定功能

ps:当然?试更多是跟软g成本斚w相关,q里׃l想?附上讲的ppt<实用的黑盒测试方?/a>>

----------------------------------------




]]>
[整理]工程中jar功能对照?/title><link>http://www.tkk7.com/dongbule/archive/2010/11/03/336905.html</link><dc:creator>陈于?/dc:creator><author>陈于?/author><pubDate>Wed, 03 Nov 2010 06:59:00 GMT</pubDate><guid>http://www.tkk7.com/dongbule/archive/2010/11/03/336905.html</guid><wfw:comment>http://www.tkk7.com/dongbule/comments/336905.html</wfw:comment><comments>http://www.tkk7.com/dongbule/archive/2010/11/03/336905.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.tkk7.com/dongbule/comments/commentRss/336905.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/dongbule/services/trackbacks/336905.html</trackback:ping><description><![CDATA[<br /> 把我上次的工E所用到的jar包做了一个整?也加了一些简单的描述,下面图是上次工程用到的所有jar?br /> <br /> <img alt="" src="http://www.tkk7.com/images/blogjava_net/dongbule/jar/1.png" width="549" height="600" /><br /> <br /> <table width="964" border="0" cellpadding="2" cellspacing="2" height="734"> <tbody> <tr> <td><strong>JAR包与描述对照?/strong></td> <td><strong>注:jar包尾后的版本号不代表当前最高版?/strong></td> </tr> <tr> <td>activation-1.1.jar</td> <td>Sun的JavaBeans Activation FrameworkQJAFQ?JavaMail要运行必M赖于它的支持</td> </tr> <tr> <td>asm-3.0.jar<br /> asm-commons-2.2.3.jar<br /> asm-util-2.2.3.jar<br /> </td> <td>asm是一个轻量字节码处理和分析框架</td> </tr> <tr> <td>alveole-struts2.jar<br /> alveole-tools.jar<br /> </td> <td> </td> </tr> <tr> <td valign="top">aspectjtools-1.5.3.jar<br /> </td> <td valign="top">Aspect提供的注释类库和相应的解析类?br /> </td> </tr> <tr> <td valign="top">atomikos-util.jar<br /> </td> <td valign="top">数据库提供分布式事务支持<br /> </td> </tr> <tr> <td valign="top">c3p0-0.8.5.2.jar<br /> </td> <td valign="top">C3PO是一个数据库q接?br /> </td> </tr> <tr> <td valign="top">cglib-nodep-2.2.jar<br /> </td> <td valign="top">CGLIB是一个强大的高质量高性能的代码生成库,在运行时可以用它来扩展Javac?br /> </td> </tr> <tr> <td valign="top">commons-attributes-api.jar<br /> </td> <td valign="top">Apache Commons包中的一?包含了一些属性的api<br /> </td> </tr> <tr> <td valign="top">commons-beanutils-1.6.jar<br /> </td> <td valign="top">Apache Commons包中的一个,包含了一些Bean工具cȝ<br /> </td> </tr> <tr> <td valign="top">commons-chain-1.1.jar<br /> </td> <td valign="top"><br /> </td> </tr> <tr> <td valign="top">commons-codec-1.3.jar<br /> </td> <td valign="top"><br /> </td> </tr> <tr> <td valign="top">commons-collections-3.2.jar<br /> </td> <td valign="top">Apache Commons包中的一?包含了一些Apache开发的集合c,功能比java.util.*强大<br /> </td> </tr> <tr> <td valign="top">commons-configuration.jar<br /> </td> <td valign="top">Apache Commons包中的一?用于协助d配置和首选项文g<br /> </td> </tr> <tr> <td valign="top">commons-digester-1.8.jar<br /> </td> <td valign="top">Apache Commons包中的一?通过它可以很方便的解析xml文g生成java对象<br /> </td> </tr> <tr> <td valign="top">commons-fileupload.jar<br /> </td> <td valign="top">Apache Commons包中的一?是一个通过Http接收上传的文件ƈ处理l果文g的库<br /> </td> </tr> <tr> <td valign="top">commons-lang-2.1.jar<br /> </td> <td valign="top">Apache Commons包中的一?包含了一些数据类型工LQ是java.lang.*的扩?br /> </td> </tr> <tr> <td valign="top">commons-httpclient-3.0.jar<br /> </td> <td valign="top">Apache Commons包中的一?提供一个框架啊处理http客户端的扩展<br /> </td> </tr> <tr> <td valign="top">commons-io.jar    <br /> </td> <td valign="top">Apache Commons包中的一?java.io.*的扩?输入输出,支持文g上传<br /> </td> </tr> <tr> <td valign="top">commons-logging-1.1.1.jar<br /> </td> <td valign="top">Apache Commons包中的一?包含日志功能<br /> </td> </tr> <tr> <td valign="top">commons-logging-api-1.1.jar<br /> </td> <td valign="top">Apache Commons包中的一?Commons Logging应用接口,一U超薄适配器允许其他可配置桥连?br /> </td> </tr> <tr> <td valign="top">commons-validator-1.3.0.jar<br /> </td> <td valign="top">Apache Commons包中的一?struts使用它进行表单验?br /> </td> </tr> <tr> <td valign="top">dom4j-1.6.1.jar    <br /> </td> <td valign="top">dom4j XML 解析?br /> </td> </tr> <tr> <td valign="top">ezmorph-1.0.4.jar<br /> </td> <td valign="top">json和java转化的辅助工?br /> </td> </tr> <tr> <td valign="top">freemarker-2.3.8.jar<br /> </td> <td valign="top">freemarker表现层模板工?br /> </td> </tr> <tr> <td valign="top">hessian-3.1.3.jar<br /> </td> <td valign="top">一个轻量的remoting onhttp工具Q用简单的Ҏ提供了RMI的功?br /> </td> </tr> <tr> <td valign="top">htmlparser.jar<br /> </td> <td valign="top">强大的html解析?br /> </td> </tr> <tr> <td valign="top">httpsqs4j.jar<br /> </td> <td valign="top">一Ƒ֟?HTTP GET/POST 协议的轻量开源简单消息队列服?br /> </td> </tr> <tr> <td valign="top">ibatis-2.3.3.720.jar<br /> </td> <td valign="top">iBATIS提供的持久层框架包括SQL Maps和Data Access ObjectsQDAOQ?br /> </td> </tr> <tr> <td valign="top">jamon-2.7.jar<br /> </td> <td valign="top">一个小巧的Q免费的Q高性能的,U程安全的性能监测工具<br /> </td> </tr> <tr> <td valign="top">java_memcached-release.jar<br /> </td> <td valign="top">memcachedq接的java客户?br /> </td> </tr> <tr> <td valign="top">jfreechart-1.0.1.jar<br /> </td> <td valign="top">使用java生成图表的工?br /> </td> </tr> <tr> <td valign="top">jcommon-1.0.8.jar<br /> </td> <td valign="top">使用java生成图表的工?br /> </td> </tr> <tr> <td valign="top">json-lib-2.2-jdk15.jar<br /> </td> <td valign="top">json和java转化的辅助工?br /> </td> </tr> <tr> <td valign="top">jta.jar<br /> </td> <td valign="top">Java事务API,为J2EEq_提供了分布式事务服务<br /> </td> </tr> <tr> <td valign="top">junit-3.8.1.jar<br /> </td> <td valign="top">是一个开放源代码的Java试框架Q用于编写和q行可重复的试。他是用于单元测试框架体pxUnit的一个实?br /> </td> </tr> <tr> <td valign="top">jxl.jar<br /> </td> <td valign="top">通过java操作excel表格的工L?br /> </td> </tr> <tr> <td valign="top">log4j-1.2.9.jar<br /> </td> <td valign="top">通过使用Log4jQ我们可以控制日志信息输送的目的地是控制台、文件、GUIlg、甚x套接口服务器<br /> </td> </tr> <tr> <td valign="top">lucene-core-2.3.2.jar<br /> </td> <td valign="top">是一个全文检索引擎的架构Q提供了完整的查询引擎和索引引擎<br /> </td> </tr> <tr> <td valign="top">mongo-2.2.jar<br /> </td> <td valign="top">javaq接mongodb客户端接?br /> </td> </tr> <tr> <td valign="top">morphia.jar</td> <td valign="top">是一个轻量的类型安全的JavacdQ用来将在MongoDB和Java对象之间q行映射</td> </tr> <tr> <td valign="top">mysql-connector-java.jar<br /> </td> <td valign="top">mysqlq接驱动<br /> </td> </tr> <tr> <td valign="top">ognl-2.6.11.jar<br /> </td> <td valign="top">OGNL表达?支持EL<br /> </td> </tr> <tr> <td valign="top">oscache-2.3.2.jar<br /> </td> <td valign="top">Java对象的缓存工?比ehcache的优势在于页面缓?br /> </td> </tr> <tr> <td valign="top">poi-3.0.1.jar<br /> </td> <td valign="top">apache工具,用于操作pdf和excel的工L<br /> </td> </tr> <tr> <td valign="top">quartz-1.6.0.jar<br /> </td> <td valign="top">自动d处理功能cd<br /> </td> </tr> <tr> <td valign="top">proxool-0.9.1.jar<br /> </td> <td valign="top">Proxool JDBC q接?工具<br /> </td> </tr> <tr> <td valign="top">servlet.jar<br /> </td> <td valign="top"><br /> </td> </tr> <tr> <td valign="top">spring-2.0.2.jar</td> <td valign="top"><br /> </td> </tr> <tr> <td valign="top">spring-2.0.2.jar<br /> </td> <td valign="top"><br /> </td> </tr> <tr> <td valign="top">velocity-1.6.3-dep.jar<br /> velocity-tools-1.4.jar    <br /> </td> <td valign="top">velocityZjava的模板引?允许用简单的模板语言来引用java定义的对?br /> </td> </tr> <tr> <td valign="top">xwork-core-2.1.6.jar<br /> </td> <td valign="top">web work的核心库<br /> </td> </tr> </tbody> </table> <br /> <hr width="100%" size="2" /> <br /> 下蝲<<a >http://download.csdn.net/source/2806071</a>><br /> <br /> ?blogjava上传不了,我传到csdn<br /> <br /> ----------------------------------------<br /> <br /> by 陈于?<br /> QQ:34174409<br /> Mail: dongbule@163.com<br /> <br /> <br /> <img src ="http://www.tkk7.com/dongbule/aggbug/336905.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/dongbule/" target="_blank">陈于?/a> 2010-11-03 14:59 <a href="http://www.tkk7.com/dongbule/archive/2010/11/03/336905.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>览器的~存协商http://www.tkk7.com/dongbule/archive/2010/08/25/329840.html陈于?/dc:creator>陈于?/author>Tue, 24 Aug 2010 16:03:00 GMThttp://www.tkk7.com/dongbule/archive/2010/08/25/329840.htmlhttp://www.tkk7.com/dongbule/comments/329840.htmlhttp://www.tkk7.com/dongbule/archive/2010/08/25/329840.html#Feedback0http://www.tkk7.com/dongbule/comments/commentRss/329840.htmlhttp://www.tkk7.com/dongbule/services/trackbacks/329840.html
~存协商
现在我们需要将用户的浏览器也纳入我们构建网站各个缓存层ơ中的其中一个重要层ơ,|站信息和内容在由web服务器生成,而将q些信息和内容作ZD二q制的文件作为本地缓存文件存攑֜用户的浏览器Q是两个独立个体共同完成的Q务,所以两者之间需要一U沟通的机制Q也是HTTP的缓存协?br />
Last-Modified和If-Modified-Since协商
Last-Modified和If-Modified-Since分别位于响应头信息和h头信息中Q都是记录请求的面最后的修改旉
在第一ơ访问web服务器会q回200状态,q在览器的响应头Last-Modified上写上此面最后修改的旉?br /> 使用firebugq行查看




在再ơ访问时Q浏览器会把W一ơ返回Last-Modified的时间戳记录到If-Modified-SinceQƈ作ؓh头信息发送到服务区,web服务器会通过If-Modified-Since上的旉x判断用户的页面是否是最新的Q如果不是最新的Q则q回新的面q修改响应头Last-Modified旉戳给用户Q如果判断是最新的Q则q回304状态ƈ告诉览器本地的cache面是最新的Q浏览器可以直接加蝲本地面Q这样可以减网l上传输的数据,q且也减服务器的负担?br />



q里需要注意的是,HTTP协议中规定用的是GMT旉(格林威治)Q而我们国家用的是GMT+8的时_所以我们从firebug中看到的旉是比我们早了8个小Ӟ不过q没关系Q它q不影响到缓存的Ҏ工作

Etag协商
如果我们的一个文件存攑֜多台web服务器上Q用Lh在这些服务器上之间轮询,实现负蝲均衡Q那些这个文件在各台web服务器的最后修Ҏ间很可能是不一Pq样用户每次h到的web服务器都可能是不同,Last-Modified和If-Modified-Since则无法对应,D每次都需要重新获取内容,q时候采用直接标记内容的Etag法Q就可以避免上述的问?br /> Etag是由Web服务器生成的Q如ApacheZ个静态文件新增响应头?br /> Etag    "e3af4060-5-472bedf076880"
览器获得这个Etag后,便会在下ơ请求该面Ӟ在HTTP的请求头附上If-None-Match    "e3af4060-5-472bedf076880"Q与web服务器上的Etag值相比较Q如果是相同的话Q便q回304状态,不同则重新返回新面信息



当然啦,q里要指出浏览器~存只针对HTML和HTMq行而动态文件则无法~存Q浏览器q不在乎你的文g是否动态还是静态,览器只认准和web服务器通讯的HTTP协商Q所以只要动态页面HTTP头信息包含的~存协商信息Q动态内容也是可以一栯览器进行缓存的Q和静态页面无什么两P只是你确定你需要这样做Q让动态页面被~存Q?br /> 以下是对一个jspq行写头信息

response.addHeader("Last-Modified",DateUtl.format(new java.util.Date())+" GMT");
response.addHeader(
"ETag","e3af4060-5-472bedf076880");


同样Q这样两个设|会写入览器的响应_q个动态文件跟静态文件一样会被浏览器~存

Expires
Expires标记告诉览器该面何时q期Qƈ且在此过期前不需要再讉Kweb服务器,直接使用本地的缓存文件即可,q样h响应头都不需要,实节省了带宽和服务器的开销Q但是就页面在web服务器上更新后在Expiresq期前也不会出现在用户面前,I竟是否应该在于我们的实际应用和取舍
下面是Apache中提供的mod_expires模块
<IfModule mod_expires.c>
ExpiresActive On
ExpiresDefault A600
ExpiresByType image/x-icon A2592000
ExpiresByType application/x-javascript A604800
ExpiresByType text/css A604800
ExpiresByType image/gif A2592000
ExpiresByType image/png A2592000
ExpiresByType image/jpeg A2592000
ExpiresByType text/plain A86400
ExpiresByType application/x-shockwave-flash A2592000
ExpiresByType video/x-flv A2592000
ExpiresByType application/pdf A2592000
ExpiresByType text/html A600
</IfModule>

或?br />
<IfModule mod_expires.c>
ExpiresActive On
ExpiresDefault "access plus 12 hours"
ExpiresByType text/html "access plus 3 days"
ExpiresByType text/plain "access plus 3 days"
ExpiresByType text/css  "access plus 7 days"
ExpiresByType image/gif "access plus 30 days"
ExpiresByType image/png "access plus 30 days"
ExpiresByType image/jpeg "access plus 30 days"
ExpiresByType image/x-icon "access plus 30 days"
ExpiresByType video/x-flv  "access plus 30 days"
ExpiresByType application/x-shockwave-flash "access plus 30 days"
</IfModule>


我们在jsp文g也可以指定expires的过期时?br />
response.addHeader("Expires",DateUtl.format(new java.util.Date())+" GMT");



当然啦,你再h也不会返?04状态,因ؓ览器已l不用想web服务器发?br />
----------------------------------------

by 陈于?
Mail: chenyz@corp.netease.com


参考文?br /> 郭欣 《构建高新能web站点?br /> 中文?《HTTP协议(RFC2616)?br />

]]>
վ֩ģ壺 ҹƬ߹ۿ| þþþþavѿƬ | ɫɫWWW| VVþþ| ƷžƷƵ| ޳avƬۿ| պٸѲ| ޾ƷһۺϾƷ99| պѸһëƬ| ޹˾þۺҰ| ˳վ| ޾ƷAAƬѽ | ˿Ƶ| ޹ƷɫƬۿ| aɫëƬƵ| Ʒ޳AV߹ۿ| רAVվ | ޾ƷĻ| AëƬƵ߲| ɫۺͼ| ŮƵaƵȫ| ޾ƷŮͬĻ| ҹƷþ| պAVר| һƷƵ| ˬָ߳BBƵѿ| ƷϵƵ| AVĻɫ| AƬƵWWW | avۺɫ| ɫƬѹۿ | ƵĻ| ҹҹƵۿ| j8ֳִӲˬƵ | Ʒ߲ҳ| ѿbbb| ѻɫӰ߹ۿ| ŷav߹ۿ| ޹a777| ˽Ƶ75| ɫƵ|