??xml version="1.0" encoding="utf-8" standalone="yes"?>亚洲一区高清,国产高清精品一区,精品午夜一区二区三区http://www.aygfsteel.com/jnbzwm/archive/2011/04/09/347958.html??/dc:creator>??/author>Sat, 09 Apr 2011 09:37:00 GMThttp://www.aygfsteel.com/jnbzwm/archive/2011/04/09/347958.htmlhttp://www.aygfsteel.com/jnbzwm/comments/347958.htmlhttp://www.aygfsteel.com/jnbzwm/archive/2011/04/09/347958.html#Feedback1http://www.aygfsteel.com/jnbzwm/comments/commentRss/347958.htmlhttp://www.aygfsteel.com/jnbzwm/services/trackbacks/347958.html本文为原创,Ƣ迎转蝲Q{载请注明出处BlogJava?/span>
快速排序的法思想Q?br /> 快速排序采用了分治的策略,原问题分解q个规模更小但结构与原问题相似的子问题。用递归Ҏ解决子问题,然后这些子问题的解l合为原问题的解?br />
快速排序的E序的一般过E可单描qCؓQ?br /> 1.用统一的方法取?pivot(??br /> 2.Ҏpivot 对已有数l进行排?br />     1) array[pivot]存储在tmp变量中,作ؓ比较基准?br />     以low、high分别从前向后、从后向前遍历数l?br />     2) 从后向前遍历Q找到第一个小于tmp的数Q将其移动到low的位|?br />     3) 从前向后遍历Q找到第一个大于tmp的数Q将其移动到high的位|?br />     4) 循环2?步,直到两指针重?即退出@环的条g?low >= high)Q将tmpUd到low(此时low与high重合)的位|,q将lowq回成ؓ新的pivot?br />     5) Ҏ4步返回的pivotQ对已有数组q行划分Q?~pivot-1 ?pivot+1 ?array.lenghtQ递归1?步。直到调用退出?br />
怿对于以上理论大家一定是耳熟能详了,但理解v来还是比较抽象,下面我就用Exceld单的描述一?快速排?的过E?br />
假设我们要写一个程序对已有数组q行排序Q简单v见,讑֮待排序数lؓ int[] array = { 4, 2, 1, 7, 5, 3, 8, 6 }。对其用快速排序算法进行排序,q程描述如下Q?br /> 1.Ҏ已有待排序数l,取得pivotQ我在这里取得pivot的策略就??数组的第一个数Q这里即?4?br />    tmp = 4Q?br />
待排序数l:黄色底色表示pivot?br />


2.从后向前UdhighQ找到第一个小于tmp的数Q则该数移动到low的位|?br />


3.从前向后UdlowQ找到第一个大于tmpQ?Q的敎ͼ其Ud到high的位|?br />

