??xml version="1.0" encoding="utf-8" standalone="yes"?>视频一区二区三区在线观看,中文产幕区在线观看,av激情成人网http://www.aygfsteel.com/liveandletdie/category/2656.htmlzh-cnFri, 20 Jul 2007 17:20:00 GMTFri, 20 Jul 2007 17:20:00 GMT60Maven学习W记Q?.基础概念Q?/title><link>http://www.aygfsteel.com/liveandletdie/articles/130959.html</link><dc:creator>q福是把温暖的枪</dc:creator><author>q福是把温暖的枪</author><pubDate>Wed, 18 Jul 2007 01:37:00 GMT</pubDate><guid>http://www.aygfsteel.com/liveandletdie/articles/130959.html</guid><wfw:comment>http://www.aygfsteel.com/liveandletdie/comments/130959.html</wfw:comment><comments>http://www.aygfsteel.com/liveandletdie/articles/130959.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/liveandletdie/comments/commentRss/130959.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/liveandletdie/services/trackbacks/130959.html</trackback:ping><description><![CDATA[Maven的核心概忉|POMQproject object modelQ一个最单的POM文g如下所C?br><project xmlns="<a xmlns:xsi="<a <br>  xsi:schemaLocation="<a >http://maven.apache.org/POM/4.0.0</a> <a ><br>  <modelVersion>4.0.0</modelVersion><br>  <groupId>net.blogjava.prometheus</groupId><br>  <artifactId>prometheus</artifactId><br>  <packaging>jar</packaging><br>  <version>1.0-SNAPSHOT</version><br>  <name>prometheus</name><br>  <url>http://maven.apache.org</url><br>  <dependencies><br>    <dependency><br>      <groupId>junit</groupId><br>      <artifactId>junit</artifactId><br>      <version>3.8.1</version><br>      <scope>test</scope><br>    </dependency><br>  </dependencies><br></project><br>projectQpom.xml的顶U元?br>modelVersionQ指明了POM正在使用的对象模型的版本。这个版本号极少改变?br>groupIdQ指明了创徏工程者的唯一标识W。一般来说基于工E创的域名Q例如net.blogjava.prometheus?br>artifactIdQ指明了工程生成的artifact的唯一基础名称QMaven最后生的artifact是这样一个格式:<artifactId><version>.<extension>Q比如prometheus-1.0-SNAPSHOT.jar?br>packagingQ指明了当前artifact打包的格式(warQjarQear{)<br>versionQ指明了工程产生的artifact的版本。SNAPSHOT表明当前版本正处于开发状态?br>nameQ指明了工程的显C名U?br>urlQ指明了工程的web site位于何处?br><br><br> <img src ="http://www.aygfsteel.com/liveandletdie/aggbug/130959.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/liveandletdie/" target="_blank">q福是把温暖的枪</a> 2007-07-18 09:37 <a href="http://www.aygfsteel.com/liveandletdie/articles/130959.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>常用正则表达式(摘录Q?/title><link>http://www.aygfsteel.com/liveandletdie/articles/59242.html</link><dc:creator>q福是把温暖的枪</dc:creator><author>q福是把温暖的枪</author><pubDate>Thu, 20 Jul 2006 09:21:00 GMT</pubDate><guid>http://www.aygfsteel.com/liveandletdie/articles/59242.html</guid><wfw:comment>http://www.aygfsteel.com/liveandletdie/comments/59242.html</wfw:comment><comments>http://www.aygfsteel.com/liveandletdie/articles/59242.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/liveandletdie/comments/commentRss/59242.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/liveandletdie/services/trackbacks/59242.html</trackback:ping><description><![CDATA[ <p>匚w中文字符的正则表辑ּQ?[\u4e00-\u9fa5]</p> <p>匚w双字节字W?包括汉字在内)Q[^\x00-\xff]</p> <p>匚wI的正则表辑ּQ\n[\s| ]*\r</p> <p>匚wHTML标记的正则表辑ּQ?<(.*)>.*<\/\1>|<(.*) \/>/ </p> <p>匚w首尾I格的正则表辑ּQ?^\s*)|(\s*$)</p> <p>匚wIP地址的正则表辑ּQ?\d+)\.(\d+)\.(\d+)\.(\d+)/ <br /><br />匚wEmail地址的正则表辑ּQ\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*</p> <p>匚w|址URL的正则表辑ּQhttp://([\w-]+\.)+[\w-]+(/[\w- ./?%&=]*)?</p> <img src ="http://www.aygfsteel.com/liveandletdie/aggbug/59242.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/liveandletdie/" target="_blank">q福是把温暖的枪</a> 2006-07-20 17:21 <a href="http://www.aygfsteel.com/liveandletdie/articles/59242.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>cronExpression的说?摘自http://www.opensymphony.com)http://www.aygfsteel.com/liveandletdie/articles/42100.htmlq福是把温暖的枪q福是把温暖的枪Thu, 20 Apr 2006 02:32:00 GMThttp://www.aygfsteel.com/liveandletdie/articles/42100.htmlhttp://www.aygfsteel.com/liveandletdie/comments/42100.htmlhttp://www.aygfsteel.com/liveandletdie/articles/42100.html#Feedback0http://www.aygfsteel.com/liveandletdie/comments/commentRss/42100.htmlhttp://www.aygfsteel.com/liveandletdie/services/trackbacks/42100.htmlCron expressions are comprised of 6 required fields and one optional field separated by white space. The fields respectively are described as follows:

Field Name   Allowed Values   Allowed Special Characters
Seconds   0-59   , - * /
Minutes   0-59   , - * /
Hours   0-23   , - * /
Day-of-month   1-31   , - * ? / L W C
Month   1-12 or JAN-DEC   , - * /
Day-of-Week   1-7 or SUN-SAT   , - * ? / L #
Year (Optional)   empty, 1970-2099   , - * /

The '*' character is used to specify all values. For example, "*" in the minute field means "every minute".

The '?' character is allowed for the day-of-month and day-of-week fields. It is used to specify 'no specific value'. This is useful when you need to specify something in one of the two fileds, but not the other.

