paulwong

#

進銷存系統有幾個資料庫?

我在教授 軟體設計課程,尤其是以使用案例圖在說明架構設計時,每一個用套件(Package)所界定範圍的系統,係指軟體應用系統,但卻幾乎不會談及到資料庫。因 為,軟體應用系統與資料庫是兩個不同的層次,甚至,把資料庫視為是應用系統的 "私有倉儲(private storage)",會比較恰當。


不過,這衍生出一個問題,學員不容易分清楚如何 "mapping" 抽象面的架構設計至實體的 IT 系統,尤其是資料庫的問題。所以,我會先帶一個問題問學員:在設計層次的考量中,進銷存系統有幾個資料庫?


這一個問題要能回答得出來,其假設前提的考量必須要瞭解,在整體的架構設計中,設計團隊到底將 "進銷存" 視為是一個,還是三個,甚至多個的子系統?


參考下圖1,這是把 "進銷存" 視為是單一的系統,所以,資料庫只有一個。


好處是什麼? 就是簡單,開發也容易。進銷存相關的資訊處理,都是在同一個資料庫內,並沒有分散的問題,所以當處理銷貨需要查詢庫存資訊時,只要下 SQL 敘述直接連結庫存的 TABLE 即可。



圖1、將進銷存視為一個整體系統


參考下圖2,架構設計之初時,就已把 "進銷存" 分為三個子系統(Sub-system),或者也可以稱之為元件(Component),以凸顯子系統之間的溝通,是透過介面(Interface)的呼 叫。其實,論子系統的範圍與規模,稱為 "模組(Module)" 更為適合,不過,我個人並不喜歡以 "模組" 二字來稱之,因為,這個術語被業界給濫用了,已淪落為在業務面的術語,卻並沒有在實體的系統間,嚴格遵循透過介面的呼叫。


所以圖2,有三個資料庫。


當銷貨人員處理銷貨需要查詢庫存資訊時,需要透過庫存系統所提供的介面來呼叫,介面的實做可能是 "Web Service"、"Java Bean"、"Session Bean"、"COM+" 等,但絕對不能直接下 SQL 來呼叫位於庫存系統內的資料庫,否則,就違背了圖2的整體架構設計。不遵循整體架構設計的規範,私自偷偷連接,稱之為 "跳線"。



圖2、將進銷存分成三個獨立的子系統

上圖2的抽象設計與IT面的實做技術,比較困難,也需要花較多成本,以專案為主(Project-based)的開發,時程短、預算 低廉,不容易達成圖2的設計目標。但若重覆性的專案,專注在進銷存這個領域上,有豐富足夠的領域知識(Domain Knowledge),且打算產品化(Product),那麼,圖2的系統架構來得有彈性很多,"進"、"銷"、"存" 三個子系統(元件),均可以隨意抽換,各自更新或改版,而不會影響到另一個子系統,如同 PC 主機板內的硬體元件,可以造成 "PnP(Plug and Play)" 的效果。


請注意,上述問題的提問,會有幾個資料庫,是指抽象的邏輯設計層面,可千萬不要與實體的資料庫混為一 談。例如,圖2雖然需要三個資料庫,但若以 Oracle 資料庫系統,DBA 可以將邏輯層面的三個資料庫,切分為三個 "TABLE SPACE",然後放在同一個實體的 Oracle 資料庫系統內;而若是 MS SQL 或是 MySQL,則是切割為三個 "database",放入同一個實體資料庫系統內。


當然,若有地理位置或資料庫系統負載的問題,要分散至多個實體的資料庫系統,那也沒問題。例如,進銷存位於三個地點不同的廠,各自配置了三個實體資料庫,各自存放自己的資訊。這也是圖2架構設計的優點,一切分合自如!