4.然后再向前移动highQ试图找到第一个小于tmp(4)的数Q但没有扑ֈQ此时low与high重叠Q将tmp的值放入low的位|,q将low作ؓpivotq回?br />



  Ҏ新的pivotq行递归调用Q将原待排序数组 分解Z块,index区间分别??Q??Q即以下两个子数l?br />   (q未新徏数组Q只是只xq个区间的数据,对其q行排序Q也是问题分解ؓ两个的子问题,但问题很cM?
 

q两个数l的排序q程q里׃MQ一Lq程?br />
下面来看看实现的代码Q与刚刚的过E描q是W合的:

package com.bz.sort.algorithm;

public class QuickSort {
    
/**
     * 对外调用的方法入口?br />      * 
@param array 待排序数l?br />      */

    
public void sort(int[] array) {
        
if (array == null || array.length < 0{
            
throw new RuntimeException("待排序数l中无数据?/span>");
        }


        
// 排序
        sort(array, 0, array.length - 1);
    }


    
/**
     * 快速排序?br />      * 
@param arr 待排序数l?br />      * @param left x的区?br />      * @param right x的区?br />      */

    
private void sort(int[] arr, int left, int right) {
        
if (left >= right) {
            
return;
        }

        
// 取得pivot位置Q这里的{略是取得最的indexQ即q回left
        int pivot = findPivot(arr, left, right);
        
// 排序q新计出pivot
        pivot = partion(arr, left, right, pivot);

        
// 以pivotZ心将原数l分解成两块Q递归排序
        sort(arr, left, pivot - 1);
        sort(arr, pivot 
+ 1, right);
    }


    
/**
     * 排序q返回新的pivot
     * 
@param arr 待排序数l?br />      * @param left 区间
     * 
@param right 区间
     * 
@param pivot ?br />      * @return 
     
*/

    
private int partion(int[] arr, int left, int right, int pivot) {
        
int tmp = arr[pivot];
        
int low = left;
        
int high = right;
        
while (low < high) {
            
// 从后向前遍历数组Q找到第一个小于arr[pivot]的数
            while (low < high && tmp < arr[high]) {
                high
--;
            }

            arr[low] 
= arr[high];

            
// 从前向后遍历数组Q找到第一个大于arr[pivot]的数
            while (low < high && tmp >= arr[low]) {
                low
++;
            }

            arr[high] 
= arr[low];
        }


        
// 此时low与high重合Q将tmp的值移动到low的位|?/span>
        arr[low] = tmp;
        
// low当作新的pivotq回
        return low;
    }


    
/**
     * 取得排序的u
     * 
@param array
     * 
@return
     
*/

    
protected int findPivot(int[] array, int left, int right) {
        
if (array == null || array.length < 0{
            
throw new RuntimeException("待排序数l中无数据?/span>");
        }

        
// 选择W一个元素ؓ?/span>
        return left;
    }

}

 


试代码如下Q?br />

package com.bz.sort.algorithm;

import org.junit.Test;

import junit.framework.Assert;

public class QuickSortTest {
    @Test
    
public void testSort() {
        
int[] array = 42175386 };
        QuickSort qs 
= new QuickSort();
        qs.sort(array);
        
for (int i = 0; i < array.length - 1; i++{
            Assert.assertTrue(array[i] 
<= array[i + 1]);
        }

    }

}


注:此代码只?演示 排序q程?

]]>
java代码实现利用 classloader 动态加?jar包、文件夹到classpath?/title><link>http://www.aygfsteel.com/jnbzwm/archive/2011/04/01/347491.html</link><dc:creator>??/dc:creator><author>??/author><pubDate>Fri, 01 Apr 2011 12:39:00 GMT</pubDate><guid>http://www.aygfsteel.com/jnbzwm/archive/2011/04/01/347491.html</guid><wfw:comment>http://www.aygfsteel.com/jnbzwm/comments/347491.html</wfw:comment><comments>http://www.aygfsteel.com/jnbzwm/archive/2011/04/01/347491.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.aygfsteel.com/jnbzwm/comments/commentRss/347491.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/jnbzwm/services/trackbacks/347491.html</trackback:ping><description><![CDATA[     摘要: 在项目中实现了一个工?独立q行的Java工程Q打成jar包后 通过 java -jar **.jar 执行的?Q该工具通过配置能够实现一些业务功能, q且该工h供了接口与抽象类Q供其他人扩展它的功能? q就涉及C个问题:别h在扩展它的时候,需要引入一些jar或者配|文Ӟ本来工具依赖的jar和配|文仉记录在manifest文g中了Q?不可能别人加了jar包和配置文gp修改ma...  <a href='http://www.aygfsteel.com/jnbzwm/archive/2011/04/01/347491.html'>阅读全文</a><img src ="http://www.aygfsteel.com/jnbzwm/aggbug/347491.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/jnbzwm/" target="_blank">??/a> 2011-04-01 20:39 <a href="http://www.aygfsteel.com/jnbzwm/archive/2011/04/01/347491.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Maven常用命o 备忘http://www.aygfsteel.com/jnbzwm/archive/2011/03/30/347270.html??/dc:creator>??/author>Wed, 30 Mar 2011 05:07:00 GMThttp://www.aygfsteel.com/jnbzwm/archive/2011/03/30/347270.htmlhttp://www.aygfsteel.com/jnbzwm/comments/347270.htmlhttp://www.aygfsteel.com/jnbzwm/archive/2011/03/30/347270.html#Feedback0http://www.aygfsteel.com/jnbzwm/comments/commentRss/347270.htmlhttp://www.aygfsteel.com/jnbzwm/services/trackbacks/347270.html使maven2在下载依赖包的同时下载其源代码包的方法:

1. 使用maven命oQmvn dependency:sources 下蝲依赖包的源代码?/p>

2. 使用参数Q?-DdownloadSources=true 下蝲源代码jar?-DdownloadJavadocs=true 下蝲javadoc包?/p>


maven2  跌试用例

-Dmaven.test.skip=true


例如?install、package、deploy阶段跌用例

mvn install -Dmaven.test.skip=true

mvn package -Dmaven.test.skip=true

mvn deploy -Dmaven.test.skip=true



]]>
无法开?IE 开发者工?IE Developer Tools) 处理Ҏhttp://www.aygfsteel.com/jnbzwm/archive/2011/03/17/346454.html??/dc:creator>??/author>Thu, 17 Mar 2011 03:17:00 GMThttp://www.aygfsteel.com/jnbzwm/archive/2011/03/17/346454.htmlhttp://www.aygfsteel.com/jnbzwm/comments/346454.htmlhttp://www.aygfsteel.com/jnbzwm/archive/2011/03/17/346454.html#Feedback0http://www.aygfsteel.com/jnbzwm/comments/commentRss/346454.htmlhttp://www.aygfsteel.com/jnbzwm/services/trackbacks/346454.html1.问题Q?br />    a.IE8(本h修复问题的IE版本) 无法通过点击 “工具”-> “开发者工?#8221; 或?#8220;F12”  来开启开发者工兗?br />    b.通过a中描q的ҎQ开发者工具会启动Q但不会昄出来Q现象是一直处于最化状态?br />
2.解决ҎQ?br />    a.打开注册?regedit命o)
   b.扑ֈ HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\IEDevTools
   c.删除WindowPos
   d.重启IE?br />