The '-' character is used to specify ranges For example "10-12" in the hour field means "the hours 10, 11 and 12".

The ',' character is used to specify additional values. For example "MON,WED,FRI" in the day-of-week field means "the days Monday, Wednesday, and Friday".

The '/' character is used to specify increments. For example "0/15" in the seconds field means "the seconds 0, 15, 30, and 45". And "5/15" in the seconds field means "the seconds 5, 20, 35, and 50". Specifying '*' before the '/' is equivalent to specifying 0 is the value to start with. Essentially, for each field in the expression, there is a set of numbers that can be turned on or off. For seconds and minutes, the numbers range from 0 to 59. For hours 0 to 23, for days of the month 0 to 31, and for months 1 to 12. The "/" character simply helps you turn on every "nth" value in the given set. Thus "7/6" in the month field only turns on month "7", it does NOT mean every 6th month, please note that subtlety.

The 'L' character is allowed for the day-of-month and day-of-week fields. This character is short-hand for "last", but it has different meaning in each of the two fields. For example, the value "L" in the day-of-month field means "the last day of the month" - day 31 for January, day 28 for February on non-leap years. If used in the day-of-week field by itself, it simply means "7" or "SAT". But if used in the day-of-week field after another value, it means "the last xxx day of the month" - for example "6L" means "the last friday of the month". When using the 'L' option, it is important not to specify lists, or ranges of values, as you'll get confusing results.

The 'W' character is allowed for the day-of-month field. This character is used to specify the weekday (Monday-Friday) nearest the given day. As an example, if you were to specify "15W" as the value for the day-of-month field, the meaning is: "the nearest weekday to the 15th of the month". So if the 15th is a Saturday, the trigger will fire on Friday the 14th. If the 15th is a Sunday, the trigger will fire on Monday the 16th. If the 15th is a Tuesday, then it will fire on Tuesday the 15th. However if you specify "1W" as the value for day-of-month, and the 1st is a Saturday, the trigger will fire on Monday the 3rd, as it will not 'jump' over the boundary of a month's days. The 'W' character can only be specified when the day-of-month is a single day, not a range or list of days.

The 'L' and 'W' characters can also be combined for the day-of-month expression to yield 'LW', which translates to "last weekday of the month".

The '#' character is allowed for the day-of-week field. This character is used to specify "the nth" XXX day of the month. For example, the value of "6#3" in the day-of-week field means the third Friday of the month (day 6 = Friday and "#3" = the 3rd one in the month). Other examples: "2#1" = the first Monday of the month and "4#5" = the fifth Wednesday of the month. Note that if you specify "#5" and there is not 5 of the given day-of-week in the month, then no firing will occur that month.

The legal characters and the names of months and days of the week are not case sensitive.



]]>
href中target属性的用法Q摘录自http://www.zhcfw.com/new/List.Asp?ListID=752Q?/title><link>http://www.aygfsteel.com/liveandletdie/articles/39414.html</link><dc:creator>q福是把温暖的枪</dc:creator><author>q福是把温暖的枪</author><pubDate>Wed, 05 Apr 2006 08:22:00 GMT</pubDate><guid>http://www.aygfsteel.com/liveandletdie/articles/39414.html</guid><wfw:comment>http://www.aygfsteel.com/liveandletdie/comments/39414.html</wfw:comment><comments>http://www.aygfsteel.com/liveandletdie/articles/39414.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.aygfsteel.com/liveandletdie/comments/commentRss/39414.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/liveandletdie/services/trackbacks/39414.html</trackback:ping><description><![CDATA[target属?br /><br />  q个属性指定所链接的页面在览器窗口中的打开方式Q它的参数g要有Q_blank、_parent、_self、_topQ这些参数g表的含义如下Q?br /><br />  ◎_blankQ在新浏览器H口中打开链接文g?br /><br />  ◎_parentQ将链接的文件蝲入含有该链接框架的父框架集或父窗口中。如果含有该链接的框架不是嵌套的Q则在浏览器全屏H口中蝲入链接的文gQ就象_self参数一栗?br /><br />  ◎_selfQ在同一框架或窗口中打开所链接的文档。此参数为默认|通常不用指定?br /><br />  ◎_topQ在当前的整个浏览器H口中打开所链接的文档,因而会删除所有框架?br /><img src ="http://www.aygfsteel.com/liveandletdie/aggbug/39414.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/liveandletdie/" target="_blank">q福是把温暖的枪</a> 2006-04-05 16:22 <a href="http://www.aygfsteel.com/liveandletdie/articles/39414.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>hibernate学习W记Q-Q(入门Q?/title><link>http://www.aygfsteel.com/liveandletdie/articles/33230.html</link><dc:creator>q福是把温暖的枪</dc:creator><author>q福是把温暖的枪</author><pubDate>Thu, 02 Mar 2006 07:49:00 GMT</pubDate><guid>http://www.aygfsteel.com/liveandletdie/articles/33230.html</guid><wfw:comment>http://www.aygfsteel.com/liveandletdie/comments/33230.html</wfw:comment><comments>http://www.aygfsteel.com/liveandletdie/articles/33230.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/liveandletdie/comments/commentRss/33230.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/liveandletdie/services/trackbacks/33230.html</trackback:ping><description><![CDATA[unsaved-value<BR><BR>Hibernate提供了saveOrUpdate()ҎQ在定义映射文gӞ可以通过讑֮<id>标签的unsaved-value来决定更新方?BR><BR>unsaved-value取D围ؓQ?<BR>*any - L存储 <BR>*none - L更新 <BR>*null - id为null的时候存储(~省Q?<BR>*valid - id为null或者是指定值的时候存?<img src ="http://www.aygfsteel.com/liveandletdie/aggbug/33230.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/liveandletdie/" target="_blank">q福是把温暖的枪</a> 2006-03-02 15:49 <a href="http://www.aygfsteel.com/liveandletdie/articles/33230.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>XPATH学习W记http://www.aygfsteel.com/liveandletdie/articles/19804.htmlq福是把温暖的枪q福是把温暖的枪Tue, 15 Nov 2005 02:11:00 GMThttp://www.aygfsteel.com/liveandletdie/articles/19804.htmlhttp://www.aygfsteel.com/liveandletdie/comments/19804.htmlhttp://www.aygfsteel.com/liveandletdie/articles/19804.html#Feedback0http://www.aygfsteel.com/liveandletdie/comments/commentRss/19804.htmlhttp://www.aygfsteel.com/liveandletdie/services/trackbacks/19804.html
/代表根目?BR>
/node 代表根目录下名称为node的子节点