e 化的系統設計,即使是 ERP 如此重視資料存取與處理的系統,應該要能摒除傳統以資料庫為中心的設計觀點,因為,系統整體的彈性度會不佳,很難應變需求面的頻繁變更,或是 IT 實體平台,包括資料庫系統的變更等。設計重心應該要轉移至 "Middleware",這個術語可能太貼近 IT 平台面了,倒不如乾脆這麼說,設計的重心就是回歸至以 "應用系統" 為主,是觀察應用系統可以提供那些服務(services)或功能(functions),這些服務與功能其實就是系統一個個可以量化的子目標(Sub- goal),次一步驟才是考量如何取得要能達成這些子目標的資訊(資料),要取得資訊,就是到實體的倉儲,也就是私有的資料庫系統去找,或是,透過標準的 程序,也就是透過標準的介面,至外部系統取得相關的資訓來處理。

posted @ 2006-06-17 09:57 paulwong 阅读(430) | 评论 (0)编辑 收藏

tomcat支持中文名的处理方式

在server.xml配置文件中,增加URIEncoding=GBK"

<Connector port="8080"
               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 
-->

posted @ 2006-06-11 17:52 paulwong 阅读(228) | 评论 (0)编辑 收藏

华为公司 java 面试题

第一部分:选择题
QUESTION NO: 1
1、


public   class  Test {
    
public   static   void  changeStr(String str){
        str
= " welcome " ;
    }
    
public   static   void  main(String[] args) {
        String str
= " 1234 " ;
        changeStr(str);
        System.out.println(str);
    }
}

Please write the output result :

QUESTION NO:2

1public class Test {
2static boolean foo(char c) {
3. System.out.print(c);
4return true;
5. }
6public static void main( String[] argv ) {
7int i =0;
8for ( foo('A'); foo('B')&&(i<2); foo('C')){
9. i++ ;
10. foo('D');
12. }
13. }
14. }


What is the result?
A. ABDCBDCB
B. ABCDABCD
C. Compilation fails.
D. An exception is thrown at runtime.


QUESTION NO: 3

1class A {
2protected int method1(int a, int b) { return 0; }
3. }

Which two are valid in a class that extends class A? (Choose two)
A. public int method1(int a, int b) { return 0; }
B. private int method1(int a, int b) { return 0; }
C. private int method1(int a, long b) { return 0; }
D. public short method1(int a, int b) { return 0; }
E. static protected int method1(int a, int b) { return 0; }

QUESTION NO: 4

1public class Outer{
2public void someOuterMethod() {
3// Line 3
4. }
5public class Inner{}
6public static void main( String[]argv ) {
7. Outer o = new Outer();
8// Line 8
9. }
10. }

Which instantiates an instance of Inner?
A. new Inner(); // At line 3
B. new Inner(); // At line 8
C. new o.Inner(); // At line 8
D. new Outer.Inner(); // At line 8//new Outer().new Inner()

QUESTION NO: 5
Which method is used by a servlet to place its session ID in a URL that is written to the servlet’s response output stream?
A. The encodeURL method of the HttpServletRequest interface.
B. The encodeURL method of the HttpServletResponse interface.
C. The rewriteURL method of the HttpServletRequest interface.
D. The rewriteURL method of the HttpServletResponse interface.


QUESTION NO: 6
Which two are equivalent? (Choose two)
A. <%= YoshiBean.size%>
B. <%= YoshiBean.getSize()%>
C. <%= YoshiBean.getProperty("size")%>
D. <jsp:getProperty id="YoshiBean" param="size"/>
E. <jsp:getProperty name="YoshiBean" param="size"/>
F. <jsp:getProperty id="YoshiBean" property="size"/>
G. <jsp:getProperty name="YoshiBean" property="size"/>


QUESTION NO: 7
Which of the following statements regarding the lifecycle of a session bean are correct?
1.  java.lang.IllegalStateException is thrown if SessionContext.getEJBObject() is invoked when a stateful session bean instance is passivated.
2.  SessionContext.getRollbackOnly() does not throw an exception when a session bean with bean-managed transaction demarcation is activated.
3.  An exception is not thrown when SessionContext.getUserTransaction() is called in the afterBegin method of a bean with container-managed transactions.
4.  JNDI access to java:comp/env is permitted in all the SessionSynchronization methods of a stateful session bean with container-managed transaction demarcation.
5.  Accessing resource managers in the SessionSynchronization.afterBegin method of a stateful session bean with bean-managed transaction does not throw an exception.


第二部分:概念题
1.    描述Struts体系结构?对应各个部分的开发工作主要包括哪些?

 

