??xml version="1.0" encoding="utf-8" standalone="yes"?>亚洲午夜日韩高清一区,国产精品亚洲专区无码WEB,国产成人高清亚洲http://www.tkk7.com/wyz191/category/19203.html走向一条通往JAVA的不归\...zh-cnThu, 22 Mar 2007 10:16:28 GMTThu, 22 Mar 2007 10:16:28 GMT60Java中日期的使用Ҏ(gu)http://www.tkk7.com/wyz191/articles/105161.htmljava_蝈蝈java_蝈蝈Wed, 21 Mar 2007 01:57:00 GMThttp://www.tkk7.com/wyz191/articles/105161.htmlhttp://www.tkk7.com/wyz191/comments/105161.htmlhttp://www.tkk7.com/wyz191/articles/105161.html#Feedback0http://www.tkk7.com/wyz191/comments/commentRss/105161.htmlhttp://www.tkk7.com/wyz191/services/trackbacks/105161.html1、 DateQ具体类java.util.Date Q?br />2、 Calendar:抽象cjava.text.DateFormat,它派生的一个子cMؓ(f)java.text.SimpleDateFormat 
3、 DateFormat:抽象cjava.util.CalendarQ它z的一个子cMؓ(f)java.util.GregorianCalendar 
Q注Q如果有朋友对具体类和抽象类不了解,可以参考相关Java资料Q?br />
现在对以上三个类q行如下分析Q?br />
一、对Datecȝ分析 

Date cMJDK 1.0开始进化, 当时它只包含了几个简单的处理日期数据的方法。 由于这些方法实用性差Q现在基本上被CalendarcM各方法所代替了。这U改q目的是Z更好的处理日期数据国际化格式。 Date cd际上只是一个包裹类, 它包含一个长整型数据, 表示的是从GMT(格林治标准旉)1970q? 1 月??0:00:00q一M前或者是之后l历的毫U数. 

