<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    菠蘿三國(guó)

    大江東去,浪淘盡...
    隨筆 - 34, 文章 - 47, 評(píng)論 - 22, 引用 - 0
    數(shù)據(jù)加載中……

    Servlet與Web服務(wù)

    1.第一口就吃到餡,配置一個(gè)Web服務(wù)的最簡(jiǎn)方法
    ===============================================================================================

    為了能讓web服務(wù)先跑起來(lái),先給出一個(gè)Web服務(wù)的原型,以便于后面的討論。
    我們從一個(gè)最簡(jiǎn)單的例子開始,只給出必須的東西。

    所需軟件:
    1.Tomcat4.1.2
    2.一個(gè)Java編譯器,jdk或JBuilder等等,這是為了編譯我們的Java源程序,于web服務(wù)無(wú)關(guān)。

    所需文件:
    1.sayHello.java
    2.web.xml
    3.server-config.xml
    4.Java Packages: axis.jar,jaxrpc.jar,tt-bytecode.jar,wsdl4j.jar,xercesImpl.jar,xml-apis.jar

    至于Tomcat怎么安裝我就不說(shuō)了,網(wǎng)上關(guān)于Tomcat安裝的文章有很多。
    這六個(gè)package,從ibm和apache的網(wǎng)站上都可以下得到。

    只需要這些,我們就可以部署自己的Web服務(wù)了。。
    下面是目錄結(jié)構(gòu):
    webapps/test/WEB-INF/web.xml
    webapps/test/WEB-INF/server-config.wsdd
    webapps/test/WEB-INF/classes/sayHello.class
    webapps/test/WEB-INF/lib/xxx.jar ---所需得六個(gè)packages


    web.xml
    ---------------------------------------------

    <?xml version="1.0" encoding="ISO-8859-1"?>
    <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN" "http://java.sun.com/j2ee/dtds/web-app_2_2.dtd">

    <web-app>

    <servlet>
        <servlet-name>Axis</servlet-name>
        <!--實(shí)際servlet程序,這里是AxisServlet-->
        <servlet-class>org.apache.axis.transport.http.AxisServlet</servlet-class>
    </servlet>

    <!-- ### 定義servlet和url的對(duì)應(yīng)關(guān)系-->

    <servlet-mapping>
        <servlet-name>Axis</servlet-name>
        <url-pattern>/services/*</url-pattern>
    </servlet-mapping>

    </web-app>

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

    server-config.wsdd
    ---------------------------------------------
    <?xml version="1.0" encoding="UTF-8"?>
    <deployment xmlns:java="http://xml.apache.org/axis/wsdd/providers/java" xmlns="http://xml.apache.org/axis/wsdd/">

    <handler type="java:org.apache.axis.handlers.http.URLMapper" name="URLMapper"/>
      
    <service name="sayHelloService" provider="java:RPC">
      <parameter name="className" value="sayHello"/>
      <parameter name="allowedMethods" value="sayHelloTo"/>
    </service>

    <transport name="http">
      <requestFlow>
        <handler type="URLMapper"/>
      </requestFlow>
    </transport>

    </deployment>
    ---------------------------------------------

    sayHello.java
    ---------------------------------------------
    public class sayHello
    {
      public String sayHelloTo(String aname)
      {
        return "How are you, " + aname;
      }
    }
    ---------------------------------------------


    假設(shè)ip地址192.168.0.1,端口號(hào)是80,我們輸入下面的url得到服務(wù)列表(當(dāng)然這里只有一個(gè)):
    http://192.168.0.1/test/services
    如果你的端口號(hào)是8080,就應(yīng)該輸入http://192.168.0.1:8080/test/services,后面同理。

    瀏覽器顯示:
    ——————————————
    |And now... Some Services |
    | sayHelloService (wsdl)  |
    |  .sayHelloTo            |   
    ——————————————

    sayHelloService是我們的服務(wù)名,右側(cè)的 (wsdl)是一個(gè)鏈接指向sayHelloService的WSDL文檔,
    這個(gè)文檔是由Axis自動(dòng)生成的。
    sayHelloTo當(dāng)然就是我們的方法了。。。

    點(diǎn)擊(wsdl)鏈接或輸入下面的url,得到WSDL:
    http://192.168.0.1/test/services/sayHelloService?wsdl

    瀏覽器顯示sayHelloService的WSDL文檔:

    <?xml version="1.0" encoding="UTF-8"?>
    <wsdl:definitions targetNamespace="http://192.168.0.1/test/services/sayHelloService/test/services/sayHelloService" xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:apachesoap="http://xml.apache.org/xml-soap" xmlns:impl="http://192.168.0.1/test/services/sayHelloService/test/services/sayHelloService-impl" xmlns:intf="http://192.168.0.1/test/services/sayHelloService/test/services/sayHelloService" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
      <wsdl:message name="sayHelloToResponse">
        <wsdl:part name="return" type="xsd:string"/>
      </wsdl:message>
      <wsdl:message name="sayHelloToRequest">
        <wsdl:part name="aname" type="xsd:string"/>
      </wsdl:message>
      <wsdl:portType name="sayHello">
        <wsdl:operation name="sayHelloTo" parameterOrder="aname">
          <wsdl:input message="intf:sayHelloToRequest" name="sayHelloToRequest"/>
          <wsdl:output message="intf:sayHelloToResponse" name="sayHelloToResponse"/>
        </wsdl:operation>
      </wsdl:portType>
      <wsdl:binding name="sayHelloServiceSoapBinding" type="intf:sayHello">
        <wsdlsoap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
        <wsdl:operation name="sayHelloTo">
          <wsdlsoap:operation soapAction=""/>
          <wsdl:input name="sayHelloToRequest">
            <wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://192.168.0.1/test/services/sayHelloService/test/services/sayHelloService" use="encoded"/>
          </wsdl:input>
          <wsdl:output name="sayHelloToResponse">
            <wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://192.168.0.1/test/services/sayHelloService/test/services/sayHelloService" use="encoded"/>
          </wsdl:output>
        </wsdl:operation>
      </wsdl:binding>
      <wsdl:service name="sayHelloService">
        <wsdl:port binding="intf:sayHelloServiceSoapBinding" name="sayHelloService">
          <wsdlsoap:address location="http://192.168.0.1/test/services/sayHelloService"/>
        </wsdl:port>
      </wsdl:service>
    </wsdl:definitions>



    我們甚至不用客戶端,就可以查看服務(wù)是否部署成功以及獲得返回結(jié)果
    用Get方法獲得soap流,我們要用下面的url:
    (真正調(diào)用Web服務(wù),用的是Post方法,這個(gè)后面會(huì)講)

    http://192.168.0.1/test/services/sayHelloService?method=sayHelloTo&aname=everybody

    瀏覽器顯示的是亂碼,我們點(diǎn)右鍵查看源文件,結(jié)果如下:

    <p>Got response message</p>
    <?xml version="1.0" encoding="UTF-8"?>
    <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
     <soapenv:Body>
      <sayHelloToResponse soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
       <sayHelloToReturn xsi:type="xsd:string">How are you, everybody</sayHelloToReturn>
      </sayHelloToResponse>
     </soapenv:Body>
    </soapenv:Envelope>

    這就是我們想要的結(jié)果嗎?這只是服務(wù)器端送回來(lái)的SOAP消息,不過(guò)我們想要的結(jié)果在里面。。。


    為了真正調(diào)用我們的Web服務(wù),下面給出一個(gè)Client:

    import org.apache.axis.client.Call;
    import org.apache.axis.client.Service;
    import javax.xml.namespace.QName;

      public class test
      {
        public static void main(String [] args)
        {
          try {
                 String endpoint = "http://192.168.0.1/test/services/sayHelloService";
                 Service  service = new Service();
                 Call     call    = (Call) service.createCall();
                 call.setTargetEndpointAddress( new java.net.URL(endpoint) );
                 call.setOperationName(new QName("http://sayHelloService", "sayHelloTo"));
                 String ret = (String) call.invoke( new Object[] { args[0] } );
                 System.out.println(ret);
             } catch (Exception e) {
                 e.printStackTrace();
             }
        }
      }

      注意要配置好正確的classpath,確保編譯器能找的到axis.jar和jaxrpc.jar,否則編譯不會(huì)通過(guò)。
      用下面的命令行運(yùn)行這個(gè)class:
      java test everybody
      我們會(huì)得到:How are you, everybody

      這才是我們真正想要的。。。



    2.追根究底,我們的Web服務(wù)是怎樣跑起來(lái)的
    ===============================================================================================


    前面給出的兩個(gè)配置文件web.xml和server-config.wsdd,或許不是能一下子就看懂的。

    先讓我們回顧一下servlet的映射模式。

    我們知道,servlet是從javax.servlet.http.HttpServlet繼承的,在服務(wù)器端被載入JVM執(zhí)行,然后向客戶端輸出html流。
    servlet的web.xml文件(位于 webapps/foo/WEB-INF目錄):

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN"
                             "http://java.sun.com/j2ee/dtds/web-app_2.2.dtd">
    <web-app>
    <servlet-mapping>
    <servlet-name>invoker</servlet-name>
    <url-pattern>/servlet/*</url-pattern>
    </servlet-mapping>
    </web-app>


    invoker servlet 其實(shí)是:org.apache.catalina.servlets.InvokerServlet
    按類名提供小服務(wù)程序。例如,如果您調(diào)用 foo/servlet/HelloServlet,
    invoker servlet將裝入該HelloServlet(如果它在其類路徑中的話)并執(zhí)行。

    初看上面的web.xml,好像只給出了一個(gè)servlet映射,而沒(méi)有定義invoker servlet。
    其實(shí),invoker servlet 是在tomcat的conf目錄中的web.xml中定義的::
     <servlet>
            <servlet-name>invoker</servlet-name>
            <servlet-class>
              org.apache.catalina.servlets.InvokerServlet
            </servlet-class>
            <init-param>
                <param-name>debug</param-name>
                <param-value>0</param-value>
            </init-param>
            <load-on-startup>2</load-on-startup>
        </servlet>

    所以,如果拋開Tomcat_HOME/conf/web.xml,我們這樣定義一個(gè)web.xml,似乎更能清楚的說(shuō)明問(wèn)題:

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN"
                             "http://java.sun.com/j2ee/dtds/web-app_2.2.dtd">
    <web-app>
    <servlet-name>MyInvoker</servlet-name>
    <servlet-class>
    org.apache.catalina.servlets.InvokerServlet
    </servlet-class>
    <init-param>
    <param-name>debug</param-name>
    <param-value>0</param-value>
    </init-param>
    <load-on-startup>2</load-on-startup>
    </servlet>

    <servlet-mapping>
    <servlet-name>MyInvoker</servlet-name>
    <url-pattern>/servlet/*</url-pattern>
    </servlet-mapping>
    </web-app>


    即所有/servlet/* 模式的url,都會(huì)交給org.apache.catalina.servlets.InvokerServlet來(lái)處理。
    或者說(shuō),所有/servlet/* 模式的url,其實(shí)都是調(diào)用InvokerServlet這個(gè)類,而InvokerServlet本身也是
    一個(gè)servlet,它也是從 HttpServlet 繼承而來(lái)的。

    這樣,我們自己的servlet就能夠通過(guò)特定的url執(zhí)行,即 /servlet/OurServlet。
    當(dāng)然,如果你高興,可以定義任何的 url pattern,而不一定是 /servlet/*,這一點(diǎn),正如我們后面
    看到的Axis處理Soap消息的方法。


    再進(jìn)一步,如果不想讓 InvokerServlet 在中間“搗鬼”,我們當(dāng)然可以直接定義自己的servlet:

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN"
                             "http://java.sun.com/j2ee/dtds/web-app_2.2.dtd">
    <web-app>
    <servlet-name>MyInvoker2</servlet-name>
    <servlet-class>
    com.foo.MyServlet
    </servlet-class>
    </servlet>

    <servlet-mapping>
    <servlet-name>MyInvoker2</servlet-name>
    <url-pattern>/AnyName/*</url-pattern>
    </servlet-mapping>
    </web-app>


    JSP也是一樣的道理,有了上面的分析,
    看看Tomcat_HOME/conf/web.xml中的如下語(yǔ)句就可以JSP的處理方法了,這里就不再?gòu)U話了:
    ....
    <servlet>
            <servlet-name>jsp</servlet-name>
            <servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class>
            <init-param>
                <param-name>logVerbosityLevel</param-name>
                <param-value>WARNING</param-value>
            </init-param>
            <load-on-startup>3</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>jsp</servlet-name>
        <url-pattern>*.jsp</url-pattern>
    </servlet-mapping>
    ....


    下面進(jìn)入正題。


    我們先來(lái)看部署Web Service的web.xml:

    <?xml version="1.0" encoding="ISO-8859-1"?>
    <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN" "http://java.sun.com/j2ee/dtds/web-app_2_2.dtd">

    <web-app>

    <servlet>
        <servlet-name>Axis</servlet-name>
        <!--實(shí)際servlet程序,這里是AxisServlet-->
        <servlet-class>org.apache.axis.transport.http.AxisServlet</servlet-class>
    </servlet>

    <!-- ### 定義servlet和url的對(duì)應(yīng)關(guān)系-->

    <servlet-mapping>
        <servlet-name>Axis</servlet-name>
        <url-pattern>/services/*</url-pattern>
    </servlet-mapping>

    </web-app>


    所有 /services/* 模式的 url 都會(huì)交給org.apache.axis.transport.http.AxisServlet處理,
    AxisServlet當(dāng)然也是從HttpServlet繼承而來(lái)的。這就是為什么我們部署的Web服務(wù)在調(diào)用時(shí)都要在
    服務(wù)名稱前加上 services/ 了。

    可以說(shuō),AxisServlet是所有Web服務(wù)調(diào)用的入口。
    那么AxisServlet在接手Web服務(wù)調(diào)用后都做了哪些工作呢?

    客戶端用call.invoke()調(diào)用web服務(wù)用的是POST,所以入口是AxisServlet.doPost...
    而不是AxisServlet.doGet...


    先來(lái)看看AxisServlet的doPost函數(shù),這里只給出了關(guān)鍵語(yǔ)句及注釋:

        /**
         * Process a POST to the servlet by handing it off to the Axis Engine.
         * Here is where SOAP messages are received
         * @param req posted request
         * @param res respose
         * @throws ServletException trouble
         * @throws IOException different trouble
         */
         public void doPost(HttpServletRequest req, HttpServletResponse res)
            throws ServletException, IOException
        {
    msgContext = createMessageContext(engine, req, res);//獲取客戶請(qǐng)求信息

    engine.invoke(msgContext); //調(diào)用客戶端請(qǐng)求的服務(wù)

    responseMsg = msgContext.getResponseMessage();//得到調(diào)用的返回結(jié)果

    sendResponse(getProtocolVersion(req), contentType, res, responseMsg);//將結(jié)果送至客戶端
         }

    這樣一來(lái),Web服務(wù)調(diào)用的來(lái)龍去脈就大致清楚了。。。

    為了高清楚前面我們的三個(gè)url
    http://192.168.0.1/test/services
    http://192.168.0.1/test/services/sayHelloService?wsdl
    http://192.168.0.1/test/services/sayHelloService?method=sayHelloTo&aname=everybody
    是怎樣獲得輸出結(jié)果的,再來(lái)看看AxisServlet的doGet函數(shù),這里只給出了流程框架及注釋:

    **
    * Process GET requests. Because Axis does not support the GET-style
    * pseudo execution of SOAP methods, this handler deals with queries
    * of various kinds, not real SOAP actions.
    *
    * @todo for secure installations, dont stack trace on faults
    * @param request request in
    * @param response request out
    * @throws ServletException
    * @throws IOException
    */
    public void doGet(HttpServletRequest req, HttpServletResponse res)
            throws ServletException, IOException
    {

    //如果路徑為空,比如:http://localhost/wstk/services 或 http://localhost/wstk/services/*
    if((pathInfo == null || pathInfo.equals("")) && !realpath.endsWith(".jws"))

    {
    //從server-config.wsdd文件中讀取所有部署的服務(wù)信息,向向客戶端列出所有部署的服務(wù),
    //包括每個(gè)服務(wù)可調(diào)用的方法。

    }else
    //如果路徑不為空,比如:http://localhost/wstk/services/sayHelloService
    if(realpath != null)
    {
    //如果請(qǐng)求wsdl,比如:http://localhost/wstk/services/sayHelloService?wsdl
    if(wsdlRequested)
    {
    //創(chuàng)建sayHelloService的WSDL文件并傳送至客戶端
    } else
    //這里是利用url調(diào)用Web服務(wù)的入口,比如http://192.168.0.1/test/services/sayHelloService?method=sayHelloTo&aname=everybody
    if(req.getParameterNames().hasMoreElements())
    {
    //如果客戶端調(diào)用的方法正確,則Axis會(huì)調(diào)用相應(yīng)的JavaBean,并把JavaBean的返回結(jié)果
    //封裝為Soap消息流返回給客戶端。
    }
    }
    }


    而Axis怎樣找到我們所請(qǐng)求的JavaBean呢?答案是server-config.wsdd文件。

    server-config.wsdd

    <?xml version="1.0" encoding="UTF-8"?>
    <deployment xmlns:java="http://xml.apache.org/axis/wsdd/providers/java" xmlns="http://xml.apache.org/axis/wsdd/">

    <service name="sayHelloService" provider="java:RPC">
      <parameter name="className" value="sayHello"/>
      <parameter name="allowedMethods" value="sayHelloTo"/>
    </service>

    <handler type="java:org.apache.axis.handlers.http.URLMapper" name="URLMapper"/>

    <transport name="http">
      <requestFlow>
        <handler type="URLMapper"/>
      </requestFlow>
    </transport>

    </deployment>

    WSDD是web service deployment descriptor的縮寫。

    最外面的<deployment>元素指示這是WSDD,并定義了java的名字空間。

    接著的 <service>元素定義了service。一個(gè)service是一個(gè)目標(biāo)鏈,包括請(qǐng)求request、內(nèi)容提供者provider、響應(yīng)response。
    在這個(gè)例子中,我們指出service名字是sayHelloService ,provider是"java:RPC",它是axis 的標(biāo)記,指示這是一個(gè)java的RPC service,
    而處理它的真正的class是org.apache.axis.providers.java.RPCProvider。

    接著我們要在<parameter>中告訴RPCProvider,它如何實(shí)例化并調(diào)用正確的class(如:com.foo.MyService)。
    <parameter>元素的className指示class名,allowedMethods告訴引擎那些共用的方法要通過(guò)soap來(lái)調(diào)用。
    "*"表示所有的公共方法,我們也列出方法名字列表,可以空格或逗號(hào)分割它們。

    posted on 2007-08-06 22:23 菠蘿 閱讀(298) 評(píng)論(0)  編輯  收藏 所屬分類: AXIS

    主站蜘蛛池模板: 免费av欧美国产在钱| 亚洲熟妇av一区二区三区漫画| 免费在线观看理论片| 久久综合亚洲鲁鲁五月天| 深夜免费在线视频| 黄页免费的网站勿入免费直接进入| 亚洲中文字幕无码中文字在线| 国产成人不卡亚洲精品91| 丁香花免费高清视频完整版| 亚洲一本之道高清乱码| 日本免费高清视频| 又爽又高潮的BB视频免费看| 暖暖免费在线中文日本| 亚洲精品永久在线观看| 免费无码AV片在线观看软件| 国产97视频人人做人人爱免费| 亚洲AV无码乱码在线观看| 真人无码作爱免费视频| 亚洲国产综合91精品麻豆| 4399好看日本在线电影免费| 亚洲综合另类小说色区| 国产在线a免费观看| 国产成人高清精品免费观看| 亚洲精品伊人久久久久| 97人伦色伦成人免费视频| 怡红院免费的全部视频| 亚洲综合在线另类色区奇米| 丁香花免费高清视频完整版| a在线观看免费视频| 亚洲精品在线免费看| 香蕉高清免费永久在线视频| 亚洲中文字幕久久精品无码A| 岛国片在线免费观看| 免费无毒a网站在线观看| 亚洲va无码va在线va天堂| 久久免费视频精品| 九九综合VA免费看| 亚洲国产精品一区| 亚洲综合在线另类色区奇米| 免费看一级做a爰片久久| 国产男女爽爽爽免费视频 |