2.    XML包括哪些解释技术,区别是什么?

 


3.    JSP有哪些内置对象和动作?它们的作用分别是什么?

 


4、SQL问答题
SELECT * FROM TABLE

SELECT * FROM TABLE
WHERE NAME LIKE '%%' AND ADDR LIKE '%%'
AND (1_ADDR LIKE '%%' OR 2_ADDR LIKE '%%'
OR 3_ADDR LIKE '%%' OR 4_ADDR LIKE '%%' )
的检索结果为何不同?

 

5、SQL问答题
表结构:
1、    表名:g_cardapply
字段(字段名/类型/长度):
g_applyno        varchar   8;//申请单号(关键字)
g_applydate     bigint     8;//申请日期
g_state        varchar     2;//申请状态

2、    表名:g_cardapplydetail
字段(字段名/类型/长度):
g_applyno        varchar     8;//申请单号(关键字)
g_name        varchar     30;//申请人姓名
g_idcard        varchar     18;//申请人身份证号
g_state        varchar     2;//申请状态

其中,两个表的关联字段为申请单号。

题目:
1、    查询身份证号码为440401430103082的申请日期

2、    查询同一个身份证号码有两条以上记录的身份证号码及记录个数

3、    将身份证号码为440401430103082的记录在两个表中的申请状态均改为07

4、    删除g_cardapplydetail表中所有姓李的记录

posted @ 2006-05-21 18:46 paulwong 阅读(2671) | 评论 (2)编辑 收藏

世界杯赛事时间表

世界杯赛事时间表:


posted @ 2006-05-21 16:18 paulwong 阅读(967) | 评论 (1)编辑 收藏

自定义集合中的排序

1、先自定义Comparator


//    对象的比较器,如1.1.1<1.2.1<1.11.1<1.1.1.1
    public final class LcsjMapComparator implements Comparator
    {

        
        
public int compare(Object arg0, Object arg1) {
            GdnkVO_Lcsj_Map vo1
=(GdnkVO_Lcsj_Map)arg0;
            GdnkVO_Lcsj_Map vo2
=(GdnkVO_Lcsj_Map)arg1;
            String[] flowCode1
=vo1.getFlowCode().trim().split("\\.");
            String[] flowCode2
=vo2.getFlowCode().trim().split("\\.");

            
for(int i=0;i<2;i++)
            {
                
if(Integer.parseInt(flowCode1[i])<Integer.parseInt(flowCode2[i]))
                    
return -1;
                
else if(Integer.parseInt(flowCode1[i])>Integer.parseInt(flowCode2[i]))
                    
return 1;
            }
            
return 0;
        }
        
    }    


compare方法中的对象类型必须是集合中的元素的数据类型。

排在后面的返回1,排在前面的返回-1,相同顺序的返回0。


2、使用


Comparator lcsjComparator=new LcsjMapComparator();
Collections.sort(lcsjList,lcsjComparator);


即可得到排好序的集合。

posted @ 2006-05-19 11:33 paulwong 阅读(217) | 评论 (0)编辑 收藏

JSP技巧篇---字符串日期格式转换

有一些网友问我字符串转日期或日期转字符串要如何做,本来已经在留言板回答了,但觉得似乎有满多的网友有这种困扰,因此我把它整理整理贴出来。


在这篇文章中,我用的API是SimpleDateFormat,它是属于java.text.SimpleDateFormat,所以请记得import进来!


用法:


SimpleDateFormat sdf  =   new  SimpleDateFormat( " yyyy-MM-dd HH:mm:ss " ); 

这一行最重要,它确立了转换的格式,yyyy是完整的公元年,MM是月份,dd是日期,至于HH:mm:ss就不需要我再解释了吧!


ps:为什么有的格式大写,有的格式小写,那是怕避免混淆,例如MM是月份,mm是分;HH是24小时制,而hh是12小时制

1.字符串转日期:

 
2002-10-8 15:30:22要把它转成日期,可以用


Date date = sdf.parse( " 2002-10-8 15:30:22 " );

2.日期转字符串


假如把今天的日期转成字符串可用


String datestr = sdf.format( new  Date()); 

 这个字符串的内容便类似2002-10-08 14:55:38