以上Ҏ解决了本人的问题Q希望对大家也有帮助?/p>

]]>
freemarker数字格式化引入的问题http://www.aygfsteel.com/jnbzwm/archive/2010/12/29/341910.html??/dc:creator>??/author>Wed, 29 Dec 2010 06:54:00 GMThttp://www.aygfsteel.com/jnbzwm/archive/2010/12/29/341910.htmlhttp://www.aygfsteel.com/jnbzwm/comments/341910.htmlhttp://www.aygfsteel.com/jnbzwm/archive/2010/12/29/341910.html#Feedback6http://www.aygfsteel.com/jnbzwm/comments/commentRss/341910.htmlhttp://www.aygfsteel.com/jnbzwm/services/trackbacks/341910.html问题
freemarker在解析数据格式的时候,默认数字按3位来分割Q例?000被格式化?,000Q这样做看似观Q但在实际操作时候会带来问题。例如我一个页面有一个元素,该元素的值由后台l定且超q?000Q那么当我要使用q个元素的值的时候,便会出现问题?br /> 例如Q我在ftl文g中这样写Q?br />
<input type="hidden" id="testElement" name="testElement" value="${size}" />
假设后台l定的size?000?br />
然后我在js里用这个testElement元素的倹{?br />
var t = $("#testElement");
alert(t);
alert(parseInt(t));
alert(Number(t));


得到的值是Q?br /> 1,000
1
NaN

q下悲剧了,没有一个是我想要的数值类?000Q这让我情何以堪啊?br />
我之前有一个随W,ZStruts2、Freemarker的分늻件实?附工E源? Q便因ؓfreemarker的数字格式化问题Q存在一个bug?br /> 在数据超q?000时候,点击下一,便会报错。原因是?,000传到了后収ͼ当作是总记录数Q而这个值ƈ非数倹{?br />
解决问题
* 在模板中直接?toString()转化数字为字W串Q如Q?{size.toString()}Q?br /> * 在freemarker配置文gfreemarker.properties(在类路径下即??lt;#setting number_format="#">Q?br /> * 在模板中直接?lt;#setting number_format="#">Q?br /> * 通过freemarker.template.Configuration的config.setNumberFormat("#")来设定freemarkerҎ值的格式?

其实后三U方法的思\是一致的Q只是实现方法不同而已。如果应用中已经存在?nbsp;freemarker.properties q|了其他的属性,可以在这里配|,否则推荐使用最后一U方法?br />
最后我是用最后一U方法解决的问题。分늻件上的问题也解决了?/span>



]]>
[转]session详解http://www.aygfsteel.com/jnbzwm/articles/341746.html??/dc:creator>??/author>Tue, 28 Dec 2010 03:26:00 GMThttp://www.aygfsteel.com/jnbzwm/articles/341746.htmlhttp://www.aygfsteel.com/jnbzwm/comments/341746.htmlhttp://www.aygfsteel.com/jnbzwm/articles/341746.html#Feedback0http://www.aygfsteel.com/jnbzwm/comments/commentRss/341746.htmlhttp://www.aygfsteel.com/jnbzwm/services/trackbacks/341746.html目录Q?br /> 一、术语session
二、HTTP协议与状态保?br /> 三、理解cookie机制
四、理解session机制
五、理解javax.servlet.http.HttpSession
六、HttpSession常见问题
七、跨应用E序的session׃n
八、ȝ
参考文?/p>

一、术语session
在我的经验里Qsessionq个词被滥用的程度大概仅ơ于transactionQ更加有的是transaction与session在某些语境下的含义是相同的?/p>

sessionQ中文经常翻译ؓ会话Q其本来的含义是指有始有l的一pd动作/消息Q比如打电话时从拿v电话拨号到挂断电话这中间的一pdq程可以UCZ?session。有时候我们可以看到这L?#8220;在一个浏览器会话期间Q?..”Q这里的会话一词用的就是其本义Q是指从一个浏览器H口打开到关闭这个期?①。最混ؕ的是“用户Q客LQ在一ơ会话期?#8221;q样一句话Q它可能指用L一pd动作Q一般情况下是同某个具体目的相关的一pd动作Q比如从d到选购商品到结账登样一个网上购物的q程Q有时候也被称Z个transactionQ,然而有时候也可能仅仅是指一ơ连接,也有可能是指含义①,其中的差别只能靠上下文来推断②?/p>

然而当session一词与|络协议相关联时Q它又往往隐含?#8220;面向q接”??#8220;保持状?#8221;q样两个含义Q?“面向q接”指的是在通信双方在通信之前要先建立一个通信的渠道,比如打电话,直到Ҏ接了电话通信才能开始,与此相对的是写信Q在你把信发出去的时候你q不能确认对方的地址是否正确Q通信渠道不一定能建立Q但对发信h来说Q通信已经开始了?#8220;保持状?#8221;则是指通信的一方能够把一pd的消息关联v来,使得消息之间可以互相依赖Q比如一个服务员能够认出再次光的老顾客ƈ且记得上ơ这个顾客还Ơ店里一块钱。这一cȝ例子?#8220;一个TCP session”或?“一个POP3 session”③?/p>

而到了web服务器蓬勃发展的时代Qsession在web开发语境下的语义又有了新的扩展Q它的含义是指一cȝ来在客户端与服务器之间保持状态的解决Ҏ④。有时候session也用来指q种解决Ҏ的存储结构,?#8220;把xxx保存在session ?#8221;⑤。由于各U用于web开发的语言在一定程度上都提供了对这U解x案的支持Q所以在某种特定语言的语境下Qsession也被用来指代该语a的解x案,比如l常把Java里提供的javax.servlet.http.HttpSessionUCؓsession⑥?/p>

鉴于q种混ؕ已不可改变,本文中session一词的q用也会Ҏ上下文有不同的含义,请大家注意分辨?br /> 在本文中Q用中?#8220;览器会话期?#8221;来表辑֐义①Q?#8220;session机制”来表辑֐义④Q?#8220;session”表达含义⑤,使用具体?#8220;HttpSession”来表辑֐义⑥

二、HTTP协议与状态保?br /> HTTP 协议本n是无状态的Q这与HTTP协议本来的目的是相符的,客户端只需要简单的向服务器h下蝲某些文gQ无论是客户端还是服务器都没有必要纪录彼此过ȝ行ؓQ每一ơ请求之间都是独立的Q好比一个顾客和一个自动售货机或者一个普通的Q非会员Ӟ大卖Z间的关系一栗?/p>

然而聪明(或者贪心?Q的Z很快发现如果能够提供一些按需生成的动态信息会使web变得更加有用Q就像给有线电视加上Ҏ功能一栗这U需求一斚wqHTML逐步d了表单、脚本、DOM{客L行ؓQ另一斚w在服务器端则出现了CGI规范以响应客L的动态请求,作ؓ传输载体的HTTP协议也添加了文g上蝲?cookieq些Ҏ。其中cookie的作用就是ؓ了解决HTTP协议无状态的~陷所作出的努力。至于后来出现的session机制则是又一U在客户端与服务器之间保持状态的解决Ҏ?/p>

让我们用几个例子来描qC下cookie和session机制之间的区别与联系。笔者曾l常ȝ一家咖啡店有喝5杯咖啡免费赠一杯咖啡的优惠Q然而一ơ性消?杯咖啡的Z微乎其微Q这时就需要某U方式来U录某位֮的消Ҏ量。想象一下其实也无外乎下面的几种ҎQ?br /> 1、该店的店员很厉宻I能记住每位顾客的消费数量Q只要顾客一走进咖啡店,店员q道该怎么对待了。这U做法就是协议本w支持状态?br /> 2、发l顾客一张卡片,上面记录着消费的数量,一般还有个有效期限。每ơ消ҎQ如果顾客出C张卡片,则此ơ消费就会与以前或以后的消费相联pv来。这U做法就是在客户端保持状态?br /> 3、发l顾客一张会员卡Q除了卡号之外什么信息也不纪录,每次消费Ӟ如果֮出示该卡片,则店员在店里的纪录本上找到这个卡号对应的U录d一些消费信息。这U做法就是在服务器端保持状态?/p>

׃HTTP协议是无状态的Q而出于种U考虑也不希望使之成ؓ有状态的Q因此,后面两种Ҏ成为现实的选择。具体来说cookie机制采用的是在客L保持状态的ҎQ而session机制采用的是在服务器端保持状态的Ҏ。同时我们也看到Q由于采用服务器端保持状态的Ҏ在客L也需要保存一个标识,所以session机制可能需要借助于cookie机制来达C存标识的目的Q但实际上它q有其他选择?/p>

三、理解cookie机制
cookie机制的基本原理就如上面的例子一L单,但是q有几个问题需要解冻I“会员?#8221;如何分发Q?#8220;会员?#8221;的内容;以及客户如何使用“会员?#8221;?/p>

正统的cookie分发是通过扩展HTTP协议来实现的Q服务器通过在HTTP的响应头中加上一行特D的指示以提C浏览器按照指示生成相应的cookie。然而纯_的客户端脚本如JavaScript或者VBScript也可以生成cookie?/p>

而cookie 的用是由浏览器按照一定的原则在后台自动发送给服务器的。浏览器查所有存储的cookieQ如果某个cookie所声明的作用范围大于等于将要请求的资源所在的位置Q则把该cookie附在h资源的HTTPh头上发送给服务器。意思是麦当劳的会员卡只能在麦当劳的店里出示Q如果某家分店还发行了自q会员卡,那么q这家店的时候除了要出示麦当劳的会员卡,q要出示q家店的会员卡?/p>

cookie的内容主要包括:名字Q|q期旉Q\径和域?br /> 其中域可以指定某一个域比如.google.comQ相当于d招牌Q比如宝z公司,也可以指定一个域下的具体某台机器比如www.google.com或者froogle.google.comQ可以用飘柔来做比?br /> 路径是跟在域名后面的URL路径Q比?或?foo{等Q可以用某飘柔专柜做比?br /> 路径与域合在一起就构成了cookie的作用范围?br /> 如果不设|过期时_则表C个cookie的生命期为浏览器会话期间Q只要关闭浏览器H口Qcookie消׃。这U生命期为浏览器会话期的 cookie被称Z话cookie。会话cookie一般不存储在硬盘上而是保存在内存里Q当然这U行为ƈ不是规范规定的。如果设|了q期旉Q浏览器׃把cookie保存到硬盘上Q关闭后再次打开览器,q些cookie仍然有效直到过讑֮的过期时间?/p>

存储在硬盘上的cookie 可以在不同的览器进E间׃nQ比如两个IEH口。而对于保存在内存里的cookieQ不同的览器有不同的处理方式。对于IEQ在一个打开的窗口上?Ctrl-NQ或者从文g菜单Q打开的窗口可以与原窗口共享,而用其他方式新开的IEq程则不能共享已l打开的窗口的内存cookieQ对?Mozilla Firefox0.8Q所有的q程和标{N都可以共享同Lcookie。一般来说是用javascript的window.open打开的窗口会与原H口׃n内存cookie。浏览器对于会话cookie的这U只认cookie不认人的处理方式l常l采用session机制的web应用E序开发者造成很大的困扰?/p>

下面是一个goolge讄cookie的响应头的例?br /> HTTP/1.1 302 Found
Location: http://www.google.com/intl/zh-CN/
Set-Cookie: PREF=ID=0565f77e132de138:NW=1:TM=1098082649:LM=1098082649:S=KaeaCFPo49RiA_d8; expires=Sun, 17-Jan-2038 19:14:07 GMT; path=/; domain=.google.com
Content-Type: text/html

q是使用HTTPLookq个HTTP Sniffer软g来俘LHTTP通讯U录的一部分
览器在再次讉Kgoolge的资源时自动向外发送cookie
使用Firefox可以很容易的观察现有的cookie的?br /> 使用HTTPLook配合Firefox可以很容易的理解cookie的工作原理?br /> IE也可以设|在接受cookie前询?br /> q是一个询问接受cookie的对话框?/p>

四、理解session机制
session机制是一U服务器端的机制Q服务器使用一U类g散列表的l构Q也可能是使用散列表)来保存信息?/p>

当程序需要ؓ某个客户端的h创徏一个session的时候,服务器首先检查这个客L的请求里是否已包含了一个session标识 - UCؓ session idQ如果已包含一个session id则说明以前已lؓ此客L创徏qsessionQ服务器按照session id把这?session索出来用(如果索不刎ͼ可能会新Z个)Q如果客Lh不包含session idQ则为此客户端创Z个sessionq且生成一个与此session相关联的session idQsession id的值应该是一个既不会重复Q又不容易被扑ֈ规律以仿造的字符Ԍq个 session id被在本ơ响应中q回l客L保存?/p>

保存q个session id的方式可以采用cookieQ这样在交互q程中浏览器可以自动的按照规则把q个标识发挥l服务器。一般这个cookie的名字都是类gSEEESIONIDQ而。比如weblogic对于web应用E序生成的cookieQJSESSIONID= ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764Q它的名字就?JSESSIONID?/p>

׃cookie可以被h为的止Q必L其他机制以便在cookie被禁止时仍然能够把session id传递回服务器。经常被使用的一U技术叫做URL重写Q就是把session id直接附加在URL路径的后面,附加方式也有两种Q一U是作ؓURL路径的附加信息,表现形式?a href="http://...../xxx;jsessionid">http://...../xxx;jsessionid= ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764
另一U是作ؓ查询字符串附加在URL后面Q表现Ş式ؓhttp://...../xxx?jsessionid=ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764
q两U方式对于用h说是没有区别的,只是服务器在解析的时候处理的方式不同Q采用第一U方式也有利于把session id的信息和正常E序参数区分开来?br /> Z在整个交互过E中始终保持状态,必d每个客户端可能请求的路径后面都包含这个session id?/p>

另一U技术叫做表单隐藏字Dc就是服务器会自动修改表单,d一个隐藏字D,以便在表单提交时能够把session id传递回服务器。比如下面的表单
<form name="testform" action="/xxx">
<input type="text">
</form>
在被传递给客户端之前将被改写成
<form name="testform" action="/xxx">
<input type="hidden" name="jsessionid" value="ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764">
<input type="text">
</form>
q种技术现在已较少应用Q笔者接触过的很古老的iPlanet6(SunONE应用服务器的前n)׃用了q种技术?br /> 实际上这U技术可以简单的用对action应用URL重写来代ѝ?/p>

在谈论session机制的时候,常常听到q样一U误?#8220;只要关闭览器,session消׃”。其实可以想象一下会员卡的例子,除非֮d对店家提出销卡,否则店家l对不会L删除֮的资料。对session来说也是一LQ除非程序通知服务器删除一个sessionQ否则服务器会一直保留,E序一般都是在用户做log off的时候发个指令去删除session。然而浏览器从来不会d在关闭之前通知服务器它要关闭Q因此服务器Ҏ不会有机会知道浏览器已经关闭Q之所以会有这U错觉,是大部分session机制都用会话cookie来保存session idQ而关闭浏览器后这?session id消׃Q再ơ连接服务器时也无法找到原来的session。如果服务器讄的cookie被保存到盘上,或者用某U手D|写浏览器发出的HTTPh_把原来的session id发送给服务器,则再ơ打开览器仍然能够找到原来的session?/p>

恰恰是由于关闭浏览器不会Dsession被删除,q服务器ؓseesion讄了一个失效时_当距dL上一ơ用session的时间超q这个失效时间时Q服务器可以认为客L已经停止了活动,才会把session删除以节省存储空间?/p>

五、理解javax.servlet.http.HttpSession
HttpSession是Javaq_对session机制的实现规范,因ؓ它仅仅是个接口,具体到每个web应用服务器的提供商,除了对规范支持之外,仍然会有一些规范里没有规定的细微差异。这里我们以BEA的Weblogic Server8.1作ؓ例子来演C?/p>

首先QWeblogic Server提供了一pd的参数来控制它的HttpSession的实玎ͼ包括使用cookie的开关选项Q用URL重写的开关选项Qsession持久化的讄Qsession失效旉的设|,以及针对cookie的各U设|,比如讄cookie的名字、\径、域Q?cookie的生存时间等?/p>

一般情况下Qsession都是存储在内存里Q当服务器进E被停止或者重启的时候,内存里的session也会被清I,如果讄了session的持久化Ҏ,服务器就会把session保存到硬盘上Q当服务器进E重新启动或q些信息能够被再次使用Q?Weblogic Server支持的持久性方式包括文件、数据库、客Lcookie保存和复制?/p>

复制严格说来不算持久化保存,因ؓsession实际上还是保存在内存里,不过同样的信息被复制到各个cluster内的服务器进E中Q这样即使某个服务器q程停止工作也仍然可以从其他q程中取得session?/p>

cookie生存旉的设|则会媄响浏览器生成的cookie是否是一个会话cookie。默认是使用会话cookie。有兴趣的可以用它来试验我们在第四节里提到的那个误解?/p>

cookie的\径对于web应用E序来说是一个非帔R要的选项QWeblogic Server对这个选项的默认处理方式得它与其他服务器有明昄区别。后面我们会专题讨论?/p>

关于session的设|参考[5] http://e-docs.bea.com/wls/docs70/webapp/weblogic_xml.html#1036869

六、HttpSession常见问题
Q在本小节中session的含义ؓ⑤和⑥的混合Q?/p>


1、session在何时被创徏
一个常见的误解是以为session在有客户端访问时p创徏Q然而事实是直到某server端程序调?HttpServletRequest.getSession(true)q样的语句时才被创徏Q注意如果JSP没有昄的?<% @page session="false"%> 关闭sessionQ则JSP文g在编译成Servlet时将会自动加上这样一条语?HttpSession session = HttpServletRequest.getSession(true);q也是JSP中隐含的 session对象的来历?/p>

׃session会消耗内存资源,因此Q如果不打算使用sessionQ应该在所有的JSP中关闭它?/p>

2、session何时被删?br /> l合前面的讨论,session在下列情况下被删除a.E序调用HttpSession.invalidate();或b.距离上一ơ收到客L发送的session id旉间隔过了session的超时设|?或c.服务器进E被停止Q非持久sessionQ?/p>

3、如何做到在览器关闭时删除session
严格的讲Q做不到q一炏V可以做一点努力的办法是在所有的客户端页面里使用javascript代码window.oncolose来监视浏览器的关闭动作,然后向服务器发送一个请求来删除session。但是对于浏览器崩溃或者强行杀死进E这些非常规手段仍然无能为力?/p>

4、有个HttpSessionListener是怎么回事
你可以创Llistenerȝ控session的创建和销毁事Ӟ使得在发生这L事g时你可以做一些相应的工作。注意是session的创建和销毁动作触发listenerQ而不是相反。类似的与HttpSession有关的listenerq有 HttpSessionBindingListenerQHttpSessionActivationListener?HttpSessionAttributeListener?/p>

5、存攑֜session中的对象必须是可序列化的?br /> 不是必需的。要求对象可序列化只是ؓ了session能够在集中被复制或者能够持久保存或者在必要时server能够暂时把session交换出内存。在 Weblogic Server的session中放|一个不可序列化的对象在控制C会收C个警告。我所用过的某个iPlanet版本如果 session中有不可序列化的对象Q在session销毁时会有一个ExceptionQ很奇怪?/p>

6、如何才能正的应付客户端禁止cookie的可能?br /> Ҏ有的URL使用URL重写Q包括超链接Qform的actionQ和重定向的URLQ具体做法参见[6]
http://e-docs.bea.com/wls/docs70/webapp/sessions.html#100770

7、开两个览器窗口访问应用程序会使用同一个sessionq是不同的session
参见W三节对cookie的讨论,对session来说是只认id不认人,因此不同的浏览器Q不同的H口打开方式以及不同的cookie存储方式都会对这个问题的{案有媄响?/p>

8、如何防止用h开两个览器窗口操作导致的session混ؕ
q个问题与防止表单多ơ提交是cM的,可以通过讄客户端的令牌来解冟뀂就是在服务器每ơ生成一个不同的idq回l客LQ同时保存在session里,客户端提交表单时必须把这个id也返回服务器Q程序首先比较返回的id与保存在session里的值是否一_如果不一致则说明本次操作已经被提交过了。可以参看《J2EE核心模式》关于表C层模式的部分。需要注意的是对于用javascript window.open打开的窗口,一般不讄q个idQ或者用单独的idQ以防主H口无法操作Q徏议不要再window.open打开的窗口里做修Ҏ作,q样可以不用设|?/p>

9、ؓ什么在Weblogic Server中改变session的值后要重新调用一ơsession.setValue
做这个动作主要是Z在集环境中提示Weblogic Server session中的值发生了改变Q需要向其他服务器进E复制新的session倹{?/p>

10、ؓ什么session不见?br /> 排除session正常失效的因素之外,服务器本w的可能性应该是微乎其微的,虽然W者在iPlanet6SP1加若q补丁的Solaris版本上倒也遇到q;览器插件的可能性次之,W者也遇到q?721插g造成的问题;理论上防火墙或者代理服务器在cookie处理上也有可能会出现问题?br /> 出现q一问题的大部分原因都是E序的错误,最常见的就是在一个应用程序中去访问另外一个应用程序。我们在下一节讨个问题?/p>

七、跨应用E序的session׃n

常常有这L情况Q一个大目被分割成若干项目开发,Z能够互不q扰Q要求每个小目作ؓ一个单独的web应用E序开发,可是C最后突然发现某几个项目之间需要共享一些信息,或者想使用session来实现SSO(single sign on)Q在session中保存login的用户信息,最自然的要求是应用E序间能够访问彼此的session?/p>

然而按照Servlet规范Qsession的作用范围应该仅仅限于当前应用程序下Q不同的应用E序之间是不能够互相讉KҎ的session的。各个应用服务器从实际效果上都遵守了q一规范Q但是实现的l节却可能各有不同,因此解决跨应用程序session׃n的方法也各不相同?/p>

首先来看一下Tomcat是如何实现web应用E序之间session的隔ȝQ从 Tomcat讄的cookie路径来看Q它对不同的应用E序讄的cookie路径是不同的Q这样不同的应用E序所用的session id是不同的Q因此即使在同一个浏览器H口里访问不同的应用E序Q发送给服务器的session id也可以是不同的?/p>

Ҏq个Ҏ,我们可以推测Tomcat中session的内存结构大致如下?/p>

W者以前用q的iPlanet也采用的是同L方式Q估计SunONE与iPlanet之间不会有太大的差别。对于这U方式的服务器,解决的思\很简单,实际实行h也不难。要么让所有的应用E序׃n一个session idQ要么让应用E序能够获得其他应用E序的session id?/p>

iPlanet中有一U很单的Ҏ来实现共享一个session idQ那是把各个应用程序的cookie路径都设?Q实际上应该?NASAppQ对于应用程序来讲它的作用相当于根)?br /> <session-info>
<path>/NASApp</path>
</session-info>

需要注意的是,操作׃n的session应该遵@一些编E约定,比如在session attribute名字的前面加上应用程序的前缀Q?setAttribute("name", "neo")变成setAttribute("app1.name", "neo")Q以防止命名I间冲突Q导致互相覆盖?/p>


在Tomcat中则没有q么方便的选择。在Tomcat版本3上,我们q可以有一些手D|׃nsession。对于版?以上的TomcatQ目前笔者尚未发现简单的办法。只能借助于第三方的力量,比如使用文g、数据库、JMS或者客LcookieQURL参数或者隐藏字D늭手段?/p>

我们再看一下Weblogic Server是如何处理session的?/p>

从截屏画面上可以看到Weblogic ServerҎ有的应用E序讄的cookie的\径都?Q这是不是意味着在Weblogic Server中默认的可以共享session了呢Q然而一个小实验卛_证明即不同的应用程序用的是同一个sessionQ各个应用程序仍然只能访问自己所讄的那些属性。这说明Weblogic Server中的session的内存结构可能如?/p>

对于q样一U结构,?session机制本n上来解决session׃n的问题应该是不可能的了。除了借助于第三方的力量,比如使用文g、数据库、JMS或者客L cookieQURL参数或者隐藏字D늭手段Q还有一U较为方便的做法Q就是把一个应用程序的session攑ֈServletContext中,q样另外一个应用程序就可以从ServletContext中取得前一个应用程序的引用。示例代码如下,

应用E序A
context.setAttribute("appA", session);

应用E序B
contextA = context.getContext("/appA");
HttpSession sessionA = (HttpSession)contextA.getAttribute("appA");

值得注意的是q种用法不可ULQ因为根据ServletContext的JavaDocQ应用服务器可以处于安全的原因对于context.getContext("/appA");q回I|以上做法在Weblogic Server 8.1中通过?/p>

那么Weblogic ServerZ么要把所有的应用E序的cookie路径都设?呢?原来是ؓ了SSOQ凡是共享这个session的应用程序都可以׃n认证的信息。一个简单的实验可以证明这一点,修改首先d的那个应用程序的描述Wweblogic.xmlQ把cookie路径修改?appA 讉K另外一个应用程序会重新要求dQ即使是反过来,先访问cookie路径?的应用程序,再访问修改过路径的这个,虽然不再提示dQ但是登录的用户信息也会丢失。注意做q个实验时认证方式应该用FORMQ因为浏览器和web服务器对basic认证方式有其他的处理方式Q第二次h的认证不是通过 session来实现的。具体请参看[7] secion 14.8 AuthorizationQ你可以修改所附的CZE序来做q些试验?/p>

八、ȝ
session机制本nq不复杂Q然而其实现和配|上的灵zL却使得具体情况复杂多变。这也要求我们不能把仅仅某一ơ的l验或者某一个浏览器Q服务器的经验当作普遍适用的经验,而是始终需要具体情况具体分析?/p>

]]>
JUnit单元试Mock技术之jMock用法介绍http://www.aygfsteel.com/jnbzwm/archive/2010/12/17/340951.html??/dc:creator>??/author>Fri, 17 Dec 2010 01:28:00 GMThttp://www.aygfsteel.com/jnbzwm/archive/2010/12/17/340951.htmlhttp://www.aygfsteel.com/jnbzwm/comments/340951.htmlhttp://www.aygfsteel.com/jnbzwm/archive/2010/12/17/340951.html#Feedback3http://www.aygfsteel.com/jnbzwm/comments/commentRss/340951.htmlhttp://www.aygfsteel.com/jnbzwm/services/trackbacks/340951.html阅读全文

]]>
JUnit4用法详解http://www.aygfsteel.com/jnbzwm/archive/2010/12/15/340801.html??/dc:creator>??/author>Wed, 15 Dec 2010 07:34:00 GMThttp://www.aygfsteel.com/jnbzwm/archive/2010/12/15/340801.htmlhttp://www.aygfsteel.com/jnbzwm/comments/340801.htmlhttp://www.aygfsteel.com/jnbzwm/archive/2010/12/15/340801.html#Feedback1http://www.aygfsteel.com/jnbzwm/comments/commentRss/340801.htmlhttp://www.aygfsteel.com/jnbzwm/services/trackbacks/340801.html阅读全文

]]>
ZStruts2、Freemarker的分늻件实?附工E源?http://www.aygfsteel.com/jnbzwm/archive/2010/12/01/339528.html??/dc:creator>??/author>Wed, 01 Dec 2010 09:35:00 GMThttp://www.aygfsteel.com/jnbzwm/archive/2010/12/01/339528.htmlhttp://www.aygfsteel.com/jnbzwm/comments/339528.htmlhttp://www.aygfsteel.com/jnbzwm/archive/2010/12/01/339528.html#Feedback4http://www.aygfsteel.com/jnbzwm/comments/commentRss/339528.htmlhttp://www.aygfsteel.com/jnbzwm/services/trackbacks/339528.html本文为原创,Ƣ迎转蝲Q{载请注明出处BlogJava?/span>