Z加深对Datecȝ理解Q列丑֦下一个简单例子来说明Date的用:(x) 
import java.util.Date; 
public class DateTest1 { 
public static void main(String[] args) { 
/** Get the system Date **/ 
Date date = new Date(); 
System.out.println(date.getTime()); 


pȝ输出如下l果Q?br />1001803809710 

在这个例子中,值得我们注意的是我们使用了Date 构造函数创Z个日期对? 在没有Q何参数的情况下,q个构造函C(x)自动调用System.currentTimeMillis() Ҏ(gu)来获取当前系l日?。?br />

二、对DateFormatcȝ分析 

如果我们希望定制日期数据的格? 比如昄的日期格式ؓ(f)Q?006q?6?3日,抽象cjava.util.Calendar和它的子cjava.util.GregorianCalendar能完成这一功能。?br />下面的例子展CZ如何完成q个工作: 
import java.util.SimpleDateFormat; 
import java.util.Date; 
public class DateTest2 { 
public static void main(String[] args) { 

SimpleDateFormat format = new SimpleDateFormat("yyyyqMM月dd?,Locale.US); 
Date date = new Date(); 
System.out.println(bartDateFormat.format(date)); 



只要通过向SimpleDateFormat 的构造函C递格式字W串" yyyyqMM月dd?, 我们可以指明自己想要的格式. 其中yyyy是年QMM是月, dd是日. 字符的个数决定了日期是如何格式化的,如果格式?yyyyqMM月dd?׃(x)昄 06q?6?3日;如果?yy-MM-dd"显C?6-06-23。?br />
三、对Calendar cȝ分析 

如果惌|、获取、操U一个日期对象的各个特定部分Q比如获得小? ? 分钟、计一个月的某一天说星期几等{。这L(fng)情况需要抽象类java.util.Calendar和它的子cL处理。ؓ(f)了能清楚地说明问题,列D下面的例? 它的功能是计第十个星期五是13? 

import java.util.GregorianCalendar; 
import java.util.Date; 
import java.text.DateFormat; 
public class CalendarTest{ 

public static void main(String[] args) { 
DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.FULL); 
GregorianCalendar cal = new GregorianCalendar(); 

/** Set the date and time of our calendar to the system&s date and time **/ 
cal.setTime(new Date()); 
System.out.println("System Date: " + dateFormat.format(cal.getTime())); 

/** Set the day of week to FRIDAY **/ 
cal.set(GregorianCalendar.DAY_OF_WEEK, GregorianCalendar.FRIDAY); 
System.out.println("After Setting Day of Week to Friday: " + 
dateFormat.format(cal.getTime())); 

int friday13Counter = 0; 
while (friday13Counter <= 10) { 

/** Go to the next Friday by adding 7 days. **/ 
cal.add(GregorianCalendar.DAY_OF_MONTH, 7); 

/** If the day of month is 13 we have another Friday the 13th. **/ 
if (cal.get(GregorianCalendar.DAY_OF_MONTH) == 13) { 
friday13Counter++; 
System.out.println(dateFormat.format(cal.getTime())); 




输出l果? 
System Date: Saturday, September 29, 2005 


四、ȝ 

在Java通过一下三个类的用,一般可以满_UŞ式的日期使用。实际上QJava中日期用的Ҏ(gu)q有很多Q如果有兴趣的朋友请参考JDK帮助手册。?br />http://www.javaresearch.org/article/55424.htm

java_蝈蝈 2007-03-21 09:57 发表评论
]]>
JDBC2/3.0的特征点?http://www.tkk7.com/wyz191/articles/jdbc.htmljava_蝈蝈java_蝈蝈Mon, 05 Feb 2007 06:38:00 GMThttp://www.tkk7.com/wyz191/articles/jdbc.htmlhttp://www.tkk7.com/wyz191/comments/97998.htmlhttp://www.tkk7.com/wyz191/articles/jdbc.html#Feedback0http://www.tkk7.com/wyz191/comments/commentRss/97998.htmlhttp://www.tkk7.com/wyz191/services/trackbacks/97998.html
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery("SELECT * FROM user WHERE username='aa'");
stmt.executeUpdate("UPDATE user SET lastdatetime=now() where username='aa'"); 

q是一个用L(fng)录时Q经常用到的代码Q先是根据用户名aa查找该用L(fng)详细信息Q然后再更新该用L(fng)最后登录时_(d)lastdatetimeQ。这q个里面Q我们用了两个sql语句Q这个是我一直用的方法,但是如果用JDBC2.0l我们提供的便利Q我们只要写一条sql够了,其他的都交给jdbcQ看下面的代码:(x) 

Statement stmt2 = con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE);
ResultSet rs2 = stmt.executeQuery("SELECT * FROM user WHERE username='aa'");
rs2.next();
rs2.updateDate("lastdatetime", new Date(Calendar.getInstance().getTimeInMillis()));
rs2.updateRow(); 

q里面最主要的特征就是ResultSet.TYPE_FORWARD_ONLY和ResultSet.CONCUR_UPDATABLEQ通过初始化Statement时传不同的参敎ͼ可以对ResultSetq行不用的错作限制。con.createStatement的时候,有三U可以掉用的函数Q?

1、createStatement();
2、createStatement(int resultSetType, int resultSetConcurrency)
3、createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability) 

其中resultSetType可选值是Q?
   1、ResultSet.TYPE_FORWARD_ONLY  在ResultSet中只能先前移动游标,
   2、ResultSet.TYPE_SCROLL_INSENSITIVE 在ResultSet中可以随心所Ʋ的先前向后Ud游标Q?
   3、ResultSet.TYPE_SCROLL_SENSITIVE 在ResultSet中可以随心所Ʋ的先前向后Ud游标Q同时ResultSet的值有所改变的时候,他可以得到改变后的最新的?
其中resultSetConcurrency可选值是Q?
   1、ResultSet.CONCUR_READ_ONLY  在ResultSet中的数据记录是只ȝQ可以修?
   2、ResultSet.CONCUR_UPDATABLE  在ResultSet中的数据记录可以L修改Q然后更C(x)数据?
其中resultSetHoldability可选值是Q?
   1、ResultSet.HOLD_CURSORS_OVER_COMMIT 表示修改提交?不关闭ResultSet的游?
   2、ResultSet.CLOSE_CURSORS_AT_COMMIT  表示修改提交?关闭ResultSet的游标?

对于查询操作W一U初始化Ҏ(gu)createStatement()Q相当于W二U方法的createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY)Q第三种Ҏ(gu)的createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY, ResultSet.CLOSE_CURSORS_AT_COMMIT) 

下面写一Ddemo的代码,我把一些特征函数都用出来,但是只是用来查考和说明名灵zL的。?

 Statement stmt2 = con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE);
 ResultSet rs2 = stmt.executeQuery("SELECT * FROM user");
 rs2.next();
 rs2.updateDate("lastdatetime", new Date(Calendar.getInstance().getTimeInMillis()));
 rs2.updateRow();
 rs2.afterLast();
 while(rs2.previous()){ /**....*/ }
 rs.beforeFirst();
 while(rs2.next()){  /**....*/ }
 rs.last();
 rs.first();
 rs.absolute(5); //游标Ud到第5?
 rs.absolute(-1);  //游标Ud到最后一?
 rs.relative(-5);  //游标向上Ud5?
 rs.relative(2);   //游标向下Ud2?
 rs.deleteRow(); //删除当前?
 rs.last();  //游标Ud到最?
 rs.updateString("summary", "This is ..."); //讄更新的字D?
 rs.cancelRowUpdates();  //取消刚才输入的更?
 rs.getRow(); //得到当前行号
 rs.moveToInsertRow();  //游标Ud到要新增的那条记录上
 rs.updateInt("id", 1);
 rs.updateString(2, "my name");
 rs.insertRow(); //插入新记录?


JDBC2.0提供的还有一个功能就是数据库的批量操作:(x) 

  con.setAutoCommit(false);
  Statement stmt3 = con.createStatement();
  stmt3.addBatch("insert .....");
  stmt3.addBatch("insert .....");
  int[] rows = stmt3.executeBatch();
  con.commit(); 

但是有一点要注意Qstmt3.executeBatch()他不?x)自动给你回滚数据操作,当你?条update语句的时候,如果W三条发生错误,那么无法自动回滚前两条update语句的媄响,所以一定要自己手工q行事务理。?

在?zhn)的事务中使用 Savepoint 
JDBC3.0中最令h兴奋的附加特点就是 Savepoint 了。有时候需要的是对事务多一点的控制Q而不是在当前的事务中单地Ҏ(gu)一个改变进行回滚。在JDBC3.0下,(zhn)就可以通过 Savepoint 获得q种控制。Savepoint 接口允许(zhn)将事务分割为各个逻辑断点Q以控制有多事务需要回滚。看下面的代码:(x) 