透过这个API我们便可以随心所欲的将日期转成我们想要的字符串格式,例如希望将日期输出成2002年10月08日


我们可以这么写:


SimpleDateFormat sdf  =   new  SimpleDateFormat( " yyyy年MM月dd日 " );
    String datestr
= sdf.format( new  Date()); 


datestr便会依照我们设定的格式输出

posted @ 2006-05-18 22:07 paulwong 阅读(488) | 评论 (0)编辑 收藏

在Tomcat中使用连接池

以Oracle + Tomcat 5.0为例:

1.配置server.xml

<Resource name="jdbc/myoracle" auth="Container"
              type
="javax.sql.DataSource"/> 

<ResourceParams name="jdbc/myoracle">
  
<parameter>
    
<name>factory</name>
    
<value>org.apache.commons.dbcp.BasicDataSourceFactory</value>
  
</parameter>
  
<parameter>
    
<name>driverClassName</name>
    
<value>oracle.jdbc.driver.OracleDriver</value>
  
</parameter>
  
<parameter>
    
<name>url</name>
    
<value>jdbc:oracle:thin:myschema@127.0.0.1:1521:mysid</value>
  
</parameter>
  
<parameter>
    
<name>username</name>
    
<value>scott</value>
  
</parameter>
  
<parameter>
    
<name>password</name>
    
<value>tiger</value>
  
</parameter>
  
<parameter>
    
<name>maxActive</name>
    
<value>20</value>
  
</parameter>
  
<parameter>
    
<name>maxIdle</name>
    
<value>10</value>
  
</parameter>
  
<parameter>
    
<name>maxWait</name>
    
<value>-1</value>
  
</parameter>
</ResourceParams>

2.配置web.xml

在</web-app>节点下加下面信息:

<resource-ref>
 
<description>Oracle Datasource example</description>
 
<res-ref-name>jdbc/myoracle</res-ref-name>
 
<res-type>javax.sql.DataSource</res-type>
 
<res-auth>Container</res-auth>
</resource-ref>

3.测试的代码

Context initContext = new InitialContext();
Context envContext  
= (Context)initContext.lookup("java:/comp/env");
DataSource ds 
= (DataSource)envContext.lookup("jdbc/myoracle");
Connection conn 
= ds.getConnection();
//etc.

posted @ 2006-05-18 22:00 paulwong 阅读(138) | 评论 (0)编辑 收藏

如何在JAVA中使用日期

如果想要取得系统的时间,可以使用System.currentTimeMillis()方法,例如:

DateDemo.java

1 public class DateDemo {
2     public static void main(String[]args) {
3         System.out.println(System.currentTimeMillis());
4     }
5}

执行结果会显示从1970年1月1日开始到取得系统时间为止所经过的毫秒数,例如1115346430703这个数字,但这样的数字没有人确切了解它的意 义是什么,您可以使用Date类别来让这个数字变的更有意义一些,例如:

DateDemo.java

import java.util.Date;

public class DateDemo {
    
public static void main(String[]args) {
        Date date 
= new Date();                    
        System.out.println(date.toString());
        System.out.println(date.getTime());
    }
}

执行的结果如下:

  Fri May 06 10:31:13 GMT+08:00 2005
  1115346673531

当您生成Date对象时,实际上它会使用System.currentTimeMillis()来取得系统时间,而您使用
toString()方法时,会将取得的1970年1月1日至今的毫秒数转为dow mon dd hh:mm:ss zzz yyyy的格式,分别是:「星期 月 日 时:分:秒 公元」;使用Date的getTime()方法则可以取得毫秒数。

如果您想要对日期时间作格式设定,则可以使用DateFormat来作格式化,先来看看它的子类SimpleDateFormat如何使用:

DateDemo.java
   
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;

public class DateDemo {
    
public static void main(String[]args) {
        Date date 
= new Date();
        DateFormat dateFormat 
= new  SimpleDateFormat("EE-MM-dd-yyyy");
        System.out.println(dateFormat.format(date));
    }
}

执行结果:

     星期五-05-06-2005