//* 代表所有元?BR>
//parent/child 代表所有本wؓchild父亲为parent的元?BR>
/node/*  根目录下node节点的所有子元素

/*/*/node W三层的节点,名称必须为node

[]代表元素的顺?@代表属?BR>
//node[@*] 选择node元素,有Q意属?BR>
//node[@name] 选择hname属性的node

//*[@name="abc"] 所有元素中name属性等于abc?BR>
引用:Ancestor表示当前节点的所有祖先节点,所以不仅包括该元素的直接父节点Q还包括父节点的父节点等

{。用一|表示节点层次关系的话Q所有该节点的上层都叫做Ancestor。例子://球|站/ancestor::*?BR>
表示所有球网站元素的先节点




]]>
Javacd载内q?转蝲自matrix)http://www.aygfsteel.com/liveandletdie/articles/18110.htmlq福是把温暖的枪q福是把温暖的枪Fri, 04 Nov 2005 03:53:00 GMThttp://www.aygfsteel.com/liveandletdie/articles/18110.htmlhttp://www.aygfsteel.com/liveandletdie/comments/18110.htmlhttp://www.aygfsteel.com/liveandletdie/articles/18110.html#Feedback0http://www.aygfsteel.com/liveandletdie/comments/commentRss/18110.htmlhttp://www.aygfsteel.com/liveandletdie/services/trackbacks/18110.htmlJavacd载内q?/SPAN>
作者:Binildas Christudas 01/26/2005

译Q?A target=_new>purplerain