conn.setAutoCommit(false); 
conn.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE); 
Statement stmt = conn.createStatement(); 
int rows = stmt.executeUpdate( "INSERT INTO authors (first_name, last_name) valueS(′Lewis? ′Carroll?"); 
Savepoint svpt = conn.setSavepoint("NewAuthor"); 
try{
 rows = stmt.executeUpdate( "UPDATE authors set type = ′fiction′ WHERE last_name = ′Carroll?); 
}catch(Exception e){
 conn.rollback(svpt);
 rows = stmt.executeUpdate( " update .......... other sql ");
}
conn.commit(); 

上面代码昄Q当UPDATE authorsp|的时候,pȝ事务回滚UPDATE authors的sql的媄响,而INSERT INTO authors的sql仍然有效 


索自动生的关键字?/b> 
Z解决对获取自动生的或自动增加的关键字的值的需求,JDBC 3.0现在获取这U值变得很L。要定M所产生的关键字的|只要单地在语句的 execute() Ҏ(gu)中指定一个可选的标记QStatement.RETURN_GENERATED_KEYS和Statement.NO_GENERATED_KEYS。在执行q条语句后,所产生的关键字的值就?x)通过从 Statement 的实例方法 getGeneratedKeys() 来检索 ResultSet 而获得。ResultSet 包含了每个所产生的关键字的列。看下面代码Q?

Statement stmt = conn.createStatement(); 
stmt.executeUpdate("INSERT INTO authors (first_name, last_name) valueS (′George? ′Orwell?", Statement.RETURN_GENERATED_KEYS); 
ResultSet rs = stmt.getGeneratedKeys(); 
if ( rs.next() ) { 
 int key = rs.getInt(); 
}

http://www.netskycn.com/article/articleId2913.html

java_蝈蝈 2007-02-05 14:38 发表评论
]]>
基本的类装入异常 http://www.tkk7.com/wyz191/articles/97908.htmljava_蝈蝈java_蝈蝈Mon, 05 Feb 2007 00:29:00 GMThttp://www.tkk7.com/wyz191/articles/97908.htmlhttp://www.tkk7.com/wyz191/comments/97908.htmlhttp://www.tkk7.com/wyz191/articles/97908.html#Feedback0http://www.tkk7.com/wyz191/comments/commentRss/97908.htmlhttp://www.tkk7.com/wyz191/services/trackbacks/97908.html    下面的几U异常是比较常见的:(x)
ClassNotFoundException
    ClassNotFoundException 是最常见的类装入异常cd。它发生在装入阶Dc(din)Java 规范?ClassNotFoundException 的描q是q样的:(x)
    当应用程序试N过cȝ字符串名Uͼ使用以下三种Ҏ(gu)装入c,但却找不到指定名U的cd义时抛出该异常?br />    * c?Class 中的 forName() Ҏ(gu)?br />    * c?ClassLoader 中的 findSystemClass() Ҏ(gu)?br />    * c?ClassLoader 中的 loadClass() Ҏ(gu)?br />    所以,如果昑ּ地装入类的尝试失败,那么抛?ClassNotFoundException?br />    q些异常修复h通常比较单。可以用  verbose 选项查类路径Q确保用的c\径设|正。如果类路径讄正确Q但是仍然看到这个错误,那么是需要的cdc\径中不存在。要修复q个问题Q可以把cȝ动到c\径中指定的目录或 JAR 文g中,或者把cL在的位置d到类路径中?br />