DateFormat会依计算机上的区域设定显示时间格式,EE表示星期,MM表示月份、dd表示日期,而yyyy是公元,每个字符的设定都各有其意义,您
可以参考 SimpleDateFormat 的API说明了解每个字符设定的意义。

您也可以直接从DateFormat指定格式生成DateFormat的实例,例如:

DateDemo.java
   

import java.text.DateFormat;
import java.util.Date;

public class DateDemo {
    
public static void main(String[] args) {
        Date date 
= new Date();
        DateFormat shortFormat 
=  DateFormat.getDateTimeInstance(DateFormat.SHORT,
DateFormat.SHORT);
        DateFormat mediumFormat 
= DateFormat.getDateTimeInstance(DateFormat.MEDIUM,DateFormat.MEDIUM);
        DateFormat longFormat 
= DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG);
        DateFormat fullFormat 
= DateFormat.getDateTimeInstance(DateFormat.FULL,DateFormat.FULL);
        System.out.println(shortFormat.format(date));
        System.out.println(mediumFormat.format(date));
        System.out.println(longFormat.format(date));
        System.out.println(fullFormat.format(date));
    }
}

在使用getDateTimeInstance()取得DateFormat实例时,可以指定的参数是日期格式与时间格式,以上所指定的格式依讯息详细度 区分,执行结果如下:

  

2005/5/6 上午 10:45
2005/5/6 上午 10:45:25
2005年5月6日 上午10时45分25秒
2005年5月6日 星期五 上午10时45分25秒 GMT+08:00

  
您也可以使用getDateInstance()取得DateFormat实 例,并同时指定日期的区域显示方式,例如:

DateDemo.java

import java.text.DateFormat;
import java.util.Date;
import java.util.Locale;

public class DateDemo {
    
public static void main(String[] args) {
        Date date 
= new Date();
        Locale locale 
= new Locale("en""US");
        DateFormat shortFormat 
=  DateFormat.getDateInstance(DateFormat.SHORT,locale);
        DateFormat mediumFormat 
= DateFormat.getDateInstance(                DateFormat.MEDIUM,locale);
        DateFormat longFormat 
= DateFormat.getDateInstance(DateFormat.LONG, locale);
        DateFormat fullFormat 
= DateFormat.getDateInstance(DateFormat.FULL, locale);
        System.out.println(shortFormat.format(date));
        System.out.println(mediumFormat.format(date));
        System.out.println(longFormat.format(date));
        System.out.println(fullFormat.format(date));
    }
}

这边指定了美国的时间显示方式,执行结果如下:

  5/6/05
  May 6, 2005
  May 6, 2005
  Friday, May 6, 2005

posted @ 2006-05-18 22:00 paulwong 阅读(423) | 评论 (0)编辑 收藏

JSP技巧篇---防止浏览器快取网页

浏 览器为了加速使用者的浏览速度,常会将浏览过的网页快取到硬盘,下次浏览同一页时,便去硬盘里面去找,但现在的网页常是动态的,为了避免使用者抓到硬盘内 过期的数据,JSP可用下面的方式来防止浏览器快取住网页,此方法便可保证使用者到这个网页时始终都可看到最新的资料。


1.JSP语法


<%

        response.setHeader(
" Pragma " , " no-cache " );

        response.setHeader(
" Cache-Control " , " no-cache " );

        response.setDateHeader(
" Expires " , 0 );

    %>



2.也可以用以下的HTML语法,可用在静态网页上


< meta http - equiv  =   " Pragma "  content = " no-cache " >

    < meta http - equiv = " Cache-Control "  content = " no-cache " >

    < meta http - equiv  =   " Expires "  content = " 0 " >


注意,这些HTML语法要下在<head></head>的标签内。

posted @ 2006-05-18 21:58 paulwong 阅读(160) | 评论 (0)编辑 收藏

AJAX 上手篇

AJAX 上手篇

第一步 – 说声「请」 (又称为「怎么发出 XMLHttpRequest」)

为了用 JavaScript 对服务器发送 HTTP 要求,你必须先以相关的类别(class)制出实体(instance)。Internet
Explorer 首先以 ActiveX 对象方式提供 XMLHTTP 类别,而 Mozilla、Safari及其它浏览器则随后以 XMLHttpRequest 类别支持此 ActiveX 对象中的类别及属性。