本次分页lg着重于面QFreemarker部分Q、及Action部分?br /> 至于Service及持久层处理Q只是做了一个模拟的实现Q实际开发中Q我是应用了iBatisQ封装了分页调用?br /> ׃用法有所不同Q所以就不放在源码范围内Q也不在q里介绍了?br /> q里的分功能只提供?上一c下一c指定页 的分,但在分页Java代码中包含了 首页、末늚实现。有需要的可自行添加?br />

分页的效果如图:



分页实现代码介绍Q?br /> 1.pagination.ftl 分页lg 面部分?br />
2.PageSupport.java 分页Action部分?br />
3.WebPager.java 计算分页动作?br />
4.Pager.java 保存分页信息Q由Action传递到ServiceQ根据Pager对象取得数据?br />
5.MockDataBase.java 模拟DaoQ实现分处理?br />

使用该组件的Ҏ如下Q?br />

W一步:引入分页lg

<#include "/ftl/ecs/pagination.ftl" />
分页lg使用了Freemarker的宏?br />

W二步:在ftl文g中用分늻?/span>

分页lg需要输?个参敎ͼ分别为id、method、btnCssClass、cssClassQ其中id、method必须输入QbtnCssClass、cssClass可选。以下是参数详细说明Q?br /> 1.id : 分页lg的唯一标识?br /> 2.method : 分页用的Action。例如:定义了Action为PaginationQ则method输入 Pagination.actionQ若为动态方法调用,可输入Pagination!query.action
3.cssClass : 分页lg的class属性。例如cssClass="center"?br /> 4.btnCssClass : 分页lg按钮的class属性。例如btnCssClass="btn_history"?br />