NoClassDefFoundError
    NoClassDefFoundError 是类装入器在装入阶段抛出的另一个常见异常。JVM 规范?NoClassDefFoundError 的定义如下:(x)
    如果 Java 虚拟机或 ClassLoader 实例试图装入cd义(作ؓ(f)正常的方法调用的一部分Q或者作Z?new 表达式创建新实例的一部分Q,但却没有扑ֈcd义时抛出该异常?br />    当目前执行的cdl编译,但是找不到它的定义时Q会(x)存在 searched-for cd义?
    实际上,q意味着 NoClassDefFoundError 的抛出,是不成功的隐式类装入的结果?br />    单说来,是引用的类在类路径中没有找到?br />ClassCastException
    c装入器能够抛出的另一个异常是 ClassCastException。它是在cd比较中发C兼容cd的时候抛出的。JVM 规范指定 ClassCastException 是:(x)
    该异常的抛出Q表明代码企图把对象的类型{换成一个子c,而该对象q不是这个子cȝ实例?
UnsatisfiedLinkError
    在把本地Ҏ(gu)调用链接到对应的本机定义Ӟc装入器扮演着重要角色。如果程序试图装入一个不存在或者放错的本机库时Q在链接阶段的解析过E会(x)发生 UnsatisfiedLinkError。JVM 规范指定 UnsatisfiedLinkError 是:(x)
    对于声明?native 的方法,如果 Java 虚拟机找不到和它对应的本a定义Q就?x)抛异常?
    当调用本机方法时Q类装入器会(x)试装入定义了该Ҏ(gu)的本机库。如果找不到q个库,׃(x)抛出q个错误?br />    本机库的装入p?System.loadLibrary() Ҏ(gu)的类的类装入器启?Q根据用的c装入器Q会(x)搜烦不同的位|:(x)
    * 对于?bootstrap c装入器装入的类Q搜?sun.boot.library.path?br />    * 对于由扩展类装入器装入的c,先搜?java.ext.dirsQ然后是 sun.boot.library.pathQ然后是 java.library.path?br />    * 对于ql类装入器装入的c,搜烦 sun.boot.library.pathQ然后是 java.library.path?br />ClassCircularityError
    JVM 规范指定 ClassCircularityError 的抛出条件是Q?br />    cL接口׃是自q类或超接口而不能被装入?
    q个错误是在链接阶段的解析过E中抛出的。这个错误有点奇怪,因ؓ(f) Java ~译器不允许发生q种循环情况。但是,如果独立地编译类Q然后再把它们放在一P可能发生这个错误?br />ClassFormatError
JVM 规范指出Q抛?ClassFormatError 的条件是Q?br />    负责指定所h的编译类或接口的二进制数据Ş式有误?
    q个异常是在c装入的链接阶段的校验过E中抛出。如果字节码发生了更改,例如ȝ本号或次版本号发生了更改Q那么二q制数据的Ş式就?x)有误。例如,如果对字节码故意做了更改Q或者在通过|络传送类文g时现Z错误Q那么就可能发生q个异常?br />    修复q个问题的惟一Ҏ(gu)是获得字节码的正确副本Q可能需要重新进行编译?br />ExceptionInInitializerError
Ҏ(gu) JVM 规范Q抛?ExceptionInInitializer 的情冉|Q?br />    * 如果初始化器H然完成Q抛Z些异?EQ而且 E 的类不是 Error 或者它的某个子c,那么׃(x)创徏 ExceptionInInitializerError cȝ一个新实例Qƈ?E 作ؓ(f)参数Q用q个实例代替 E?br />    * 如果 Java 虚拟囑ֈ建类 ExceptionInInitializerError 的新实例Q但是因为出?Out-Of-Memory-Error 而无法创建新实例Q那么就抛出 OutOfMemoryError 对象作ؓ(f)代替?br />http://www.tkk7.com/zyl/archive/2007/02/04/97881.html

java_蝈蝈 2007-02-05 08:29 发表评论
]]>
又谈q问题解决[转]http://www.tkk7.com/wyz191/articles/95671.htmljava_蝈蝈java_蝈蝈Wed, 24 Jan 2007 02:00:00 GMThttp://www.tkk7.com/wyz191/articles/95671.htmlhttp://www.tkk7.com/wyz191/comments/95671.htmlhttp://www.tkk7.com/wyz191/articles/95671.html#Feedback0http://www.tkk7.com/wyz191/comments/commentRss/95671.htmlhttp://www.tkk7.com/wyz191/services/trackbacks/95671.html有h_(d)q问题一直跟中国的程序员特别有缘Q真是再同意不过了,不管是StrutsQJSFQJSPQ还是MySQLQTomcatQ全都或多或有q的问题?br />一般的做法有用FilterQ?

 < filter >
     < filter-name > Set Character Encoding </ filter-name >
     < filter-class > org.springframework.web.filter.CharacterEncodingFilter </ filter-class >
     < init-param >
       < param-name > encoding </ param-name >
       < param-value > GBK </ param-value >
     </ init-param >
     < init-param >
       < param-name > ignore </ param-name >
       < param-value > true </ param-value >
     </ init-param >
   </ filter >
   < filter-mapping >
     < filter-name > Set Character Encoding </ filter-name >
     < url-pattern > *.do </ url-pattern >
   </ filter-mapping >
   < filter-mapping >
     < filter-name > Set Character Encoding </ filter-name >
     < url-pattern > *.jsp </ url-pattern >
   </ filter-mapping >
   < filter-mapping >
     < filter-name > Set Character Encoding </ filter-name >
     < url-pattern > *.html </ url-pattern >
   </ filter-mapping >
   < filter-mapping >
     < filter-name > Set Character Encoding </ filter-name >
     < url-pattern > *.htm </ url-pattern >
   </ filter-mapping >

的,有用


 <% request.setCharacterEncoding( " GBK " ); %>
的,q有?/p>


 <% @ page contentType = " text/html; charset=GBK "  pageEncoding = " GBK " %>

<meta http-equiv="content-type" content="text/html; charset=GBK">

?q可以用


 <%  String name  =   new  String(request.getParameter( " name " ).getBytes( " 8859_1 " ),  " GB2312 " );  %>

昨天在做项目的q程中,发现用URL传request参数的时候,在第二个面上得Cؕ码的问题。把上面几种Ҏ(gu)都试了一下还是不行。仔l追t了一下,发现在页面的源代码上中文是正常的Q一直到URLq是中文正常Q可是在后台的Action里面log出来成了ؕ码了Q于是猜x在request装的过E中把中文变成ؕ码了Q以致于后台直接是取到的ؕ码。在后台Action中Set入中文,面上正常显C,说明Struts的中文已l不存在问题。剩下的Q应该就只有doGet和doPostҎ(gu)的问题了。找了一下tomcat的配|文Ӟ发现只要在server.xml中:(x)


      <!--  Define a non-SSL HTTP/1.1 Connector on port 8080  -->
     < Connector  port ="8080"  maxHttpHeaderSize ="8192"
               maxThreads ="150"  minSpareThreads ="25"  maxSpareThreads ="75"
               enableLookups ="false"  redirectPort ="8443"  acceptCount ="100"
               connectionTimeout ="20000"  disableUploadTimeout ="true" />
     <!--  Note : To disable connection timeouts, set connectionTimeout value
     to 0  -->