因此,如果想跨浏览器,那么可以这么写: 


if  (window.XMLHttpRequest) {  //  Mozilla, Safari, 

    http_request 
=   new  XMLHttpRequest();

else   if  (window.ActiveXObject) {  //  IE

    http_request 
=   new  ActiveXObject( " Microsoft.XMLHTTP " );

}


(由于这段程序仅供说明,所以是采最简方式写出。本文第三步中有另一种我们比较常用的写法。)

有些版本的 Mozilla 浏览器在服务器送回的数据未含 XML mime-type 文件头(header)时会出错。为了避免这个问题,你可以用下列方法覆写服务器传回的档头,以免传回的不是text/xml


http_request  =   new  XMLHttpRequest();

http_request.overrideMimeType('text
/ xml');


接下来是要决定服务器传回资料后的处理方式,此时你只要以 onreadystatechange 这个属性指明要处理传回值的
JavaScript 函式名称即可,例如:


http_request.onreadystatechange  =  nameOfTheFunction;

注意,指定的函式名称后不加括号也没有参数。除了指定函式名称外,你也能用 Javascript 实时定义函式的方法来定一个新的处理函式,如下:


http_request.onreadystatechange  =   function (){

    
//  做些事

};


决定处理方式之后你得确实发出 request,此时需叫用 HTTP request 类别的 open()send() 方法,如下:


http_request.open('GET', 'http: // www.example.org/some.file', true);
http_request.send( null );

  • open() 的第一个参数是
         HTTP request 的方法,也就是从
         GET、POST、HEAD 中择一使用,亦可用你主机上支持的方式。为遵循 HTTP 标准,请记得这些方法都是大写,不然有的浏览器(如 Firefox)或许不会理你。其它 HTTP request 可以支持的方法列表请参考
         W3C 规格书 (http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html)。
  • 第二个参数是目标 URL。基于安全考虑,你不能叫用同网域以外的网页。如果网域不同,则叫用
         open() 时会出现「权限不足,拒绝存取」那类的错误。通常大伙会犯的错误多为在 domain.tld 网的网站下呼叫 www.domain.tld 中的网页,仅是一点点差别都不行。
        
  • 第三个参数决定此 request 是否不同步进行,如果设定为
         TRUE 则即使服务器尚未传回数据也会继续执行其余的程序,这也就是 AJAX 中第一个 A 代表的意义。

send() 的参数在以 POST 发出 request 时可以是任何想传给服务器的东西,而数据则以查询字符串的方式列出,例如:

 

name = value & anothername = othervalue & so = on

不过如果你想要以 POST 方式传送数据,则必须先将 MIME 型态改好,如下:

				


http_request.setRequestHeader('Content
-
Type', 'application
/
x
-
www
-
form
-
urlencoded');







否则服务器就不会理你传过来的数据了。

第二步 – 「就上咩!」(又称为「处理服务器传回的数据」)

传出 request 时必须提供处理传回值的函式名称。

http_request.onreadystatechange  =  nameOfTheFunction;

////////////////////////////////////////////////////////////////////
//但是,FireFox 对onreadyStateChange没有反应,怎么办,这个方法不能用在
//FireFox 中,有没有其它的方法?
//      Added by www.besook.com 2006-03-19
//////////////////////////////////////////////////////////////

那么来看看这个函式该做些什么。首先,它必须检查 request 目前的状态:如果状态值为 4 代表服务器已经传回所有信息了,便可以开始解析所得信息。


if  (http_request.readyState  ==   4 ) {

    
//  一切 ok, 继续解析

else  {

    
//  还没完成

}


readyState 所有可能的值如下:

  • 0 (还没开始)
  • 1 (读取中)
  • 2 (已读取)
  • 3 (信息交换中)
  • 4 (一切完成)

(资料来源: MSDN (http://msdn.microsoft.com/workshop/author/dhtml/reference/properties/readystate_1.asp))

接下来要检查服务器传回的 HTTP 状态码。所有状态码列表可于 W3C
网站
(http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html)上查到,但我们要管的是200 OK 这种状态。


if  (http_request.status  ==   200 ) {

    
//  万事具备

else  {

    
//  似乎有点问题,或许服务器传回了 404 (查无此页) 或者 500 (内部错误) 什么的

}



检查传回的 HTTP 状态码后,要怎么处理传回的数据就由你决定了。有两种存取数据的方式:

  • http_request.responseText – 这样会把传回值当字符串用
        
  • http_request.responseXML – 这样会把传回值视为
         XMLDocument 对象,而后可用
         JavaScript DOM 相关函式处理

第三步 - 万事俱备 - 简单范例

好,接着就做一次简单的 HTTP 范例,演示方才的各项技巧。这段 JavaScript 会向服务器要一份里头有「I'm
a test.」字样的 HTML 文件(test.html),而后以 alert() 将文件内容列出。


< script type = " text/javascript "  language = " javascript " >

    
var  http_request  =   false ;

    
function  makeRequest(url) {

        http_request 
=   false ;

        
if  (window.XMLHttpRequest) {  //  Mozilla, Safari,

            http_request 
=   new  XMLHttpRequest();

            
if  (http_request.overrideMimeType) {

                http_request.overrideMimeType('text
/ xml');

            }

        } 
else   if  (window.ActiveXObject) {  //  IE

            
try  {

                http_request 
=   new  ActiveXObject( " Msxml2.XMLHTTP " );

            } 
catch  (e) {

                
try  {

                    http_request 
=   new  ActiveXObject( " Microsoft.XMLHTTP " );

                } 
catch  (e) {}

            }

        }

        
if  ( ! http_request) {

            alert('Giving up :( Cannot create an XMLHTTP instance');

            
return   false ;

        }

        http_request.onreadystatechange 
=  alertContents;

        http_request.open('GET', url, 
true );

        http_request.send(
null );

    }

    
function  alertContents() {

        
if  (http_request.readyState  ==   4 ) {

            
if  (http_request.status  ==   200 ) {

                alert(http_request.responseText);

            } 
else  {

                alert('There was a problem 
with  the request.');

            }

        }

    }

</ script >

< span

    style
= " cursor: pointer; text-decoration: underline "

    onclick
= " makeRequest('test.html') " >

        Make a request

</ span >


在此范例中:

  • 首先使用者按下「Make a request」
  • 这么一来就会呼叫
         makeRequest() 函式,亦传入参数值 test.html (也就是那份 HTML 档的名称,放在同目录下)
  • 接着发出 request,而后会将主导权交给
         onreadystatechange 指定的 alertContents() 函式
  • alertContents() 检查响应是否正常,而后以 alert()test.html 的内容列出

你可以由此测试本例 (http://www.w3clubs.com/mozdev/httprequest_test.html),也可以参考测试档案 (http://www.w3clubs.com/mozdev/test.html)。

第四步 – 「X 档案」(又称为「处理 XML 响应值」)

前面的例子中,在收到 HTTP 传回值后我们以对象的 reponseText 属性使用 test.html 档案的内容,接着来试试 responseXML 属性的方法。

首先,我们得做个格式正确的 XML 文件,以便稍后取用。此档名唤 test.xml,内容如下:


<? xml version="1.0"  ?>

< root >

    I'm a test.

</ root >


在程序中,我们叫用档案的地方只须略事修改如下:

...
				


onclick
=
"
makeRequest('test.xml')
"



...

接着在 alertContents() 中,我们必须将 alert(http_request.responseText); 改成这样:


var  xmldoc  =  http_request.responseXML;

var  root_node  =  xmldoc.getElementsByTagName('root').item( 0 );

alert(root_node.firstChild.data);


这样一来我们便可取得 responseXML 所传回的 XMLDocument 对象,而后以 DOM 相关的方法取用
XML 文件内容。你可以参考 test.xml 的原始码 (http://www.w3clubs.com/mozdev/test.xml)
以及修改过后的测试程序 (http://www.w3clubs.com/mozdev/httprequest_test_xml.html)。

posted @ 2006-05-18 21:56 paulwong 阅读(451) | 评论 (0)编辑 收藏

仅列出标题
共92页: First 上一页 84 85 86 87 88 89 90 91 92 下一页