版权声明Q可以Q意{载,转蝲时请务必以超链接形式标明文章原始出处和作者信息及本声?BR>作?
Binildas;purplerain
原文地址:http://www.onjava.com/pub/a/onjava/2005/01/26/classloading.html
中文地址:
http://www.matrix.org.cn/resource/article/43/43875_Class_Loading.html
关键词: Java Class Loading


cd载是java语言提供的最强大的机制之一。尽类加蝲q不是讨论的热点话题Q但所有的~程人员都应该了解其工作机制Q明白如何做才能让其满我们的需要。这能有效节省我们的~码旉Q从不断调试ClassNotFoundException, ClassCastException的工作中解脱出来?BR>
q篇文章从基讲vQ比如代码与数据的不同之处是什么,他们是如何构成一个实例或对象的。然后深入探讨java虚拟机(JVMQ是如何利用cd载器d代码Q以及java中类加蝲器的主要cd。接着用一个类加蝲的基本算法看一下类加蝲器如何加载一个内部类。本文的下一节演CZD代码来说明扩展和开发属于自qcd载器的必要性。紧接着解释如何使用定制的类加蝲器来完成一个一般意义上的Q务,使其可以加蝲Lq端客户的代码,在JVM中定义,实例化ƈ执行它。本文包括了J2EE关于cd载的规范——事实上q已l成ZJ2EE的标准之一?BR>
cM数据
一个类代表要执行的代码Q而数据则表示其相关状态。状态时常改变,而代码则不会。当我们一个特定的状态与一个类相对应v来,也就意味着一个类事例化。尽相同的cd应的实例其状态千差万别,但其本质都对应着同一D代码。在JAVA中,一个类通常有着一?class文gQ但也有例外。在JAVA的运行时环境中(Java runtimeQ,每一个类都有一个以W一c?first-class)的Java对象所表现出现的代码,其是java.lang.Class的实例。我们编译一个JAVA文gQ编译器都会嵌入一个public, static, final修饰的类型ؓjava.lang.ClassQ名UCؓclass的域变量在其字节码文件中。因Z用了public修饰Q我们可以采用如下的形式对其讉KQ?BR>
java.lang.Class klass = Myclass.class;


一旦一个类被蝲入JVM中,同一个类׃会被再次载入了(切记Q同一个类Q。这里存在一个问题就是什么是“同一个类”?正如一个对象有一个具体的状态,x识,一个对象始l和其代?c?相关联。同理,载入JVM的类也有一个具体的标识Q我们接下来看?BR>
在JAVA中,一个类用其完全匚wcd(fully qualified class name)作ؓ标识Q这里指的完全匹配类名包括包名和cd。但在JVM中一个类用其全名和一个加载类ClassLoader的实例作为唯一标识。因此,如果一个名为Pg的包中,有一个名为Cl的类Q被cd载器KlassLoader的一个实例kl1加蝲QCl的实例,即C1.class在JVM中表CZؓ(Cl, Pg, kl1)。这意味着两个cd载器的实?Cl, Pg, kl1) ?(Cl, Pg, kl2)是不同的Q被它们所加蝲的类也因此完全不同,互不兼容的。那么在JVM中到底有多少U类加蝲器的实例Q下一节我们揭C答案?BR>
cd载器

在JVM中,每一个类都被java.lang.ClassLoader的一些实例来加蝲.cClassLoader是在包中java.lang里,开发者可以自由地l承它ƈd自己的功能来加蝲cR?BR>
无论何时我们键入java MyMainClass来开始运行一个新的JVMQ“引导类加蝲?bootstrap class loader)”负责将一些关键的Javac,如java.lang.Object和其他一些运行时代码先加载进内存中。运行时的类在JRE\lib\rt.jar包文件中。因属于pȝ底层执行动作Q我们无法在JAVA文档中找到引导类加蝲器的工作l节。基于同L原因Q引导类加蝲器的行ؓ在各JVM之间也是大相径庭?BR>同理Q如果我们按照如下方式:

log(java.lang.String.class.getClassLoader());


来获取java的核心运行时cȝ加蝲器,׃得到null?BR>
接下来介ljava的扩展类加蝲器。扩展库提供比javaq行代码更多的特性,我们可以把扩展库保存在由java.ext.dirs属性提供的路径中?BR>
(~辑注:java.ext.dirs属性指的是pȝ属性下的一个keyQ所有的pȝ属性可以通过System.getProperties()Ҏ获得。在~者的pȝ中,java.ext.dirs的value是?C:\Program Files\Java\jdk1.5.0_04\jre\lib\ext”。下面将要谈到的如java.class.path也同属系l属性的一个key?

cExtClassLoader专门用来加蝲所有java.ext.dirs下的.jar文g。开发者可以通过把自q.jar文g或库文g加入到扩展目录的classpathQ其可以被扩展cd载器d?BR>
从开发者的角度Q第三种同样也是最重要的一U类加蝲器是AppClassLoader。这U类加蝲器用来读取所有的对应在java.class.pathpȝ属性的路径下的cR?BR>
Sun的java指南中,文章“理解扩展类加蝲”(Understanding Extension Class LoadingQ对以上三个cd载器路径有更详尽的解释,q是其他几个JDK中的cd载器
●java.net.URLClassLoader
●java.security.SecureClassLoader
●java.rmi.server.RMIClassLoader
●sun.applet.AppletClassLoader

java.lang.ThreadQ包含了public ClassLoader getContextClassLoader()ҎQ这一Ҏq回针对一具体U程的上下文环境cd载器。此cd载器qE的创徏者提供,以供此线E中q行的代码在需要加载类或资源时使用。如果此加蝲器未被徏立,~省是其父线E的上下文类加蝲器。原始的cd载器一般由d应用E序的类加蝲器徏立?BR>
cd载器如何工作Q?/SPAN>
除了引导cd载器Q所有的cd载器都有一个父cd载器Q不仅如此,所有的cd载器也都是java.lang.ClassLoadercd。以上两U类加蝲器是不同的,而且对于开发者自订制的类加蝲器的正常q行也至关重要。最重要的方面是正确讄父类加蝲器。Q何类加蝲器,其父cd载器是加载该cd载器的类加蝲器实例。(CQ类加蝲器本w也是一个类Q)

使用loadClass()Ҏ可以从类加蝲器中获得该类。我们可以通过java.lang.ClassLoader的源代码来了解该Ҏ工作的细节,如下Q?BR>
protected synchronized Class<?> loadClass
    (String name, boolean resolve)
    throws ClassNotFoundException{

    // First check if the class is already loaded
    Class c = findLoadedClass(name);
    if (c == null) {
        try {
            if (parent != null) {
                c = parent.loadClass(name, false);
            } else {
                c = findBootstrapClass0(name);
            }
        } catch (ClassNotFoundException e) {
            // If still not found, then invoke
            // findClass to find the class.
            c = findClass(name);
        }
    }
    if (resolve) {
            resolveClass(c);
    }
    return c;
}


我们可以使用ClassLoader的两U构造方法来讄父类加蝲器:

public class MyClassLoader extends ClassLoader{

    public MyClassLoader(){
        super(MyClassLoader.class.getClassLoader());
    }
}


?BR>
public class MyClassLoader extends ClassLoader{

    public MyClassLoader(){
        super(getClass().getClassLoader());
    }
}


W一U方式较为常用,因ؓ通常不徏议在构造方法里调用getClass()ҎQ因为对象的初始化只是在构造方法的出口处才完全完成。因此,如果父类加蝲器被正确建立Q当要示从一个类加蝲器的实例获得一个类Ӟ如果它不能找到这个类Q它应该首先去访问其父类。如果父cM能找到它(卛_父类也不能找不这个类Q等{?Q而且如果findBootstrapClass0()Ҏ也失败了Q则调用findClass()Ҏ。findClass()Ҏ的缺省实C抛出ClassNotFoundExceptionQ当它们l承java.lang.ClassLoader来订制类加蝲器时开发者需要实现这个方法。findClass()的缺省实现方式如下:

    protected Class<?> findClass(String name)
        throws ClassNotFoundException {
        throw new ClassNotFoundException(name);
    }


在findClass()Ҏ内部Q类加蝲器需要获取Q意来源的字节码。来源可以是文gpȝQURLQ数据库Q可以生字节码的另一个应用程序,及其他类似的可以产生java规范的字节码的来源。你甚至可以使用BCEL (Byte Code Engineering LibraryQ字节码工程?Q它提供了运行时创徏cȝ捷径。BCEL已经被成功地使用在以下方面:~译器,优化器,h器,代码产生器及其他分析工具。一旦字节码被检索,此方法就会调用defineClass()ҎQ此行ؓ对不同的cd载实例是有差异的。因此,如果两个cd载实例从同一个来源定义一个类Q所定义的结果是不同的?BR>
JAVA语言规范QJava language specificationQ详l解释了JAVA执行引擎中的cL接口的加载(loadingQ,链接QlinkingQ或初始化(initializationQ过E?BR>
图一昄了一个主cȝ为MyMainClass的应用程序。依照之前的阐述QMyMainClass.class会被AppClassLoader加蝲?MyMainClass创徏了两个类加蝲器的实例QCustomClassLoader1 ?CustomClassLoader2,他们可以从某数据源(比如|络Q获取名为Target的字节码。这表示cTarget的类定义不在应用E序c\径或扩展c\径。在q种情况下,如果MyMainClass惌用自定义的类加蝲器加载Targetc,CustomClassLoader1和CustomClassLoader2会分别独立地加蝲q定义Target.classcR这在java中有重要的意义。如果TargetcL一些静态的初始化代码,q且假设我们只希望这些代码在JVM中只执行一ơ,而这些代码在我们目前的步骤中会执行两ơ——分别被不同的CustomClassLoaders加蝲q执行。如果类Target被两个CustomClassLoaders加蝲q创Z个实例Target1和Target2Q如图一昄Q它们不是类型兼容的。换句话_在JVM中无法执行以下代码:

Target target3 = (Target) target2;


以上代码会抛Z个ClassCastException。这是因为JVM把他们视为分别不同的c,因ؓ他们被不同的cd载器所定义。这U情况当我们不是使用两个不同的类加蝲器CustomClassLoader1 ?CustomClassLoader2Q而是使用同一个类加蝲器CustomClassLoader的不同实例时Q也会出现同L错误。这些会在本文后边用具体代码说明?BR>
image
?. 在同一个JVM中多个类加蝲器加载同一个目标类

关于cd载、定义和链接的更多解释,请参考Andreas Schaefer?Inside Class Loaders."

Z么我们需要我们自qcd载器
原因之一为开发者写自己的类加蝲器来控制JVM中的cd载行为,java中的c靠其包名和cd来标识,对于实现了java.io.Serializable接口的类QserialVersionUID扮演了一个标识类版本的重要角艌Ӏ这个唯一标识是一个类名、接口名、成员方法及属性等l成的一?4位的哈希字段Q而且也没有其他快L方式来标识一个类的版本。严D来,如果以上的都匚wQ那么则属于同一个类?BR>
但是让我们思考如下情况:我们需要开发一个通用的执行引擎。可以执行实现某一特定接口的Q何Q务。当d被提交到q个引擎Q首先需要加载这个Q务的代码。假设不同的客户Ҏ引擎提交了不同的dQ凑巧,q些所有的d都有一个相同的cd和包名。现在面临的问题是q个引擎是否可以针对不同的用h提交的信息而做Z同的反应。这一情况在下文的参考一节有可供下蝲的代码样例,samepath ?differentversionsQ这两个目录分别演示了这一概念?BR>
? 昄了文件目录结构,有三个子目录samepath, differentversions, ?differentversionspushQ里Ҏ例子Q?BR>
image
?. 文g夹结构组l示?BR>
在samepath 中,cversion.Version保存在v1和v2两个子目录里Q两个类h同样的类名和包名Q唯一不同的是下边q行Q?BR>
    public void fx(){
        log("this = " + this + "; Version.fx(1).");
    }


V1中,日志记录中有Version.fx(1)Q而在v2中则是Version.fx(2)。把q个两个存在l微不同的类攑֜一个classpath下,然后q行Testc:

set CLASSPATH=.;%CURRENT_ROOT%\v1;%CURRENT_ROOT%\v2
%JAVA_HOME%\bin\java Test


?昄了控制台输出。我们可以看到对应着Version.fx(1)的代码被执行了,因ؓcd载器在classpath首先看到此版本的代码?BR>
image
?. 在类路径中samepath试排在最前面的version 1

再次q行Q类路径做如下微改动?

set CLASSPATH=.;%CURRENT_ROOT%\v2;%CURRENT_ROOT%\v1
%JAVA_HOME%\bin\java Test


控制台的输出变ؓ?。对应着Version.fx(2)的代码被加蝲Q因为类加蝲器在classpath中首先找到它的\径?BR>
image
?. 在类路径中samepath试排在最前面的version 2

Ҏ以上例子可以很明昑֜看出Q类加蝲器加载在c\径中被首先找到的元素。如果我们在v1和v2中删除了version.VersionQ做一个非version.Version形式?jar文gQ如myextension.jarQ把它放到对应java.ext.dirs的\径下Q再ơ执行后看到version.Version不再被AppClassLoader加蝲Q而是被扩展类加蝲器加载。如?所C?BR>
image
?. AppClassLoader及ExtClassLoader

l箋q个例子Q文件夹differentversions包含了一个RMI执行引擎Q客L可以提供l执行引擎Q何实Ccommon.TaskIntf接口的Q务。子文g夹client1 ?client2包含了类client.TaskImpl有个l微不同的两个版本。两个类的区别在以下几行Q?BR>
    static{
        log("client.TaskImpl.class.getClassLoader
        (v1) : " + TaskImpl.class.getClassLoader());
    }

    public void execute(){
        log("this = " + this + "; execute(1)");
    }


在client1和client2里分别有getClassLoader(v1) ?execute(1)和getClassLoader(v2) ?execute(2)的的log语句。ƈ且,在开始执行引擎RMI服务器的代码中,我们随意地将client2的Q务实现放在类路径的前面?BR>
CLASSPATH=%CURRENT_ROOT%\common;%CURRENT_ROOT%\server;
    %CURRENT_ROOT%\client2;%CURRENT_ROOT%\client1
%JAVA_HOME%\bin\java server.Server


如图6Q?Q?的屏q截图,在客LVMQ各自的client.TaskImplc被加蝲、实例化Qƈ发送到服务端的VM来执行。从服务端的控制収ͼ可以明显看到client.TaskImpl代码只被服务端的VM执行一ơ,q个单一的代码版本在服务端多ơ生成了许多实例Qƈ执行d?BR>

image
?. 执行引擎服务器控制台

?昄了服务端的控制台Q加载ƈ执行两个不同的客L的请求,如图Q,Q所C。需要注意的是,代码只被加蝲了一ơ(从静态初始化块的日志中也可以明显看出Q,但对于客L的调用这个方法被执行了两ơ?BR>
image
图7. 执行引擎客户?1控制台 

图7中,客户端VM加蝲了含有client.TaskImpl.class.getClassLoader(v1)的日志内容的cTaskImpl的代码,q提供给服务端的执行引擎。图8的客LVM加蝲了另一个TaskImpl的代码,q发送给服务端?BR>
image
?. 执行引擎客户?2控制台 

在客L的VM中,cclient.TaskImpl被分别加载,初始化,q发送到服务端执行。图6q揭CZclient.TaskImpl的代码只在服务端的VM中加载了一ơ,但这“唯一的一ơ”却在服务端创造了许多实例q执行。或许客L1该不高兴了因为ƈ不是它的client.TaskImpl(v1)的方法调用被服务端执行了Q而是其他的一些代码。如何解册一问题Q答案就是实现定制的cd载器?BR>
定制cd载器

要较好地控制cȝ加蝲Q就要实现定制的cd载器。所有自定义的类加蝲器都应承自java.lang.ClassLoader。而且在构造方法中Q我们也应该讄父类加蝲器。然后重写findClass()Ҏ。differentversionspush文g夹包含了一个叫做FileSystemClassLoader的自订制的类加蝲器。其l构如图9所C?BR>
image
?. 定制cd载器关系

以下是在common.FileSystemClassLoader实现的主ҎQ?BR>
    
public byte[] findClassBytes(String className){

        try{
            String pathName = currentRoot +
                File.separatorChar + className.
                replace('.', File.separatorChar)
                + ".class";
            FileInputStream inFile = new
                FileInputStream(pathName);
            byte[] classBytes = new
                byte[inFile.available()];
            inFile.read(classBytes);
            return classBytes;
        }
        catch (java.io.IOException ioEx){
            return null;
        }
    }

    public Class findClass(String name)throws
        ClassNotFoundException{

        byte[] classBytes = findClassBytes(name);
        if (classBytes==null){
            throw new ClassNotFoundException();
        }
        else{
            return defineClass(name, classBytes,
                0, classBytes.length);
        }
    }

    public Class findClass(String name, byte[]
        classBytes)throws ClassNotFoundException{

        if (classBytes==null){
            throw new ClassNotFoundException(
                "(classBytes==null)");
        }
        else{
            return defineClass(name, classBytes,
                0, classBytes.length);
        }
    }

    public void execute(String codeName,
        byte[] code){

        Class klass = null;
        try{
            klass = findClass(codeName, code);
            TaskIntf task = (TaskIntf)
                klass.newInstance();
            task.execute();
        }
        catch(Exception exception){
            exception.printStackTrace();
        }
    }


q个cM客户端把client.TaskImpl(v1)转换成字节数l,之后此字节数l被发送到RMI服务端。在服务端,一个同Lcȝ来把字节数组的内容{换回代码。客L代码如下Q?BR>
public class Client{

    public static void main (String[] args){

        try{
            byte[] code = getClassDefinition
                ("client.TaskImpl");
            serverIntf.execute("client.TaskImpl",
                code);
            }
            catch(RemoteException remoteException){
                remoteException.printStackTrace();
            }
        }

    private static byte[] getClassDefinition
        (String codeName){
        String userDir = System.getProperties().
            getProperty("BytePath");
        FileSystemClassLoader fscl1 = null;

        try{
            fscl1 = new FileSystemClassLoader
                (userDir);
        }
        catch(FileNotFoundException
            fileNotFoundException){
            fileNotFoundException.printStackTrace();
        }
        return fscl1.findClassBytes(codeName);
    }
}


在执行引擎中Q从客户端收到的代码被送到定制的类加蝲器中。定制的cd载器把其从字节数l定义成c,实例化ƈ执行。需要指出的是,Ҏ一个客戯求,我们用类FileSystemClassLoader的不同实例来定义客户端提交的client.TaskImpl。而且Qclient.TaskImplq不在服务端的类路径中。这也就意味着当我们在FileSystemClassLoader调用findClass()ҎӞfindClass()调用内在的defineClass()Ҏ。类client.TaskImpl被特定的cd载器实例所定义。因此,当FileSystemClassLoader的一个新的实例被使用Q类又被重新定义为字节数l。因此,Ҏ个客Lhcclient.TaskImpl被多ơ定义,我们可以在相同执行引擎JVM中执行不同的client.TaskImpl的代码?BR>
    
public void execute(String codeName, byte[] code)throws RemoteException{

        FileSystemClassLoader fileSystemClassLoader = null;

        try{
            fileSystemClassLoader = new FileSystemClassLoader();
            fileSystemClassLoader.execute(codeName, code);
        }
        catch(Exception exception){
            throw new RemoteException(exception.getMessage());
        }
    }


CZ在differentversionspush文g夹下。服务端和客L的控制台界面分别如图10Q?1Q?2所C:

image
?0. 定制cd载器执行引擎

?0昄的是定制的类加蝲器控制台。我们可以看到client.TaskImpl的代码被多次加蝲。实际上针对每一个客LQ类都被加蝲q初始化?BR>
image
?1. 定制cd载器Q客L1

?1中,含有client.TaskImpl.class.getClassLoader(v1)的日志记录的cTaskImpl的代码被客户端的VM加蝲Q然后送到服务端。图12 另一个客L把包含有client.TaskImpl.class.getClassLoader(v1)的类代码加蝲q往服务端?BR>
image
?2. 定制cd载器Q客L1

q段代码演示了我们如何利用不同的cd载器实例来在同一个VM上执行不同版本的代码?BR>
J2EE的类加蝲?/SPAN>
J2EE的服务器們֐于以一定间隔频率,丢弃原有的类q新蝲入新的类。在某些情况下会q样执行Q而有些情况则不。同P对于一个web服务器如果要丢弃一个servlet实例Q可能是服务器管理员的手动操作,也可能是此实例长旉未相应。当一个JSP面被首ơ请求,容器会把此JSP面译成一个具有特定Ş式的servlet代码。一旦servlet代码被创建,容器׃把这个servlet译成class文g{待被用。对于提交给容器的每ơ请求,容器都会首先查这个JSP文g是否刚被修改q。是的话重新翻译此文gQ这可以保每次的请求都是及时更新的。企业的部|方案以.ear, .war, .rar{Ş式的文gQ同样需要重复加载,可能是随意的也可能是依照某种配置Ҏ定期执行。对所有的q些情况——类的加载、卸载、重新加载……全部都是徏立在我们控制应用服务器的cd载机制的基础上的。实现这些需要扩展的cd载器Q它可以执行由其自n所定义的类。Brett Peterson已经在他的文?Understanding J2EE Application Server Class Loading Architecturesl出了J2EE应用服务器的cd载方案的详细说明Q详见网站TheServerSide.com?BR>
l要
本文探讨了类载入到虚拟机是如何进行唯一标识的,以及cd果存在同Lcd和包名时所产生的问题。因为没有一个直接可用的cȝ本管理机Ӟ所以如果我们要按自q意愿来加载类Ӟ需要自p制类加蝲器来扩展其行为。我们可以利用许多J2EE服务器所提供的“热部v”功能来重新加蝲一个新版本的类Q而不改动服务器的VM。即使不涉及应用服务器,我们也可以利用定制类加蝲器来控制java应用E序载入cL的具体行为。Ted Neward的书Server-Based Java Programming中详l阐qjava的类加蝲QJ2EE的API以及使用他们的最佳途径?BR>
参?/SPAN>
●本文的源码:[下蝲文g]
●JDK 1.5 API文档
●Java语言规范
●Java tutorial 中的"Understanding Extension Class Loading "
●ONJava 中的"Inside Class Loaders"
●ONJava 中的"Inside Class Loaders: Debugging"
●JavaWorld中的"What version is your Java code?"
●TheServerSide中的" Understanding J2EE Application Server Class Loading Architectures"
●字节码工程?
●Server-Based Java ProgrammingQ作者:Ted Neward

Binildas Christudas 是Infosys的Communication Service Providers Practice (CSP)中的高技术架构师Q也是Sun认证企业架构师及微Y认证专家?


]]>
FreeMaker学习W记http://www.aygfsteel.com/liveandletdie/articles/13149.htmlq福是把温暖的枪q福是把温暖的枪Fri, 16 Sep 2005 05:42:00 GMThttp://www.aygfsteel.com/liveandletdie/articles/13149.htmlhttp://www.aygfsteel.com/liveandletdie/comments/13149.htmlhttp://www.aygfsteel.com/liveandletdie/articles/13149.html#Feedback0http://www.aygfsteel.com/liveandletdie/comments/commentRss/13149.htmlhttp://www.aygfsteel.com/liveandletdie/services/trackbacks/13149.html${data model} cM于jsp?lt;%=data model%><%=data model%>

2.JTL tag:?FONT color=#a03d10>#开?除了某些特定的tag会以@开?用户自定义的tag)

3.注释:<#-- 注释内容-->

4.几个tag的例?BR> 
    <#if condition> 内容</#if>

  <#else>  

  例子:
 
 <#if animals.python.price < animals.elephant.price>
   Pythons are cheaper than elephants today.
 <#else>


Pythons are not cheaper than elephants today.

</#if> 


















  循环d数据

<#list SequenceVar as variable>repeatThis</#list>





<#list animals as being>

  ${being.name}${being.price}
  </#list>

 





<#list whatnot.fruits as fruit>

${fruit}
  </#list>

插入文g中的内容
<#include "filename">


 



]]>
用jsp产生随机验证?收藏)http://www.aygfsteel.com/liveandletdie/articles/11202.htmlq福是把温暖的枪q福是把温暖的枪Fri, 26 Aug 2005 07:25:00 GMThttp://www.aygfsteel.com/liveandletdie/articles/11202.htmlhttp://www.aygfsteel.com/liveandletdie/comments/11202.htmlhttp://www.aygfsteel.com/liveandletdie/articles/11202.html#Feedback0http://www.aygfsteel.com/liveandletdie/comments/commentRss/11202.htmlhttp://www.aygfsteel.com/liveandletdie/services/trackbacks/11202.html<%!
Color getRandColor(int fc,int bc){//l定范围获得随机颜色
Random random = new Random();
if(fc>255) fc=255;
if(bc>255) bc=255;
int r=fc+random.nextInt(bc-fc);
int g=fc+random.nextInt(bc-fc);
int b=fc+random.nextInt(bc-fc);
return new Color(r,g,b);
}
%>
<%
//讄面不缓?BR>response.setHeader("Pragma","No-cache");
response.setHeader("Cache-Control","no-cache");
response.setDateHeader("Expires", 0);

// 在内存中创徏图象
int width=60, height=20;
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);

// 获取囑Ş上下?BR>Graphics g = image.getGraphics();

//生成随机c?BR>Random random = new Random();

// 讑֮背景?BR>g.setColor(getRandColor(200,250));
g.fillRect(0, 0, width, height);

//讑֮字体
g.setFont(new Font("Times New Roman",Font.PLAIN,18));

//画边?BR>g.setColor(new Color(255,255,255));
g.drawRect(0,0,width-1,height-1);

// 随机产生155条干扰线Q图象中的认证码不易被其它E序探测?BR>g.setColor(getRandColor(160,200));
for (int i=0;i<155;i++)
{
int x = random.nextInt(width);
int y = random.nextInt(height);
int xl = random.nextInt(12);
int yl = random.nextInt(12);
g.drawLine(x,y,x+xl,y+yl);
}

// 取随Z生的认证?4位数?
String sRand="";
for (int i=0;i<4;i++){
String rand=String.valueOf(random.nextInt(10));
sRand+=rand;
// 认证码昄到图象中
g.setColor(new Color(20+random.nextInt(110),20+random.nextInt(110),20+random.nextInt(110)));
//调用函数出来的颜色相同,可能是因为种子太接近Q所以只能直接生?BR>g.drawString(rand,13*i+6,16);
}

// 认证码存入SESSION
session.setAttribute("rand",sRand);

// 图象生效
g.dispose();

// 输出图象到页?BR>ImageIO.write(image, "JPEG", response.getOutputStream());

%>

-------------我是漂亮的分割线---------------

display.jsp

<%@ page contentType="text/html;charset=gb2312" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>认证码输入页?lt;/title>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<META HTTP-EQUIV="Pragma" CONTENT="no-cache">
<META HTTP-EQUIV="Cache-Control" CONTENT="no-cache">
<META HTTP-EQUIV="Expires" CONTENT="0">
</head>
<body>
<form method=post action="check.jsp">
<table>
<tr>
<td align=left>pȝ产生的认证码Q?lt;/td>
<td><img border=0 src="image.jsp"></td>
</tr>
<tr>
<td align=left>输入上面的认证码Q?lt;/td>
<td><input type=text name=rand maxlength=4 value=""></td>
</tr>
<tr>
<td colspan=2 align=center><input type=submit value="提交?></td>
</tr>
</form>
</body>
</html>

------------分割U?又见分割U?-------------------------

check.jsp

<%@ page contentType="text/html; charset=gb2312" language="java" import="java.sql.*" errorPage="" %>
<html>
<head>
<title>认证码验证页?lt;/title>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<META HTTP-EQUIV="Pragma" CONTENT="no-cache">
<META HTTP-EQUIV="Cache-Control" CONTENT="no-cache">
<META HTTP-EQUIV="Expires" CONTENT="0">
</head>

<body>
<%
 String rand = (String)session.getAttribute("rand");
 String input = request.getParameter("rand");
%>
pȝ产生的认证码为: <%= rand %><br>
您输入的认证码ؓQ?<%= input %><br>
<br>
<%
  if (rand.equals(input)) {
%>
<font color=green>输入相同Q认证成功!</font>
<%
  } else {
%>
<font color=red>输入不同Q认证失败!</font>
<%
  }
%>
</body>
</html>



]]>
java~程思想MW记http://www.aygfsteel.com/liveandletdie/articles/11201.htmlq福是把温暖的枪q福是把温暖的枪Fri, 26 Aug 2005 07:24:00 GMThttp://www.aygfsteel.com/liveandletdie/articles/11201.htmlhttp://www.aygfsteel.com/liveandletdie/comments/11201.htmlhttp://www.aygfsteel.com/liveandletdie/articles/11201.html#Feedback0http://www.aygfsteel.com/liveandletdie/comments/commentRss/11201.htmlhttp://www.aygfsteel.com/liveandletdie/services/trackbacks/11201.html

存放数据的地?/FONT>:

1.寄存?Registers):位于处理器内?速度最?E序员无法直接操U?

2.?Stack):位于一般的RAM当中,处理器由指针提供支持.因ؓ要移动指?所以存攑֜stack中的数据的实际大和存活旉都是明确?reference可以|入其中,但是java对象不可?

3.?Heap):位于RAM当中,攄所有的java对象.new的对象都是自Heap分配I间?

4.静态存储空?Static storage):static可以某个对象内的特定成员置为静?java对象不可能置入此?

5.帔R存储I间(Constant storage):位于ROM?

6.Non-RAM存储I间:streamed objects和persistent objects.

两种型别

1.对象型别:object type

2.基本型别:primitive type 不以new分配I间,而是一Uautomatic变量直接存放数据?|于stack

如果惛_heap内代替基本型?可以适用外覆c?比如Character(char)

cȝ初始化过E?/FONT>

1.当一个对象首ơ生?或者当cȝstatic函数和static对象首次被访?java inter Preter首先Ҏclasspath环境变量来查找该对象.

2.一旦类被装?执行它的static初始动作,因此static初始化动作仅发生一?是在Class对象首次被装载时.

3.当new Class(),则先为class对象在Heap上分配够的存储I间.

4.该存储空间先被清I?q自动将class对象内部所有隶属基本类型的数据设ؓ~省?q将reference|ؓnull

5.执行所有出C数据定义处的初始化动?/P>

6.执行构造函?/P>

]]>
jsp跌{中绝对\径和相对路径的解军_?来源:csdn)http://www.aygfsteel.com/liveandletdie/articles/11060.htmlq福是把温暖的枪q福是把温暖的枪Thu, 25 Aug 2005 06:48:00 GMThttp://www.aygfsteel.com/liveandletdie/articles/11060.htmlhttp://www.aygfsteel.com/liveandletdie/comments/11060.htmlhttp://www.aygfsteel.com/liveandletdie/articles/11060.html#Feedback0http://www.aygfsteel.com/liveandletdie/comments/commentRss/11060.htmlhttp://www.aygfsteel.com/liveandletdie/services/trackbacks/11060.html   对于jsp和用sendRedirect跌{的servletQ采用直接用带
   容器路径[String request.getContextPath()]的绝对\径就可以d解决Q即Q?BR>    1Q?lt;%
          String contextPath = request.getContextPath();
          String url = contextPath + "/user/login.jsp";
       %>
       
       <a href="<%=url%>"> login</a>
   2Q?....
      String contextPath = request.getContextPath();
      String targetPath = contextPath + "/user/login.jsp";
      RequestDispatcher rd = request.getRequestDispatcher(targetPath);
      rd.forward(request, response);
      ......

   对于使用forward跌{的servletQ则不要加容器\径,否则重复出?容器路径Q?BR>

]]>
commons loggingW记http://www.aygfsteel.com/liveandletdie/articles/10310.htmlq福是把温暖的枪q福是把温暖的枪Wed, 17 Aug 2005 02:19:00 GMThttp://www.aygfsteel.com/liveandletdie/articles/10310.htmlhttp://www.aygfsteel.com/liveandletdie/comments/10310.htmlhttp://www.aygfsteel.com/liveandletdie/articles/10310.html#Feedback0http://www.aygfsteel.com/liveandletdie/comments/commentRss/10310.htmlhttp://www.aygfsteel.com/liveandletdie/services/trackbacks/10310.html1.下蝲commons logging和log4j的jar?br />2.配置2个properties文g,分别?strong>commons-logging.properties和log4j.properties
commons-logging.properties文g内容:
org.apache.commons.logging.Log=org.apache.commons.logging.impl.Log4JLogger
log4j.properties文g内容
log4j.rootLogger=info,stdout,file
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %p [%c] %m%n
log4j.appender.file=org.apache.log4j.RollingFileAppender
log4j.appender.file.File=youapp.log
log4j.appender.file.MaxFileSize=512KB
log4j.appender.file.MaxBackupIndex=5
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern==%d{yyyy-MM-dd HH:mm:ss} %p [%c] %m%n
3.这2个properties文g攑ֈclasses目录?br />4.E序中调用log
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
..........
protected final Log logger = LogFactory.getLog(getClass());


-------------log4j的一些零散笔?-----------
1.
log4j.additivity.mypackage.myclass=false
默认讄为trueQ即l承root loggerQ会D自定义的子logger和父logger出现重复记录
设ؓfalseQ则不再从父loggerl承Q记录将只出现在子logger当中?br />2.MDC
为多个client的环境提供记录各自信息,可以通过filter来扩?br />所记录信息在配|文件中可以通过%X{key} 来获?br />例如MDC.put("remoteHost", request.getRemoteHost());



]]>
վ֩ģ壺 Ӻ| ־| | ƽ| | | | | | ľ| | | ƾ| ɽ| | | ǭ| »| | | | ʩ| | ɽ| ÷| Զ| | | | | | | פ| | ˮ| ̴| Ѱ| | | ·| |