改ؓ(f)


      <!--  Define a non-SSL HTTP/1.1 Connector on port 8080  -->
     < Connector  port ="8080"  maxHttpHeaderSize ="8192"
               maxThreads ="150"  minSpareThreads ="25"  maxSpareThreads ="75"
               enableLookups ="false"  redirectPort ="8443"  acceptCount ="100"
               connectionTimeout ="20000"  disableUploadTimeout ="true"  URIEncoding ="GBK"/>
     <!--  Note : To disable connection timeouts, set connectionTimeout value
     to 0  -->
是加上URIEncoding="GBK"׃事大吉了?br />
再加上一条:(x)

<session-factory>
  <property name="hibernate.connection.url">jdbc:jtds:sqlserver://192.168.0.3:1433;DatabaseName=HomeConsume;charset=GBK</property>
  <property name="hibernate.cglib.use_reflection_optimizer">true</property>
  <property name="hibernate.connection.password">sju</property>
  <property name="hibernate.connection.username">sa</property>
  <property name="hibernate.connection.driver_class">net.sourceforge.jtds.jdbc.Driver</property>
  <property name="hibernate.dialect">org.hibernate.dialect.SQLServerDialect</property>
  <mapping resource="net/magicyang/homeconsume/pojo/Test.hbm.xml" />
  <mapping resource="net/magicyang/homeconsume/pojo/Consumeinfo.hbm.xml" />
  <mapping resource="net/magicyang/homeconsume/pojo/Consumetype.hbm.xml" />
  </session-factory>
xQ应该再困难的ؕ码问题都解决了吧。就是要在页面上、数据库中、request里、doGet、doPostҎ(gu)里面都是中文Q看你还有什么地方躲Q?



java_蝈蝈 2007-01-24 10:00 发表评论
]]>
Java抽象cd接口的区别[转蝲]http://www.tkk7.com/wyz191/articles/95209.htmljava_蝈蝈java_蝈蝈Mon, 22 Jan 2007 00:53:00 GMThttp://www.tkk7.com/wyz191/articles/95209.htmlhttp://www.tkk7.com/wyz191/comments/95209.htmlhttp://www.tkk7.com/wyz191/articles/95209.html#Feedback0http://www.tkk7.com/wyz191/comments/commentRss/95209.htmlhttp://www.tkk7.com/wyz191/services/trackbacks/95209.html abstract class和interface是Java语言中对于抽象类定义q行支持的两U机Ӟ正是׃q两U机制的存在Q才赋予了Java强大的面向对象能力。abstract class和interface之间在对于抽象类定义的支持方面具有很大的怼性,甚至可以怺替换Q因此很多开发者在q行抽象cd义时对于abstract class和interface的选择昑־比较随意。其实,两者之间还是有很大的区别的Q对于它们的选择甚至反映出对于问题领域本质的理解、对于设计意囄理解是否正确、合理。本文将对它们之间的区别q行一番剖析,试图l开发者提供一个在二者之间进行选择的依据。 ?br />
理解抽象c ?br />
abstract class和interface在Java语言中都是用来进行抽象类Q本文中的抽象类q从abstract class译而来Q它表示的是一个抽象体Q而abstract class为Java语言中用于定义抽象类的一U方法,误者注意区分)定义的,那么什么是抽象c,使用抽象c能为我们带来什么好处呢Q ?br />
在面向对象的概念中,我们知道所有的对象都是通过cL描绘的,但是反过来却不是q样。ƈ不是所有的c都是用来描l对象的Q如果一个类中没有包含够的信息来描l一个具体的对象Q这L(fng)cd是抽象类。抽象类往往用来表征我们在对问题领域q行分析、设计中得出的抽象概念,是对一pd看上M同,但是本质上相同的具体概念的抽象。比如:(x)如果我们q行一个图形编辑Y件的开发,׃(x)发现问题领域存在着圆、三角Şq样一些具体概念,它们是不同的Q但是它们又都属于Ş状这样一个概念,形状q个概念在问题领域是不存在的Q它?yu)是一个抽象概c(din)正是因为抽象的概念在问题领域没有对应的具体概念Q所以用以表征抽象概늚抽象cL不能够实例化的。 ?br />
在面向对象领域,抽象cM要用来进行类型隐藏。我们可以构造出一个固定的一l行为的抽象描述Q但是这l行为却能够有Q意个可能的具体实现方式。这个抽象描q就是抽象类Q而这一lQ意个可能的具体实现则表现为所有可能的zcR模块可以操作一个抽象体。由于模块依赖于一个固定的抽象体,因此它可以是不允怿改的Q同Ӟ通过从这个抽象体zQ也可扩展此模块的行为功能。熟(zhn)OCP的读者一定知道,Z能够实现面向对象设计的一个最核心的原则OCP(Open-Closed Principle)Q抽象类是其中的关键所在。 ?br />