<@pagination id="***" btnCssClass="***" cssClass="***" method="***.action">
<table>
<tr>
<td></td>
...
</tr>
</table>
</pagination>

[~辑]W三步:l承分页cPageSupport

PageSupport.javal承自ActionSupport.javaQ在要分늚Ҏ中用PageSupport.java提供的List pageCall(String module, String target, Map dataMap)分页调用?br /> 通过setPageSize(int pageSize)Ҏ讑֮每页昄的记录数?br /> API详细说明Q?br /> 1.pageCall

 参数说明Q?
1) String module : 调用service的通道Q例如:upf、esf?
2) String target : 要调用的service的方法,例如Qcom.ailk.ecs.service.TdupfPageService.selectAllUser?
3) Map dataMap : 输入参数?
q回D明:
List : 面昄的数据记录?

2.setPageSize

 参数说明Q?
1) int pageSize : 每页昄记录数?

[~辑]
W四步:Service代码中?/span>

在service装分页Dao或者分|法?/p> pagination.ftl代码:

<#macro pagination id method cssClass="" btnCssClass="" pageSize='10'>
<div id='${id}'>
<#nested> <#-- 要刷新的区域 -->

<div class="${cssClass}">
    
<input type="button" onclick="Pagination${id}.gotoPage('prev', '${webPager.pageInfo.currentPage}', '${totalSize}');" value="上一? class="${btnCssClass}" />
    