从语法定义层面看abstract class和interface  

在语法层面,Java语言对于abstract class和interfacel出了不同的定义方式Q下面以定义一个名为Demo的抽象类Z来说明这U不同。 ?br />
使用abstract class的方式定义Demo抽象cȝ方式如下Q ?br />
abstract class Demo ?jng) ?br /> abstract void method1();  
 abstract void method2();  
 … ?br />} ?br />
使用interface的方式定义Demo抽象cȝ方式如下Q ?br />
interface Demo {  
 void method1();  
 void method2();  
 … ?br />}  

在abstract class方式中,Demo可以有自q数据成员Q也可以有非abstarct的成员方法,而在interface方式的实CQDemo只能够有静态的不能被修改的数据成员Q也是必须是static final的,不过在interface中一般不定义数据成员Q,所有的成员Ҏ(gu)都是abstract的。从某种意义上说Qinterface是一U特DŞ式的abstract class。 ?br />
      从编E的角度来看Qabstract class和interface都可以用来实?design by contract"的思想。但是在具体的用上面还是有一些区别的。 ?br />
首先Qabstract class在Java语言中表C的是一U承关p,一个类只能使用一ơ承关pR但是,一个类却可以实现多个interface。也许,q是Java语言的设计者在考虑Java对于多重l承的支持方面的一U折中考虑吧。 ?br />
其次Q在abstract class的定义中Q我们可以赋予方法的默认行ؓ(f)。但是在interface的定义中Q方法却不能拥有默认行ؓ(f)Qؓ(f)了绕q这个限Ӟ必须使用委托Q但是这?x) 增加一些复杂性,有时?x)造成很大的麻烦。 ?br />
在抽象类中不能定义默认行存在另一个比较严重的问题Q那是可能?x)造成l护上的ȝ。因为如果后来想修改cȝ界面Q一般通过abstract class或者interface来表C)以适应新的情况Q比如,d新的Ҏ(gu)或者给已用的方法中d新的参数Q时Q就?x)非常的ȝQ可能要p很多的时_(d)对于zcd多的情况Q尤为如此)。但是如果界面是通过abstract class来实现的Q那么可能就只需要修改定义在abstract class中的默认行ؓ(f)可以了。 ?br />
同样Q如果不能在抽象cM定义默认行ؓ(f)Q就?x)导致同L(fng)Ҏ(gu)实现出现在该抽象cȝ每一个派生类中,q反?one ruleQone place"原则Q造成代码重复Q同样不利于以后的维护。因此,在abstract class和interface间进行选择时要非常的小心。 ?br />

从设计理念层面看abstract class和interface  

上面主要从语法定义和~程的角度论qCabstract class和interface的区别,q些层面的区别是比较低层ơ的、非本质的。本节从另一个层面:(x)abstract class和interface所反映出的设计理念Q来分析一下二者的区别。作者认为,从这个层面进行分析才能理解二者概늚本质所在。 ?br />
前面已经提到q,abstarct class在Java语言中体C一U承关p,要想使得l承关系合理Q父cdzcM间必d?is a"关系Q即父类和派生类在概忉|质上应该是相同的Q参考文献?〕中有关?is a"关系的大幅深入的论qͼ有兴的读者可以参考)。对于interface 来说则不Ӟq不要求interface的实现者和interface定义在概忉|质上是一致的Q仅仅是实现了interface定义的契U而已。ؓ(f)了便于理解Q下面将通过一个简单的实例q行说明。 ?br />
考虑q样一个例子,假设在我们的问题领域中有一个关于Door的抽象概念,该Doorh执行两个动作open和closeQ此时我们可以通过abstract class或者interface来定义一个表C抽象概念的类型,定义方式分别如下所C:(x)  

使用abstract class方式定义DoorQ ?br />
abstract class Door {  
 abstract void open();  
 abstract void close()Q ?br />}  

   
使用interface方式定义DoorQ ?br />

interface Door {  
 void open();  
 void close();  
}  

   
其他具体的Doorcd可以extends使用abstract class方式定义的Door或者implements使用interface方式定义的Door。看h好像使用abstract class和interface没有大的区别。 ?br />
如果现在要求Doorq要h报警的功能。我们该如何设计针对该例子的cȝ构呢Q在本例中,主要是ؓ(f)了展Cabstract class和interface反映在设计理念上的区别,其他斚w无关的问题都做了化或者忽略)Q下面将|列出可能的解决Ҏ(gu)Qƈ从设计理念层面对q些不同的方案进行分析。 ?br />
解决Ҏ(gu)一Q ?br />
单的在Door的定义中增加一个alarmҎ(gu)Q如下:(x)  

abstract class Door {  
 abstract void open();  
 abstract void close()Q ?br /> abstract void alarm();  
}  

   
或者 ?br />
interface Door {  
 void open();  
 void close();  
 void alarm();  
}  

   
那么h报警功能的AlarmDoor的定义方式如下:(x)  