&nbsp;&nbsp;?nbsp;${totalPages} ?/span>&nbsp;&nbsp;W?nbsp;${webPager.pageInfo.currentPage} ?/span>&nbsp;&nbsp;转到
    
<input type="text" id='${id}_inputPageNo' name='${id}_inputPageNo' size="6"/>?nbsp;&nbsp;&nbsp;
    
<input type="text" style="display:none"/>
    
<input type="button" onclick="Pagination${id}.gotoPage('input', '${webPager.pageInfo.currentPage}', '${totalSize}');" value="定" class="${btnCssClass}" />
    
<input type="button" onclick="Pagination${id}.gotoPage('next', '${webPager.pageInfo.currentPage}', '${totalSize}');" value="下一? class="${btnCssClass}" />
</div>

<script>
if (!this.Pagination${id} ) {
    
this.Pagination${id} = {}

    
// 分页处理Ҏ
    Pagination${id}.gotoPage = function(action, c, t) {
        
var cmd = action;

        
// 当总记录数量小于等于每记录数量时Q分动作无?/span>
        if (t <= ${webPager.pageInfo.pageSize}{
            
return;
        }


        
// 定按钮处理
        if(action == 'input') {
            
var inValue = $("#${id}_inputPageNo").val();

            
if(inValue.match(/^[0-9]+$/&& parseInt(inValue) > 0{
                cmd 
= inValue;
            }

            
else {
                
// TODO 提示错误信息
                return ;
            }

        }


        $('#$
{id}').load(
            '$
{method} #${id}',
            
{action : cmd,
             totalSize : t,
             currentPage : c
            }

        );
    }
;
    
    
// h当前面
    Pagination${id}.refreshPage = function() {
        
//Pagination${id}.gotoPage('refresh');
        //scrollPage${id}('refresh', "${method}");
    }
;

    
// 늠输入框keyup事g
    //Pagination${id}.keyup = function(inputElem, currentPage, totalSize) {
        //if (inputElem.value.match(/^[0-9]+$/) && parseInt(inputElem.value) > 0) {
            //Pagination${id}.gotoPage(inputElem.value, currentPage, totalSize);
        //}
    //};
    
    
//$("#${id}_inputPageNo").keyup(function(event){
        //if(event.keyCode == 13) {
            //Pagination${id}.keyup(this, '${webPager.pageInfo.currentPage}', '${totalSize}');
        //}
    //});
}

</script>

</div>
</#macro>



?a href="http://www.aygfsteel.com/Files/jnbzwm/Pagination.zip">点击下蝲源码?br />
非maven化工E,自己扑֌吧?br /> lib包如图:



]]>
ZStruts2 Result Type为chain 的Action之间数据传?/title><link>http://www.aygfsteel.com/jnbzwm/archive/2010/11/19/338495.html</link><dc:creator>??/dc:creator><author>??/author><pubDate>Fri, 19 Nov 2010 09:25:00 GMT</pubDate><guid>http://www.aygfsteel.com/jnbzwm/archive/2010/11/19/338495.html</guid><wfw:comment>http://www.aygfsteel.com/jnbzwm/comments/338495.html</wfw:comment><comments>http://www.aygfsteel.com/jnbzwm/archive/2010/11/19/338495.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.aygfsteel.com/jnbzwm/comments/commentRss/338495.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/jnbzwm/services/trackbacks/338495.html</trackback:ping><description><![CDATA[     摘要: 本文为原创,Ƣ迎转蝲Q{载请注明出处BlogJava? chain:基本用途是构造成一条动作链。前一个Action控制权转交l后一个ActionQ而前一个Action的状态在后一个Action里仍然保持着?我现在有一个场景,FirstAction 通过chain的方式,控制权交给 SecondAction。FirstAction对应的页面代码ؓfirst.ftlQSecondActi...  <a href='http://www.aygfsteel.com/jnbzwm/archive/2010/11/19/338495.html'>阅读全文</a><img src ="http://www.aygfsteel.com/jnbzwm/aggbug/338495.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/jnbzwm/" target="_blank">??/a> 2010-11-19 17:25 <a href="http://www.aygfsteel.com/jnbzwm/archive/2010/11/19/338495.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss> <footer> <div class="friendship-link"> <a href="http://www.aygfsteel.com/" title="狠狠久久亚洲欧美专区_中文字幕亚洲综合久久202_国产精品亚洲第五区在线_日本免费网站视频">狠狠久久亚洲欧美专区_中文字幕亚洲综合久久202_国产精品亚洲第五区在线_日本免费网站视频</a> </div> </footer> վ֩ģ壺 <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">հ</a>| <a href="http://" target="_blank">ʷ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">¬</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ߺ</a>| <a href="http://" target="_blank">ƽ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ʯ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ݳ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ƽ</a>| <a href="http://" target="_blank">̩</a>| <a href="http://" target="_blank">ָ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">º</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">տ</a>| <a href="http://" target="_blank">䶨</a>| <a href="http://" target="_blank">Դ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ɽ</a>| <a href="http://" target="_blank">Ϫ</a>| <a href="http://" target="_blank">ɽ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ҵ</a>| <script> (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })(); </script> </body>