class AlarmDoor extends Door {  
 void open() { … }  
 void close() { … }  
 void alarm() { … }  
}  

   
或者 ?br />
class AlarmDoor implements Door ?jng) ?br /> void open() { … }  
 void close() { … }  
 void alarm() { … }  
} ?br />
q种Ҏ(gu)q反了面向对象设计中的一个核心原则ISPQInterface Segregation PricipleQ,在Door的定义中把Door概念本n固有的行为方法和另外一个概?报警?的行为方法؜在了一赗这样引L(fng)一个问题是那些仅仅依赖于Doorq个概念的模块会(x)因ؓ(f)"报警?q个概念的改变(比如Q修改alarmҎ(gu)的参敎ͼ而改变,反之依然。 ?br />
解决Ҏ(gu)二:(x)  

既然open、close和alarm属于两个不同的概念,Ҏ(gu)ISP原则应该把它们分别定义在代表q两个概늚抽象cM。定义方式有Q这两个概念都用abstract class方式定义Q两个概念都使用interface方式定义Q一个概念用abstract class方式定义Q另一个概念用interface方式定义。 ?br />
昄Q由于Java语言不支持多重承,所以两个概念都使用abstract class方式定义是不可行的。后面两U方式都是可行的Q但是对于它们的选择却反映出对于问题领域中的概念本质的理解、对于设计意囄反映是否正确、合理。我们一一来分析、说明。 ?br />
如果两个概念都用interface方式来定义,那么反映出两个问题Q?、我们可能没有理解清楚问题领域,AlarmDoor在概忉|质上到底是Doorq是报警器?2、如果我们对于问题领域的理解没有问题Q比如:(x)我们通过对于问题领域的分析发现AlarmDoor在概忉|质上和Door是一致的Q那么我们在实现时就没有能够正确的揭C我们的设计意图Q因为在q两个概늚定义上(均用interface方式定义Q反映不Zq含义。 ?br />
如果我们对于问题领域的理解是QAlarmDoor在概忉|质上是DoorQ同时它有具有报警的功能。我们该如何来设计、实现来明确的反映出我们的意思呢Q前面已l说q,abstract class在Java语言中表CZU承关p,而承关pd本质上是"is a"关系。所以对于Doorq个概念Q我们应该用abstarct class方式来定义。另外,AlarmDoor又具有报警功能,说明它又能够完成报警概念中定义的行ؓ(f)Q所以报警概念可以通过interface方式定义。如下所C:(x)  

abstract class Door {  
 abstract void open();  
 abstract void close()Q ?br />}  
interface Alarm {  
 void alarm();  
}  
class AlarmDoor extends Door implements Alarm {  
 void open() { … }  
 void close() { … }  
    void alarm() { … }  
}  

   
q种实现方式基本上能够明的反映出我们对于问题领域的理解Q正的揭示我们的设计意图。其实abstract class表示的是"is a"关系Qinterface表示的是"like a"关系Q大家在选择时可以作Z个依据,当然q是建立在对问题领域的理解上的,比如Q如果我们认为AlarmDoor在概忉|质上是报警器Q同时又hDoor的功能,那么上述的定义方式就要反q来了?/font>


java_蝈蝈 2007-01-22 08:53 发表评论
]]>
多反向代理[Squid]下获取客L(fng)真实IP地址 http://www.tkk7.com/wyz191/articles/93624.htmljava_蝈蝈java_蝈蝈Sat, 13 Jan 2007 10:03:00 GMThttp://www.tkk7.com/wyz191/articles/93624.htmlhttp://www.tkk7.com/wyz191/comments/93624.htmlhttp://www.tkk7.com/wyz191/articles/93624.html#Feedback0http://www.tkk7.com/wyz191/comments/commentRss/93624.htmlhttp://www.tkk7.com/wyz191/services/trackbacks/93624.html在很多应用下都可能有需要将用户的真实IP记录下来Q这时就要获得用L(fng)真实IP地址Q在JSP里,获取客户端的IP地址的方法是Q?strong>request.getRemoteAddr()Q这U方法在大部分情况下都是有效的。但是在通过了Apache,Squid{反向代理Y件就不能获取到客L(fng)的真实IP地址了?br />
  q段旉在做IPl计的程序设计,׃服务器作了集,使用了反向代理YӞ?/font> http://192.168.1.110:2046/ 的URL反向代理?/font> http://www.xxx.com/ 的URLӞ?strong>request.getRemoteAddr()Ҏ(gu)获取的IP地址是:(x)127.0.0.1 或 192.168.1.110Q而ƈ不是客户端的真实QP。这是什么原因呢Q?br />
  q是反向代理的原因。经q代理以后,׃在客L(fng)和服务之间增加了中间层,因此服务器无法直接拿到客L(fng)的IPQ服务器端应用也无法直接通过转发h的地址q回l客L(fng)。但是在转发h的HTTP头信息中Q增加了XQFORWARDEDQFOR信息。用以跟t原有的客户端IP地址和原来客L(fng)h的服务器地址。当我们讉K
http://www.xxx.com/index.jsp/ Ӟ其实q不是我们浏览器真正讉KC服务器上的index.jsp文gQ而是先由代理服务器去讉K http://192.168.1.110:2046/index.jsp Q代理服务器再将讉K到的l果q回l我们的览器,因ؓ(f)是代理服务器去访问index.jsp的,所以index.jsp中通过request.getRemoteAddr()的方法获取的IP实际上是代理服务器的地址Qƈ不是客户端的IP地址?br />
  于是可得得客L(fng)真实IP地址的方法一Q?br />
1   public  String getIpAddr(HttpServletRequest request)  {
2       String ip  =  request.getHeader( " x-forwarded-for "
);
3        if (ip  ==   null   ||  ip.length()  ==   0
{
4             ip  =
 request.getRemoteAddr();
5         }

6          return  ip;
7     }

  可是当我讉K http://www.xxx.com/index.jsp/ Ӟq回的IP地址始终是unknownQ也q不是如上所C的127.0.0.1 或 192.168.1.110了,而我讉K http://192.168.1.110:2046/index.jsp Ӟ则能q回客户端的真实IP地址Q写了个Ҏ(gu)去验证?br />
  
 1 <% @ page import = " java.util.* "   %>
 2 < table  border =1  cellspacing =0  cellpadding =0  align =center >  
 3 < tr >
 
 4 < th > Name </ th >
 
 5 < th > Value </ th >
 
 6 </ tr >
 
 7 <%
 
 8
Enumeration enumNames; 
 9 String
 strName,strValue; 
10

11 enumNames  =
 request.getHeaderNames(); 
12 while
(enumNames.hasMoreElements()){ 
13     strName  =  ( String
)enumNames.nextElement(); 
14     strValue  =
 request.getHeader(strName); 
15     
%>  
16      < tr >
 
17      < td > <% = strName %> </ td >
 
18      < td > <% = strValue %> </ td >
 
19      </ tr >
 
20      <%
 
21

22
%>
23 < tr >
24 </ table >
25


  出来的结果:(x)X-Forwarded-For: unknown 。X-Forwarded-For实存在Q但其值却为unknownQl找原因。上|搜了搜Q原因出在了Squid上?br />
squid.conf 的配制文件 forwarded_for w认是为onQ如?forwarded_for 设成?off  则:(x)

X-Forwarded-For: unknown

一查,发现forwarded_for 设ZoffQ原因找CQ把forwarded_for 设ZonQ重启后Q访?/font> http://www.xxx.com/index.jsp/  获得的IP是客L(fng)的真实IP?br />
  于是可得得客L(fng)真实IP地址的方法二Q?br />
 1      public  String getIpAddr(HttpServletRequest request)  {
 2         String ip  =  request.getHeader( " x-forwarded-for "
);
 3          if (ip  ==   null   ||  ip.length()  ==   0   ||   " unknown " .equalsIgnoreCase(ip)) 
{
 4             ip  =  request.getHeader( " Proxy-Client-IP "
);
 5         }

 6          if (ip  ==   null   ||  ip.length()  ==   0   ||   " unknown " .equalsIgnoreCase(ip))  {
 7             ip  =  request.getHeader( " WL-Proxy-Client-IP "
);
 8         }

 9          if (ip  ==   null   ||  ip.length()  ==   0   ||   " unknown " .equalsIgnoreCase(ip))  {
10             ip  =
 request.getRemoteAddr();
11         }

12          return  ip;
13     }

14



  可是Q如果通过了多U反向代理的话,X-Forwarded-For的值ƈ不止一个,而是一Ԍp|I竟哪个才是真正的用L(fng)的真实IP呢?

  {案是取X-Forwarded-For中第一个非unknown的有效IP字符丌Ӏ?br />
  如:(x)
  X-Forwarded-ForQ?92.168.1.110, 192.168.1.120, 192.168.1.130, 192.168.1.100
  用户真实IP为:(x) 192.168.1.110



java_蝈蝈 2007-01-13 18:03 发表评论
]]>
JFreeChart在JSP中的应用实例 [转]http://www.tkk7.com/wyz191/articles/jfreechart.htmljava_蝈蝈java_蝈蝈Sat, 13 Jan 2007 09:48:00 GMThttp://www.tkk7.com/wyz191/articles/jfreechart.htmlhttp://www.tkk7.com/wyz191/comments/93623.htmlhttp://www.tkk7.com/wyz191/articles/jfreechart.html#Feedback0http://www.tkk7.com/wyz191/comments/commentRss/93623.htmlhttp://www.tkk7.com/wyz191/services/trackbacks/93623.html阅读全文

java_蝈蝈 2007-01-13 17:48 发表评论
]]>
վ֩ģ壺 ɫƵۿ| ѳ˸Ƶ| ޹ƷȾþ| ձһ| ĻmvѸƵ8| ŮƵaŮȫƤ| þþƷ99Ʒ| պvĻ| һëƬֱ| ŷ߿ƬAѹۿ| 97ԭѹۿ| йvideosԸ| ëƬһ| AV߹ۿ| һӰ| 㽶þþƷ| ޾ƷۺϾþ| av߹ۿһ| ëƬƵa| վ| 67194Ʒѹۿ| Ůcaoվѿ߿| ˿wwwƵ| ůůձ| ëƬһ| Ʒþһ| Ļ| һ߹ۿ| þþƷav| þۺպ޾Ʒɫ| Ļ޵һ| 뾫Ʒ˳| ޹Ʒպ| www.ɫͼ.com| ޳˾þ| ۺ뾫Ʒһ| ŮƷþþ| Ļþи| ëƬ޾Ʒ| ޾Ʒɫҹרպ| avۺavav|