??xml version="1.0" encoding="utf-8" standalone="yes"?>国产精品三p一区二区,久久久久久久久综合,岛国在线视频网站http://www.aygfsteel.com/conans/category/32883.html你越挣扎我就兴?/description>zh-cnSun, 08 Mar 2009 12:05:57 GMTSun, 08 Mar 2009 12:05:57 GMT60Using JAXB 2.1 with JavaSE 6http://www.aygfsteel.com/conans/articles/258412.htmlCONANCONANSat, 07 Mar 2009 13:50:00 GMThttp://www.aygfsteel.com/conans/articles/258412.htmlJavaSE 6 comes with JAXB 2.0 API in rt.jar . Therefore, using JAXB 2.1 with JavaSE 6 requires one to override a portion of rt.jar with the new API. There are several ways to do this:

  1. Place the 2.1 jaxb-api.jar into $JRE_HOME/lib/endorsed . This essentially makes your JRE to "JRE 6 + JAXB 2.1". This won't affect any other applications that use this JRE, and it's easy. On the other hand, in various scenarios you may not be able to alter the JRE.
  2. Use the system property java.endorsed.dirs when you launch your application, and have it point to the directory that contains the 2.1 jaxb-api.jar . This allows you use use JAXB 2.1 without modifying the JRE. Make sure not to include any other JAXB RI jar files (such as jsr173-api.jar or jaxb-impl.jar .)
  3. Implement a custom ClassLoader and block delegation to javax.xml.bind package, so that code running inside this class loader will load the JAXB API from elsewhere. This is a very advanced approach.

No matter which approach you take, make sure not to include jar files other than jaxb-api.jar . Doing so, for example including jaxb-xjc.jar , may result in classloading related errors such as "taskdef A class needed by class com.sun.tools.xjc.XJCTask cannot be found: org/apache/tools/ant/...."

See the endorsed directory mechanism for more details.


jdk6update12也可解决

CONAN 2009-03-07 21:50 发表评论
]]>
WebService大讲堂之Axis2(10)Q用soapmonitor模块监视soaph与响应消?http://www.aygfsteel.com/conans/articles/255091.htmlCONANCONANTue, 17 Feb 2009 06:56:00 GMThttp://www.aygfsteel.com/conans/articles/255091.html?/span>Axis2中提供了一?/span>Axis2模块Q?/span>soapmonitorQ,该模块实C?/span>《WebService大讲堂之Axis2(9)Q编写Axis2模块QModuleQ?/a>中实现的logging模块相同的功能,所不同的是Q?/span>logging模块直接?/span>SOAPh与响应消息输出到Tomcat控制CQ?/span>soapmonitor模块利用applet直接在页面中输出SOAPh和响应消息?/span>

    下面是配|和使用soapmonitor模块的步骤:   

W?/span>1步:部vApplet?/span>Servlet

    ׃axis2默认情况下已l自带了soapmonitor模块Q因此,soapmonitor模块q不需要单独安装。但applet所涉及到的相应?/span>.class文g需要安装一下。在<Tomcat安装目录>\webapps\axis2\WEB-INF\lib目录中找?/span>soapmonitor-1.4.1.jar文gQ将该文件解压。虽?/span>appletq不需?/span>soapmonitor-1.4.1.jar文g中所有的.class文gQ但Z方便Q读者也可以直接解压目录中?/span>org目录复制?/span><Tomcat安装目录>\webapps\axis2目录中,Applet所需?/span>.class文g需要放在这个目录。然后再?/span>org目录复制?/span><Tomcat安装目录>\webapps\axis2\WEB-INF\classes目录中,soapmonitor模块中的Servlet所对应?/span>.class文g需要放在这个目录?br />

W?/span>2步:配置Servlet

    打开<Tomcat安装目录>\webapps\axis2\WEB-INF\web.xml文gQ在其中加入如下的内容:

<servlet>
    
<servlet-name>SOAPMonitorService</servlet-name>
    
<servlet-class>
        org.apache.axis2.soapmonitor.servlet.SOAPMonitorService
    
</servlet-class>
    
<init-param>
        
<param-name>SOAPMonitorPort</param-name>
        
<param-value>5001</param-value>
    
</init-param>
    
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    
<servlet-name>SOAPMonitorService</servlet-name>
    
<url-pattern>/SOAPMonitor</url-pattern>
</servlet-mapping>

 

W?/span>3步:?/span>services.xml文g中引?/span>soapmonitor模块

    与引用logging模块一P引用soapmonitor模块也需要?lt;module>元素Q引用soapmonitor模块的services.xml文g的内容如下:
<service name="myService">
    
<description>
        使用logging和soapmonitor模块
    
</description>
    
<!--  引用logging模块  -->
    
<module ref="logging"/>
    
<!--  引用soapmonitor模块  -->
    
<module ref="soapmonitor"/>
    
<parameter name="ServiceClass">
        service.MyService   
    
</parameter>
    
<messageReceivers>
        
<messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-out"
            class
="org.apache.axis2.rpc.receivers.RPCMessageReceiver" />
    
</messageReceivers>
</service>

    ׃soapmonitor模块已经?/span>axis2.xmlq行配置了,因此Q在本例中不需要再?/span>axis2.xml文gq行配置了?nbsp;  

W?/span>4步:使用soapmonitor模块

    启动Tomcat后,在浏览器中输入如下的URLQ?br />
http://localhost:8080/axis2/SOAPMonitor

    在浏览器中将出现soapmonitor所带的Applet的界面,当访?/span>MyService?/span>getGreetingҎӞ?/span>Tomcat控制CApplet中都昄了相应的SOAPh和响应消息。如?/span>1和图2分别是调用了两次getGreetingҎ后输出的SOAPh和响应消息?br />



?



?

 

    如果读者想?/span>logging?/span>soapmonitor模块监视部v?/span>Axis2中的所?/span>WebServiceQ可以在axis2.xml文g中?/span><module>元素来引用这两个模块Q代码如下:

    <!--  引用logging模块  -->
    
<module ref="logging"/>
    
<!--  引用soapmonitor模块  -->
    
<module ref="soapmonitor"/>




CONAN 2009-02-17 14:56 发表评论
]]>
WebService大讲堂之Axis2(9)Q编写Axis2模块QModuleQ?http://www.aygfsteel.com/conans/articles/254909.htmlCONANCONANMon, 16 Feb 2009 08:47:00 GMThttp://www.aygfsteel.com/conans/articles/254909.html可以通过模块Q?/span>ModuleQ进行扩展?/span>Axis2模块臛_需要有两个c,q两个类分别实现?/span>Module?/span>Handler接口。开发和使用一?/span>Axis2模块的步骤如下:

1. ~写实现Module接口的类?/span>Axis2模块在进行初始化、销毁等动作时会调用该类中相应的ҎQ?/span>

2. ~写实现Handler接口的类。该cLAxis2模块的业务处理类?/span>

3. ~写module.xml文g。该文g攑֜META-INF目录中,用于配置Axis2模块?/span>

4. ?/span>axis2.xml文g中配|?/span>Axis2模块?/span>

5. ?/span>services.xml文g中配|?/span>Axis2模块。每一?/span>Axis2模块都需要?/span><module>元素引用才能使用?/span>

6. 发布Axis2模块。需要?/span>jar命o?/span>Axis2模块压羃?/span>.mar包(文g扩展名必L.marQ,然后?/span>.mar文g攑֜

<Tomcat安装目录>\webapps\axis2\WEB-INF\modules目录中?nbsp;  
    先来~写一个WebServicec,代码如下Q?br />

package service;

public class MyService
{
    
public String getGreeting(String name)
    {
        
return "您好 " + name;
    }
}

 

    下面我们来编写一个记录请求和响应SOAP消息?/span>Axis2模块。当客户端调?/span>WebServiceҎӞ?/span>Axis2模块会将h和响?/span>SOAP消息输出?/span>Tomcat控制C?/span>

W?/span>1步:~写LoggingModulec?/span>

    LoggingModulecdCModule接口Q代码如下:

package module;

import org.apache.axis2.AxisFault;
import org.apache.axis2.context.ConfigurationContext;
import org.apache.axis2.description.AxisDescription;
import org.apache.axis2.description.AxisModule;
import org.apache.axis2.modules.Module;
import org.apache.neethi.Assertion;
import org.apache.neethi.Policy;

public class LoggingModule implements Module
{
    
// initialize the module
    public void init(ConfigurationContext configContext, AxisModule module)
            
throws AxisFault
    {
        System.out.println(
"init");
    }
    
public void engageNotify(AxisDescription axisDescription) throws AxisFault
    {
    }
    
// shutdown the module
    public void shutdown(ConfigurationContext configurationContext)
            
throws AxisFault
    {
        System.out.println(
"shutdown");
    }
    
public String[] getPolicyNamespaces()
    {
        
return null;
    }
    
public void applyPolicy(Policy policy, AxisDescription axisDescription)
            
throws AxisFault
    {
    }
    
public boolean canSupportAssertion(Assertion assertion)
    {
        
return true;
    }
}

    在本例中LoggingModulecdƈ没实现实际的功能Q但该类必须存在。当Tomcat启动时会装蝲?/span>Axis2模块Q同时会调用LoggingModuleinitҎQƈ?/span>Tomcat控制C输出“init”?/span>

W?/span>2步:~写LogHandlerc?br />

    LogHandlercdCHandler接口Q代码如下:

package module;

import org.apache.axis2.AxisFault;
import org.apache.axis2.context.MessageContext;
import org.apache.axis2.engine.Handler;
import org.apache.axis2.handlers.AbstractHandler;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class LogHandler extends AbstractHandler implements Handler
{
    
private static final Log log = LogFactory.getLog(LogHandler.class);
    
private String name;
    
public String getName()
    {
        
return name;
    }
    
public InvocationResponse invoke(MessageContext msgContext)
            
throws AxisFault
    {
        
//  向Tomcat控制台输求和响应SOAP消息
        log.info(msgContext.getEnvelope().toString());
        
return InvocationResponse.CONTINUE;
    }
    
public void revoke(MessageContext msgContext)
    {
        log.info(msgContext.getEnvelope().toString());
    }
    
public void setName(String name)
    {
        
this.name = name;
    }
}

 

    LogHandlercȝ核心Ҏ?/span>invokeQ当使用?/span>Axis2模块?/span>WebService的方法被调用ӞLogHandlerinvokeҎ被调用?nbsp;  

W?/span>3步:~写module.xml文g   

    在META-INF目录中徏立一个module.xml文gQ内容如下:
<module name="logging" class="module.LoggingModule">
    
<InFlow>
        
<handler name="InFlowLogHandler" class="module.LogHandler">
            
<order phase="loggingPhase"/>
        
</handler>
    
</InFlow>
    
<OutFlow>
        
<handler name="OutFlowLogHandler" class="module.LogHandler">
            
<order phase="loggingPhase"/> 
        
</handler>
    
</OutFlow>

    
<OutFaultFlow>
        
<handler name="FaultOutFlowLogHandler" class="module.LogHandler">
            
<order phase="loggingPhase"/>
        
</handler>
    
</OutFaultFlow>
    
<InFaultFlow>
        
<handler name="FaultInFlowLogHandler" class="module.LogHandler">
            
<order phase="loggingPhase"/>
        
</handler>
    
</InFaultFlow>
</module>

W?/span>4步:?/span>axis2.xml文g中配|?/span>Axis2模块

    打开axis2.xml文gQ分别在如下四个<phaseOrder>元素中加?/span><phase name="loggingPhase"/>Q?br />

<phaseOrder type="InFlow">
     
    <phase name="soapmonitorPhase"/>
    <phase name="loggingPhase"/>
</phaseOrder>
<phaseOrder type="OutFlow">
     
    
<phase name="Security"/>
    
<phase name="loggingPhase"/>
</phaseOrder>
<phaseOrder type="InFaultFlow">
     
    
<phase name="soapmonitorPhase"/>
    
<phase name="loggingPhase"/>
</phaseOrder>
<phaseOrder type="OutFaultFlow">
     
    
<phase name="Security"/>
    
<phase name="loggingPhase"/>
</phaseOrder>

 

W?/span>5步:?/span>services.xml文g中引?/span>logging模块

    services.xml文g的内容如下:

<service name="myService">
    
<description>
        使用logging模块
    
</description>
    
<!--  引用logging模块  -->
    
<module ref="logging"/>
    
<parameter name="ServiceClass">
        service.MyService   
    
</parameter>
    
<messageReceivers>
        
<messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-out"
            class
="org.apache.axis2.rpc.receivers.RPCMessageReceiver" />
    
</messageReceivers>
</service>

W?/span>6步:发布logging模块

    到现在ؓ止,我们应用可以建立两个发行包:logging.mar?/span>service.aar。其?/span>logging.mar文g?/span>Axis2模块的发行包Q该包的目录l构如下Q?/span>

logging.mar

    module\LoggingModule.class

    module\LogHandler.class

    META-INF\module.xml

    service.aar文g是本例编写的WebService发行包,该包的目录结构如下:

service.aar

    service\MyService.class

    META-INF\services.xml

    ?/span>logging.mar文g攑֜<Tomcat安装目录>\webapps\axis2\WEB-INF\modules目录中,?/span>service.aar文g攑֜<Tomcat安装目录>\webapps\axis2\WEB-INF\services目录中。要注意的是Q如?/span>modules目录中包含了modules.list文gQ?/span>Axis2会只装蝲在该文g中引用的Axis2模块Q因此,必须在该文g中引?/span>logging模块Q该文g的内容如下:

addressing-1.4.1.mar

soapmonitor-1.4.1.mar

ping-1.4.1.mar

mex-1.4.1.mar

axis2-scripting-1.4.1.mar

logging.mar

    如果modules目录中不包含modules.list文gQ则Axis2会装?/span>modules文g中的所?/span>Axis2模块?/span>

    现在启动TomcatQ用如下的C#代码调用MyService?/span>getGreetingҎ则会?/span>Tomcat控制C输出相应的请求和响应SOAP消息?br />

//  async是引用MyService的服务名
async.myService my = new WSC.asyn.myService();
MessageBox.Show(my.getGreeting(
"中国"));
MessageBox.Show(
"完成调用");

 

    在执行上面的代码后,?/span>Tomcat控制C输出的信息如?/span>图所C?br />

转自Qhttp://www.aygfsteel.com/nokiaguy/archive/2009/02/16/254826.html





CONAN 2009-02-16 16:47 发表评论
]]>
WebService大讲堂之Axis2(8)Q异步调用WebService http://www.aygfsteel.com/conans/articles/254908.htmlCONANCONANMon, 16 Feb 2009 08:46:00 GMThttp://www.aygfsteel.com/conans/articles/254908.html在前面几文章中都是使用同步方式来调?/span>WebService。也是_如果被调用的WebServiceҎ长时间不q回Q客L一直被dQ直到该Ҏq回为止。用同步方法来调用WebService虽然很直观,但当WebServiceҎ׃各种原因需要很长时间才能返回的话,׃使客LE序一直处于等待状态,q样用户是无法忍受的?/span>
    当然Q我们很Ҏ可以想到解决问题的ҎQ这是多线E。解决问题的基本Ҏ是将讉KWebService的Q务交׃个或多个U程来完成,而主U程q不负责讉KWebService。这样即使被讉K?/span>WebServiceҎ长时间不q回Q客L仍然可以做其他的工作。我们可以管q种通过多线E访?/span>WebService的方式称为异步访问?/span>
    虽然直接使用多线E可以很好地解决q个问题Q但比较ȝ。幸?/span>Axis2的客L提供了异步访?/span>WebService的功能?/span>
    RPCServiceClientcL供了一?/span>invokeNonBlockingҎ可以通过异步的方式来讉KWebService。下面先来徏立一?/span>WebService?br />     MyService是一?/span>WebServicec,代码如下Q?br />
package service;
public class MyService
{
    
public String getName()
    {
        
try
        {            
            System.out.println(
"getNameҎ正在执行");
            
//  延迟5U?/span>
            Thread.sleep(5000);
        }
        
catch (Exception e)
        {        
        }
        
return "火星";
    }
}

    Z模拟需要一定时间才q回?/span>WebServiceҎQ在getNameҎ中用了sleepҎ来gq?/span>5U?/span>
    下面?/span>MyServicecȝ配置代码Q?br />

<!--  services.xml  -->
<service name="myService">
    
<description>
        异步调用演示
    
</description>
    
<parameter name="ServiceClass">
        service.MyService   
    
</parameter>
    
<messageReceivers>
        
<messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-out"
            class
="org.apache.axis2.rpc.receivers.RPCMessageReceiver" />
    
</messageReceivers>
</service>

 

    从上面的配置代码可以看出Q?/span>MyService的配|方式与前几章的WebService的配|方式完全一P也就是说Q?/span>MyService只是一个普通的WebService?/span>
    下面是异步调?/span>MyService?/span>Java客户端代码:

package client;

import javax.xml.namespace.QName;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.client.Options;
import org.apache.axis2.context.MessageContext;
import org.apache.axis2.rpc.client.RPCServiceClient;

public class RPCAsyncClient
{
    
public static void main(String[] args) throws Exception
    {
        RPCServiceClient serviceClient 
= new RPCServiceClient();
        Options options 
= serviceClient.getOptions();
        EndpointReference targetEPR 
= new EndpointReference(
                
"http://localhost:8080/axis2/services/myService");
        options.setTo(targetEPR);
        Object[] opAddEntryArgs 
= new Object[]{};
        QName opAddEntry 
= new QName("http://service""getName");
        serviceClient.invokeNonBlocking(opAddEntry, opAddEntryArgs,
                
new org.apache.axis2.client.async.AxisCallback()
                {
                    @Override
                    
public void onComplete()
                    {
                    }
                    @Override
                    
public void onError(Exception arg0)
                    {
                    }                    }
                    @Override
                    
public void onFault(MessageContext arg0)
                    {
                    }
                    @Override
                    
public void onMessage(MessageContext mc)
                    {
                        
//  输出q回?/span>
                        System.out.println(mc.getEnvelope().getFirstElement()
                                .getFirstElement().getFirstElement().getText());
                    }
                });
        System.out.println(
"异步调用Q?/span>");
        
//  LE序退?/span>
        System.in.read();
    }

 

    从上面的代码可以看出Q?/span>invokeNonBlockingҎ有三个参敎ͼ前两个参数分别指定了要调用的Ҏ及方法参数的相关信息Q而最后一个参数ƈ不是Ҏq回值的cd信息Q而是一个实?/span>org.apache.axis2.client.async.AxisCallback接口的类的对象实例。在本例中隐式实CAxisCallback接口。在AxisCallback接口中有四个Ҏ需要实玎ͼ其中当被异步调用的方法返回时onMessageҎ被调用。当q行上面的程序后Q将输出如下的信息:

异步调用Q?br /> 火星

    虽然上面的例子可以实现异步调用,但比较麻烦。ؓ了更方便地实现异步调用,可以使用wsdl2java命o?/span>-a参数生成可异步调用的StubcR下面的命o可生成同步和异步调用的客L代码Q两个类Q,其中-s表示生成同步调用代码Q?/span>-a表示生成异步调用代码?/span>

%AXIS2_HOME%\bin\wsdl2java -uri http://localhost:8080/axis2/services/myService?wsdl -p client -s -a -o stub

    在执行上面的命o后,生成两个类Q?/span>MyServiceStub?/span>MyServiceCallbackHandlerc,其中MyServiceStubc负责同步和异步调用WebServiceQ?/span>MyServiceCallbackHandlercL一个抽象类Q也是一个回调类Q当使用异步方式调用WebServiceҎӞ如果Ҏq回Q则MyServiceCallbackHandlerreceiveResultgetNameҎ被调用。下面是使用MyServiceStubcd步访?/span>WebService的代码:

package client;

import client.MyServiceStub.GetNameResponse;

class MyCallback extends MyServiceCallbackHandler
{
    @Override
    
public void receiveResultgetName(GetNameResponse result)
    {
        
//  输出getNameҎ的返回结?/span>
        System.out.println(result.get_return());
    }
}
public class StubClient
{
    
public static void main(String[] args) throws Exception  
    {
        MyServiceStub stub 
= new MyServiceStub();        
        
//  异步调用WebService
        stub.startgetName(new MyCallback());
        System.out.println(
"异步调用Q?/span>");
        System.in.read();    
    } 
}

 

   执行上面的程序后Q将输出如下的信息:   

异步调用Q?br /> 火星

     
?net中也可以使用异步的方式来调用WebServiceQ如在C#中可使用如下的代码来异步调用getNameҎQ?br />
//  回调Ҏ
private void getNameCompletedEvent(object sender, WSC.asyn.getNameCompletedEventArgs e)
{
    listBox1.Items.Add( e.Result.@
return);
}
private void button1_Click(object sender, EventArgs e)
{          
    async.myService my 
= new WSC.async.myService();
    my.getNameCompleted 
+= new WSC.async.getNameCompletedEventHandler(getNameCompletedEvent);
     my.getNameAsync();
     MessageBox.Show(
"完成调用");
}

    其中async是引?/span>MyService的服务名。要注意的是Q在C#中不能在同一?/span>WebService实例?/span>getNameҎ未返回之前,再次调用该实例的getNameҎQ否则将抛出异常。如下面的代码会抛出一个异常:

    async.myService my = new WSC.async.myService();
    my.getNameCompleted 
+= new WSC.async.getNameCompletedEventHandler(getNameCompletedEvent);
    my.getNameAsync();
   
//  抛出异?/span>
    my.getNameAsync();

 

    但不同的WebService实例的方法可以在Ҏ未返回时调用Q如下面的代码是可以正常工作的:

asyn.myService my = new WSC.asyn.myService();
my.getNameAsync();
my.getNameCompleted 
+= new WSC.asyn.getNameCompletedEventHandler(getNameCompletedEvent);
asyn.myService my1 
= new WSC.asyn.myService();
my1.getNameCompleted 
+= new WSC.asyn.getNameCompletedEventHandler(getNameCompletedEvent);
my1.getNameAsync();

转自Qhttp://www.aygfsteel.com/nokiaguy/archive/2009/02/13/254548.html


CONAN 2009-02-16 16:46 发表评论
]]>
WebService大讲堂之Axis2(7)Q将Spring的装配JavaBean发布成WebService http://www.aygfsteel.com/conans/articles/254907.htmlCONANCONANMon, 16 Feb 2009 08:45:00 GMThttp://www.aygfsteel.com/conans/articles/254907.html在现今的Web应用中经怋?/span>Spring框架来装?/span>JavaBean。如果要惛_某些?/span>Spring中装配的JavaBean发布?/span>WebServiceQ?/span>Axis2?/span>Spring感知功能是非常容易做到的?/span>
    在本文的例子中,除了<Tomcat安装目录>\webapps\axis2目录及该目录中的相关库外Q还需?/span>Spring框架中的spring.jar文gQ将该文件复制到<Tomcat安装目录>\webapps\axis2\WEB-INF\lib目录中?/span>
    下面先徏立一?/span>JavaBeanQ该JavaBean最l要被发布成WebServiceQ,代码如下Q?br />
package service;
import entity.Person;
public class SpringService
{
    
private String name;
    
private String job;
    
public void setName(String name)
    {
        
this.name = name;
    }
    
public void setJob(String job)
    {
        
this.job = job;
    }
    
public Person getPerson()
    {
        Person person 
= new Person();
        person.setName(name);
        person.setJob(job);
        
return person;
    }
    
public String getGreeting(String name)
    {
        
return "hello " + name;
    }
}

 

    其中Person也是一?/span>JavaBeanQ代码如下:

package entity;
public class Person
{
    
private String name;
    
private String job;
    
public String getName()
    {
        
return name;
    }
    
public void setName(String name)
    {
        
this.name = name;
    }
    
public String getJob()
    {
        
return job;
    }
    
public void setJob(String job)
    {
        
this.job = job;
    }
}

 

    上面两?/span>Java源文件编译后Q放?/span><Tomcat安装目录>\webapps\axis2\WEB-INF\classes目录中?/span>

    ?/span><Tomcat安装目录>\webapps\axis2\WEB-INF目录中徏立一?/span>applicationContext.xml文gQ该文g?/span>Spring框架用于装配JavaBean的配|文Ӟ内容如下Q?br />

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi
="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:aop
="http://www.springframework.org/schema/aop"
        xmlns:tx
="http://www.springframework.org/schema/tx"
        xsi:schemaLocation
="
            http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
            http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
            http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"
>
  
<bean id="springService" class="service.SpringService">
     
<property name="name" value="姚明" />
     
<property name="job" value="职业L" /> 
  
</bean>   
</beans>

 

    ?/span>applicationContext.xml文g中装配了service.SpringServicec,q被始化?/span>name?/span>job属性。在配置?/span>SpringServicecdQ就可以直接在程序中FileSystemXmlApplicationContextcL其他cM功能的类dapplicationContext.xml文g中的内容Qƈ获得SpringServicecȝ对象实例。但现在我们q不q样做,而是?/span>SpringServicecd布成WebService?/span>

    ?/span><Tomcat安装目录>\webapps\axis2\WEB-INF\lib目录中有一?/span>axis2-spring-1.4.1.jar文gQ该文g用于被装配JavaBean的发布成WebService。在D盘徏立一?/span>axi2-spring-ws目录Qƈ在该目录中徏立一?/span>META-INF子目录。在META-INF目录中徏立一?/span>services.xml文gQ内容如下:

<service name="springService">
    
<description>
        Spring aware
    
</description>
    
<parameter name="ServiceObjectSupplier">
        org.apache.axis2.extensions.spring.receivers.SpringServletContextObjectSupplier
    
</parameter>
    
<parameter name="SpringBeanName">
        springService
    
</parameter>
    
<messageReceivers>
        
<messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-out"
            class
="org.apache.axis2.rpc.receivers.RPCMessageReceiver" />
    
</messageReceivers>
</service>    

 

    ?/span>Windows控制台进?/span>axi2-spring-ws目录Qƈ使用jar命o?/span>axi2-spring-ws目录中的内容打包?/span>axi2-spring-ws.aarQ然后将该文件复制到<Tomcat安装目录>\webapps\axis2\WEB-INF\services目录中,启动Tomcat后,可以访问该WebService了,讉K方式与前面几文章的讉K方式相同。获?/span>wsdl内容?/span>URL如下Q?br />
http://localhost:8080/axis2/services/springService?wsdl

    在将Spring中的装配JavaBean发布?/span>WebService需要注意以下几点:

    1. ?/span>JavaBean~译生成?/span>.class文g需要放?/span>WEB-INF\classes目录中,或打?/span>.jar包后攑֜WEB-INF\lib目录中,?/span>WEB-INF\services目录中的.aar包中不需要包?/span>.class文gQ而只需要包含一?/span>META-INF目录Qƈ在该目录中包含一?/span>services.xml文g卛_?/span>

    2. services.xml的配|方法与前几文章的配置ҎcMQ只是ƈ不需要?/span>ServiceClass参数指定要发布成WebService?/span>Javac,而是要指定在applicationContext.xml文g中的装配JavaBean的名UͼSpringBeanName参数Q?/span>

    3. ?/span>services.xml文g中需要通过ServiceObjectSupplier参数指定SpringServletContextObjectSuppliercL获得Spring?/span>ApplicationContext对象?br />
转自Qhttp://www.aygfsteel.com/nokiaguy/archive/2009/02/13/254499.html



CONAN 2009-02-16 16:45 发表评论
]]>
WebService大讲堂之Axis2(6)Q跨服务会话(Session)理 http://www.aygfsteel.com/conans/articles/253527.htmlCONANCONANFri, 06 Feb 2009 03:47:00 GMThttp://www.aygfsteel.com/conans/articles/253527.html?/span>《WebService大讲堂之Axis2(5)Q会话(SessionQ管理?/a>一文中介绍了如何?/span>Axis2来管理同一个服务的会话Q但对于一个复杂的pȝQ不可能只有一?/span>WebService服务Q例如,臛_会有一个管理用LWebServiceQ用L录和注册Q以及处理业务的WebService。象q种情况Q就必须在多?/span>WebService服务之间׃n会话状态,也称服务会话(Session)理。实现跨服务会话理与实现同一个服务的会话理的步骤类|但仍然有一些差别,实现跨服务会话管理的步骤如下Q?/span>

实现跨服务的Session理需要如下三步:

1. 使用MessageContext?/span>ServiceGroupContext获得与设|?/span>key-value寏V?/span>

2. q行Session理?/span>WebServicecL对应?/span><service>元素d一?/span>scope属性,q将该属性D?/span>application?/span>

3. 在客L使用setManageSession(true)打开Session理功能?/span>

从上面的步骤可以看出Q实现跨服务会话理与实现同一个服务的会话理在前两步上存在着差异Q而第3步是完全一L。下面是一个跨服务的会话管理的实例。在q个例子中有两个WebServicec:LoginService?/span>SearchServiceQ代码如下:

LoginService.java

package service;
import org.apache.axis2.context.MessageContext;
import org.apache.axis2.context.ServiceGroupContext;
public class LoginService
{
    
public boolean login(String username, String password)
    {        
        
if("bill".equals(username) && "1234".equals(password))
        {
            
//  W?步:讄key-value?/span>
            MessageContext mc = MessageContext.getCurrentMessageContext();
            ServiceGroupContext sgc 
= mc.getServiceGroupContext();
            sgc.setProperty(
"login""成功d");    
            
return true;
        }
        
else
        {
            
return false;
        }
    }    
    
public String getLoginMsg()
    {
       
//  W?步:获得key-value对中的value
        MessageContext mc = MessageContext.getCurrentMessageContext();
        ServiceGroupContext sgc 
=  mc.getServiceGroupContext();
        
return (String)sgc.getProperty("login");    
    }
}


SearchService.java

package service;
import org.apache.axis2.context.MessageContext;
import org.apache.axis2.context.ServiceGroupContext;
public class SearchService
{
    
public String findByName(String name)
    {
        
//  W?步:获得key-value对中的value
        MessageContext mc = MessageContext.getCurrentMessageContext();
        ServiceGroupContext sgc 
=  mc.getServiceGroupContext();                
        
if (sgc.getProperty("login"!= null)
            
return "扑ֈ的数?lt;" + name + ">";
        
else
            
return "用户未登?/span>";
    }
}

services.xml文g中的配置代码如下Q?br />

<serviceGroup>
    
<!--  W?步:dscope属性,q设|属性gؓapplication -->
    
<service name="loginService" scope="application">
        
<description>
            d服务
        
</description>
        
<parameter name="ServiceClass">
            service.LoginService
        
</parameter>
        
<messageReceivers>
            
<messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-out"
                class
="org.apache.axis2.rpc.receivers.RPCMessageReceiver" />
        
</messageReceivers>
    
</service>
    
<!--  W?步:dscope属性,q设|属性gؓapplication -->
    
<service name="searchService" scope="application">
        
<description>
            搜烦服务
        
</description>
        
<parameter name="ServiceClass">
            service.SearchService
        
</parameter>
        
<messageReceivers>
            
<messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-out"
                class
="org.apache.axis2.rpc.receivers.RPCMessageReceiver" />
        
</messageReceivers>
    
</service>
</serviceGroup>


W?/span>3步与《WebService大讲堂之Axis2(5)Q会话(SessionQ管理?/a>一文中介绍的方法类伹{?br />

下面是用两?/span>stubcȝ对象实例讉K上面实现的两?/span>WebService的客L代码Q?br />

LoginServiceStub stub = new LoginServiceStub();
LoginServiceStub.Login login 
= new LoginServiceStub.Login();
login.setUsername(
"bill");
login.setPassword(
"1234");
if(stub.login(login).local_return)
{
    System.out.println(stub.getLoginMsg().local_return);
    SearchServiceStub searchStub 
= new SearchServiceStub();
    SearchServiceStub.FindByName fbn 
= new SearchServiceStub.FindByName();
    fbn.setName(
"abc");
    System.out.println(searchStub.findByName(fbn).local_return); 
}

在执行上面的代码后,输出如下的信息Q?/span>

成功d

扑ֈ的数?/span><abc>

读者可以将scope属性值改成transportsessionQ看看会输出什么!

    实际上,Axis2的会话管理也是通过Cookie实现的,与Web应用中的Session理cM。如果读者用C#讉K支持会话Q在同一个服务中的会话管理)的WebServiceQ需要指定一个CookieContainer对象Q代码如下:

service.loginService ls = new service.loginService();
System.Net.CookieContainer cc 
= new System.Net.CookieContainer();
ls.CookieContainer 
= cc;
bool r, rs;
ls.login(
"bill""1234"out @r, out rs);
if (r)
{
    MessageBox.Show(ls.getLoginMsg().@return);
}

如果是访问跨服务的支持会话的WebServiceQ则不需要指?/span>CookieContainer对象Q代码如下:

service.loginService ls = new service.loginService();
bool r, rs;
ls.login(
"bill""1234"out @r, out rs);
if (r)
{
    service1.searchService ss 
= new service1.searchService();
    MessageBox.Show(ss.findByName(
"abc"));
}

如果读者?/span>delphiQ本文用的?/span>delphi2009Q其他的delphi版本误者自行测试)调用支持会话?/span>WebService时有一些差别。经W者测试,使用delphi调用WebServiceQ将scope属性D?/span>transportsession?/span>application都可以实现跨服务的会话管理,q一点和Java?/span>C#不同Q?/span>Java?/span>C#必须?/span>scope属性D?/span>application才支持跨服务会话理。在delphi中不需要象C#指定一?/span>CookieContainer或其他类似的对象Q而只需要象讉K普通的WebService一栯问支持会话的WebService卛_?/span>



CONAN 2009-02-06 11:47 发表评论
]]>
WebService大讲堂之Axis2(5)Q会话(SessionQ管?http://www.aygfsteel.com/conans/articles/252821.htmlCONANCONANSun, 01 Feb 2009 01:48:00 GMThttp://www.aygfsteel.com/conans/articles/252821.htmlWebServicelh最直观的感觉就是由一个个Ҏl成Qƈ在客L通过SOAP协议调用q些Ҏ。这些方法可能有q回|也可能没有返回倹{虽然这样可以完成一些工P但这些被调用的方法是孤立的,当一个方法被调用后,在其他的Ҏ中无法获得这个方法调用后的状态,也就是说无法保留状态?/span>

读者可以想象,q对于一个完整的应用E序Q无法保留状态,意味着只依?/span>WebService很难完成全部的工作。例如,一个完整的应用pȝ都需要进行登录,q在Web应用中?/span>Session来保存用L录状态,而如果用WebService的方法来q行d处理Q无法保存登录状态是非常令h尬的。当Ӟq也可以通过其他的方法来解决Q如在服务端使用static变量来保存用L态,q发送一?/span>id到客LQ通过在服务端和客L传递这?/span>id来取得相应的用户状态。这非常cM?/span>Web应用中通过Session?/span>Cookie来管理用L态。但q就需要由开发h员做很多工作Q不q幸?/span>Axis2为我们提供了WebService状态管理的功能?/span>

使用Axis2来管?/span>WebService的状态基本上对于开发h员是透明的。在WebServicec需要?/span>org.apache.axis2.context.MessageContext?/span>org.apache.axis2.context.ServiceContextcL保存与获得保存在服务端的状态信息,q有些象使用HttpSession接口?/span>getAttribute?/span>setAttributeҎ获得与设|?/span>Session域属性?/span>

除此之外Q还需要修?/span>services.xml文g的内容,?/span><service>元素加一?/span>scope属性,该属性有四个可取的|Application, SOAPSession, TransportSession, RequestQ不q要注意一下,虽然Axis2的官Ҏ档将q四个值的单词首字母和~写字母都写成了大写Q但l笔者测试,必须全部写才有效,也就是这四个值应为:application?/span>soapsession?/span>transportsession?/span>requestQ其?/span>request?/span>scope属性的默认倹{读者可以选择使用transportsession?/span>application分别实现同一?/span>WebServicecd?/span>WebServicecȝ会话理?/span>

在客L需要?/span>setManageSession(true)打开Session理功能?/span>

lg所qͼ实现同一?/span>WebService?/span>Session理需要如下三步:

1. 使用MessageContext?/span>ServiceContext获得与设|?/span>key-value寏V?/span>

2. q行Session理?/span>WebServicecL对应?/span><service>元素d一?/span>scope属性,q将该属性D?/span>transportsession?/span>

3. 在客L使用setManageSession(true)打开Session理功能?/span>

下面是一个在同一?/span>WebServicecM理Session的例子?/span>

先徏立一个WebServicec,代码如下Q?br />


package service;
import org.apache.axis2.context.ServiceContext;
import org.apache.axis2.context.MessageContext;
public class LoginService
{
    
public boolean login(String username, String password)
    {
        
if("bill".equals(username) && "1234".equals(password))
        {
            
//  W?步:讄key-value?/span>
            MessageContext mc = MessageContext.getCurrentMessageContext();
            ServiceContext sc 
= mc.getServiceContext();
            sc.setProperty(
"login""成功d");    
            
return true;
        }
        
else
        {
            
return false;
        }
    }
    
public String getLoginMsg()
    {
        
//  W?步:获得key-value对中的value
        MessageContext mc = MessageContext.getCurrentMessageContext();
        ServiceContext sc 
= mc.getServiceContext();
        
return (String)sc.getProperty("login");    
    }
}

?/span>LoginServicecM有两个方法:login?/span>getLoginMsgQ如?/span>loginҎd成功Q会?#8220;成功d”字符串保存在ServiceContext对象中。如果在loginҎq回true后调?/span>getLoginMsgҎQ就会返?#8220;成功d”?/span>

下面?/span>LoginServicecȝ配置代码Q?/span>services.xmlQ:

<!--  W?步:dscope属?nbsp; -->
<service name="loginService" scope="transportsession">
    
<description>
        d服务
        
</description>
    
<parameter name="ServiceClass">
        service.LoginService
        
</parameter>
    
<messageReceivers>
        
<messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-out"
            class
="org.apache.axis2.rpc.receivers.RPCMessageReceiver" />
    
</messageReceivers>
</service>

使用如下的命令生成客L使用?/span>stubc:

%AXIS2_HOME%\bin\wsdl2java -uri http://localhost:8080/axis2/services/loginService?wsdl -p client -s -o stub

?/span>stub\src\client目录中生成了一?/span>LoginServiceStub.javac,在该cM扑ֈ如下的构造句ҎQ?br />

public LoginServiceStub(org.apache.axis2.context.ConfigurationContext configurationContext,
        java.lang.String targetEndpoint, 
boolean useSeparateListener)
        
throws org.apache.axis2.AxisFault 
{
     
    _serviceClient.getOptions().setSoapVersionURI(
                                 org.apache.axiom.soap.SOAP12Constants.SOAP_ENVELOPE_NAMESPACE_URI);
}

在该Ҏ中最后添加如下的代码Q?br />

//  W?步:打开客户端的Session理功能
_serviceClient.getOptions().setManageSession(true);

下面的客L代码使用LoginServiceStub对象讉K了刚才徏立的WebServiceQ?br />

LoginServiceStub stub = new LoginServiceStub();
LoginServiceStub.Login login 
= new LoginServiceStub.Login();
login.setUsername(
"bill");
login.setPassword(
"1234");
if(stub.login(login).local_return)
{
    System.out.println(stub.getLoginMsg().local_return);
}

q行上面的代码后Q会输出“成功d”信息?br /> 转自Q?a href="http://www.aygfsteel.com/nokiaguy/archive/2009/01/26/252564.html">http://www.aygfsteel.com/nokiaguy/archive/2009/01/26/252564.html



CONAN 2009-02-01 09:48 发表评论
]]>
WebService大讲堂之Axis2(4)Q二q制文g传输 http://www.aygfsteel.com/conans/articles/252355.htmlCONANCONANThu, 22 Jan 2009 07:43:00 GMThttp://www.aygfsteel.com/conans/articles/252355.htmlWebService大讲堂之Axis2Q?Q:复合cd数据的传?/a>》中讲过Q如果要传递二q制文gQ如囑փ、音频文件等Q,可以使用byte[]作ؓ数据cdq行传递,然后客户端?/span>RPC方式q行调用。这样做只是其中的一U方法,除此之外Q在客户端还可以使用wsdl2java命o生成相应?/span>stubcL调用WebServiceQ?/span>wsdl2java命o的用法详见?/span>WebService大讲堂之Axis2Q?Q:用POJO实现0配置的WebService》?/span>
    WebServicecM包含byte[]cd参数的方法在wsdl2java生成?/span>stubcM对应的数据类型不再是byte[]cdQ而是javax.activation.DataHandler?/span>DataHandlercL专门用来映射WebService二进制类型的?br />     ?/span>WebServicecM除了可以使用byte[]作ؓ传输二进制的数据cd外,也可以?/span>javax.activation.DataHandler作ؓ数据cd?/span> 不管是?/span>byte[]Q还是?/span>javax.activation.DataHandler作ؓWebServiceҎ的数据类型,使用wsdl2java命o生成?/span>stubcM相应Ҏ的类型都?/span>javax.activation.DataHandler。而象使用.net?/span>delphi生成?/span>stubcȝ相应Ҏcd都是byte[]。这是由?/span>javax.activation.DataHandlercLJavaҎ的,对于其他语言和技术来_q不认识javax.activation.DataHandlerc,因此Q也只有使用最原始?/span>byte[]了?br />     下面是一个上传二q制文g的例子,WebServicecȝ代码如下Q?br />
package service;

import java.io.InputStream;
import java.io.OutputStream;
import java.io.FileOutputStream;
import javax.activation.DataHandler;

public class FileService
{
   
//  使用byte[]cd参数上传二进制文?/span>
    public boolean uploadWithByte(byte[] file, String filename)
    {
         FileOutputStream fos 
= null;
         
try
         {                          
             fos 
= new FileOutputStream(filename);    
             fos.write(file);
             fos.close();
         }
         
catch (Exception e)
         {
             
return false;
         }
         
finally
         {
             
if (fos != null)
             {
                 
try
                 {
                     fos.close();
                 }
                 
catch (Exception e)
                 {
                 }
             }
         }
         
return true;
    }
    
private void writeInputStreamToFile(InputStream is, OutputStream os) throws Exception
    {
         
int n = 0;
         
byte[] buffer = new byte[8192];
         
while((n = is.read(buffer)) > 0)
         {
             os.write(buffer, 
0, n);
         }
    }
    
//  使用DataHandlercd参数上传文g
    public boolean uploadWithDataHandler(DataHandler file, String filename)
    {
        
         FileOutputStream fos 
= null;
         
try
         {            
             fos 
= new FileOutputStream(filename);   
             
//  可通过DataHandlercȝgetInputStreamҎd上传数据
             writeInputStreamToFile(file.getInputStream(), fos);
             fos.close();
         }
         
catch (Exception e)
         {
             
return false;
         }
         
finally
         {
             
if (fos != null)
             {
                 
try
                 {
                     fos.close();
                 }
                 
catch (Exception e)
                 {
                 }
             }
         }
         
return true;
    }
}

上面代码?/span>services.xml文g的配|代码如下:

<service name="fileService">
    
<description>
        文g服务
    
</description>
    
<parameter name="ServiceClass">
        service.FileService 
    
</parameter>
        
<messageReceivers>
        
<messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-out"
            class
="org.apache.axis2.rpc.receivers.RPCMessageReceiver" />
    
</messageReceivers>
</service>


    如果使用
wsdl2java命o生成调用Java客户端代码,则需要创?/span>DataHandlercȝ对象实例Q代码如下:

DataHandler dh = new DataHandler(new FileDataSource(imagePath));

wsdl2java命o会ؓ每一个方法生成一个封装方法参数的c,cd为方法名Q第一个字W大写)Q如uploadWithByteҎ生成的类名ؓUploadWithByte。如果要讄file参数的|可以使用UploadWithBytesetFileҎQ代码如下:


UploadWithByte uwb = new UPloadWithByte();
uwb.setFile(dh);

最后是调用uploadWithByteҎQ代码如下(FileServiceStub?/span>wsdl2java生成?/span>stubcdQ:


FileServiceStub fss = new FileServiceStub();
fss.uploadWithByte(uwb);

如果使用C#调用FileServiceQ则file参数cd均ؓbyte[]Q代码如下:

MemoryStream ms = new MemoryStream();
Bitmap bitmap 
= new Bitmap(picUpdateImage.Image);
bitmap.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
service.fileService fs 
= new WSC.service.fileService();
fs.uploadWithDataHandler(ms.ToArray());
fs.uploadWithByte(ms.ToArray());
 

其中picUpdateImage?/span>c#中加载图像文件的picturebox控g?br />
转自Qhttp://www.aygfsteel.com/nokiaguy/archive/2009/01/archive/2009/01/archive/2009/01/archive/2009/01/22/252305.html



CONAN 2009-01-22 15:43 发表评论
]]>
WebService大讲堂之Axis2(3)Q用services.xml文g发布WebService http://www.aygfsteel.com/conans/articles/252354.htmlCONANCONANThu, 22 Jan 2009 07:42:00 GMThttp://www.aygfsteel.com/conans/articles/252354.html实现Web ServiceQ虽然可以将POJOcL?/span>axis2\WEB-INF\pojo目录中直接发布成Web ServiceQ这样做不需要进行Q何配|,但这?/span>POJOcM能在M包中。这g有些不方便,为此Q?/span>Axis2也允许将带包?/span>POJOcd布成Web Service?br />     先实C?/span>POJOc,代码如下Q?br />
package service;

public class MyService
{
    
public String getGreeting(String name)
    {
        
return "您好 " + name;
    }
    
public void update(String data)
    {
        System.out.println(
"<" + data + ">已经更新");
    }
}

q个cL两个ҎQ这两个Ҏ都需要发布成Web ServiceҎ。这U方式和直接攑֜pojo目录中的POJOcM同。要惛_MyServicecd布成Web ServiceQ需要一?/span>services.xml文gQ这个文仉要放?/span>META-INF目录中,该文件的内容如下Q?/span>

<service name="myService">
    
<description>
        Web Service例子
    
</description>
    
<parameter name="ServiceClass">
        service.MyService  
    
</parameter>
    
<messageReceivers>
        
<messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-out"
            class
="org.apache.axis2.rpc.receivers.RPCMessageReceiver" />
        
<messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-only"
            class
="org.apache.axis2.rpc.receivers.RPCInOnlyMessageReceiver" />
    
</messageReceivers>
</service>

其中<service>元素用于发布Web ServiceQ一?/span><service>元素只能发布一?/span>WebServicec,name属性表C?/span>WebService名,如下面的URL可以获得q个WebService?/span>WSDL内容Q?br />

http://localhost:8080/axis2/services/myService?wsdl

其中name属性名是上面URL?/span>"?"?/span>"/"之间的部分?/span>

<description>元素表示当前Web Service的描qͼ<parameter>元素用于讄WebService的参敎ͼ在这里用于设|?/span>WebService对应的类名。在q里最值得注意的是<messageReceivers>元素Q该元素用于讄处理WebServiceҎ的处理器。例如,getGreetingҎ有一个返回|因此Q需要用可处理输入输出?/span>RPCMessageReceiverc,?/span>updateҎ没有q回|因此Q需要用只能处理输入的RPCInOnlyMessageReceivercR?/span>

使用q种方式发布WebServiceQ必L包成.aar文gQ?/span>..aar文g实际上就是改变了扩展名的.jar文g。在现在建立了两个文ӞMyService.java?/span>services.xml。将MyService.java~译Q生?/span>MyService.class?/span>services.xml?/span>MyService.class文g的位|如下:

D:\ws\service\MyService.class

D:\ws\META-INF\services.xml

   
?/span>windows控制Cq入ws目录Qƈ输入如下的命令生?/span>.aar文gQ实际上Q?jar文g也可以发布webserviceQ但axis2官方文档中徏议?aar文g发布webserviceQ:

jar cvf ws.aar .

   
最后将ws.aar文g复制?/span><Tomcat安装目录>\webapps\axis2\WEB-INF\services目录中,启动Tomcat后,可以调用这?/span>WebService了。调用的Ҏ?/span>《WebService大讲堂之Axis2Q?Q:用POJO实现0配置的WebService?/a>所讲的ҎcM?/span>

另外services.xml文g中也可以直接指定WebServicecȝҎQ如可以用下面的配置代码来发?/span>WebServiceQ?/span>


<service name="myService">
    
<description>
        Web Service例子
    
</description>
    
<parameter name="ServiceClass">
        service.MyService  
    
</parameter>
    
<operation name="getGreeting">
        
<messageReceiver class="org.apache.axis2.rpc.receivers.RPCMessageReceiver" />
    
</operation>
    
<operation name="update">
        
<messageReceiver
            
class="org.apache.axis2.rpc.receivers.RPCInOnlyMessageReceiver" />
    
</operation>
</service>

上面的配|代码前面的部分和以前的services.xml文g的内容相同,但后面用了<operation>元素来指定每一?/span>WebServiceҎQƈ单独指定了处理每一个方法的处理器。对于客L来说Q调用用这两个services.xml文g发布?/span>WebServiceq没有太大我区别Q只是用第二个services.xml文g发布WebServices后,在?/span>wsdl2java命o或?/span>C#?/span>delphi{生成客L?/span>stubӞupdateҎ?/span>Stringcd被封装在?/span>updatecMQ在传?/span>updateҎ的参数时需要徏?/span>updatecȝ对象实例。而用第一?/span>services.xml文g发布?/span>WebService在生?/span>stub时直接可以ؓupdateҎ传?/span>Stringcd的参数。从q一点可以看出,q两U方法生成的WSDL有一定的区别。但实际上,如果客户端程序用第一?/span>services.xml文g发布?/span>WebService生成stubcLQ这?/span>updateҎ的参数是StringQ,在服务端又改为第二个services.xml文g来发?/span>WebServiceQ这时客Lq不需要再重新生成stubc,而可以直接调?/span>updateҎ。也是_服务端用什么样的方式发?/span>WebServiceQ对客户端ƈ没有影响?/span>

如果惛_布多?/span>WebServiceQ可以?/span><serviceGroup>元素Q如再徏立一?/span>MyService1c,代码如下Q?br />

package service
public class MyService1
{
    
public String getName()  
    { 
        
return "bill";
    }
}

?/span>services.xml文g中可以用如下的配置代码来配|?/span>MyService?/span>MyService1c:


<serviceGroup>
    <service name="myService">
       
<description>
            Web Service例子
       
</description>
       
<parameter name="ServiceClass">
            service.MyService  
       
</parameter>
       
<messageReceivers>
           
<messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-out"
                class
="org.apache.axis2.rpc.receivers.RPCMessageReceiver" />
           
<messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-only"
                class
="org.apache.axis2.rpc.receivers.RPCInOnlyMessageReceiver" />
       
</messageReceivers>
    </service>
    <service name="myService1">
       
<description>
            Web Service例子
      
</description>
       
<parameter name="ServiceClass">
            service.MyService1  
       
</parameter>
        
<messageReceivers>
          
<messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-out"
                class
="org.apache.axis2.rpc.receivers.RPCMessageReceiver" />
          
<messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-only"
                class
="org.apache.axis2.rpc.receivers.RPCInOnlyMessageReceiver" />
       
</messageReceivers>
    </service>
</serviceGroup>

转自Qhttp://www.aygfsteel.com/nokiaguy/archive/2009/01/archive/2009/01/archive/2009/01/21/252255.html


CONAN 2009-01-22 15:42 发表评论
]]>
WebService大讲堂之Axis2Q?Q:复合cd数据的传?http://www.aygfsteel.com/conans/articles/252353.htmlCONANCONANThu, 22 Jan 2009 07:41:00 GMThttp://www.aygfsteel.com/conans/articles/252353.html阅读全文

CONAN 2009-01-22 15:41 发表评论
]]>
WebService大讲堂之Axis2Q?Q:用POJO实现0配置的WebServicehttp://www.aygfsteel.com/conans/articles/252352.htmlCONANCONANThu, 22 Jan 2009 07:38:00 GMThttp://www.aygfsteel.com/conans/articles/252352.html是一套崭新的WebService引擎Q该版本是对Axis1.x重新设计的物?/span>Axis2不仅支持SOAP1.1?/span>SOAP1.2Q还集成了非常流行的REST WebServiceQ同时还支持Spring?/span>JSON{技术。这些都在后面的系列教E中讲解。在本文中主要介l了如何使用Axis2开发一个不需要Q何配|文件的WebServiceQƈ在客L使用Java?/span>C#调用q个WebService?/span>

一?/span>Axis2的下载和安装

    读者可以从如下的网址下蝲Axis2的最新版本:

    http://ws.apache.org/axis2/

    在本文用了目前Axis2的最新版?/span>1.4.1。读者可以下载如下两?/span>zip包:

    axis2-1.4.1-bin.zip

    axis2-1.4.1-war.zip

    其中axis2-1.4.1-bin.zip文g中包含了Axis2中所有的jar文g, axis2-1.4.1-war.zip文g用于?/span>WebService发布?/span>Web容器中?/span>

    ?/span>axis2-1.4.1-war.zip文g解压到相应的目录Q将目录中的axis2.war文g攑ֈ<Tomcat安装目录>\webapps目录中(本文使用?/span>Tomcat的版本是6.xQ,q启?/span>Tomcat?/span>

    在浏览器地址栏中输入如下?/span>URLQ?/span>

    http://localhost:8080/axis2/

    如果在浏览器中显C出如图1所C的面Q则表示Axis2安装成功?br />



?

二、编写和发布WebService

  对于?/span>Java实现的服务程序给人的印象是需要进行大量的配置Q不q这一点在Axis2中将被终l。在Axis2中不需要进行Q何的配置Q就可以直接一个简单的POJO发布?/span>WebService。其?/span>POJO中所有的publicҎ被发布?/span>WebServiceҎ?/span>

    下面我们来实C个简单的POJOQ代码如下:

public class SimpleService
{
    
public String getGreeting(String name)
    {
        
return "你好 " + name;
    }    
    
public int getPrice()
    {
        
return new java.util.Random().nextInt(1000);
    }    
}

    ?/span>SimpleServicecM有两个方法,׃q两个方法都?/span>publicҎQ因此,它们都将作ؓWebServiceҎ被发布?/span>

    ~译SimpleServicecdQ将SimpleService.class文g攑ֈ<Tomcat安装目录>\webapps\axis2\WEB-INF\pojo目录中(如果没有pojo目录Q则建立该目录)。现在我们已l成功将SimpleServicecd布成?/span>WebService。在览器地址栏中输入如下?/span>URLQ?/span>

http://localhost:8080/axis2/services/listServices

    q时当前面显C所有在Axis2中发布的WebServiceQ如?/span>2所C?br />



?

 

    在浏览器地址栏中输入如下的两?/span>URL来分别测?/span>getGreeting?/span>getPriceҎQ?/span>

http://localhost:8080/axis2/services/SimpleService/getGreeting?name=bill

http://localhost:8080/axis2/services/SimpleService/getPrice

    ?/span>3和图4分别昄?/span>getGreeting?/span>getPriceҎ的测试结果?br />

 

?  getGreetingҎ的测试结?/span>

 

?  getPriceҎ的测试结?/span>

    在编写、发布和试0配置?/span>WebService时应注意如下几点Q?/span>

    1. POJOcM能?/span>package关键字声明包?/span>

    2. Axis2在默认情况下可以热发?/span>WebServiceQ也是_?/span>WebService?/span>.class文g复制?/span>pojo目录中时Q?/span>Tomcat不需要重新启动就可以自动发布WebService。如果想取消Axis2的热发布功能Q可以打开<Tomcat安装目录>\webapps\axis2\WEB-INF\conf\axis2.xmlQ找到如下的配置代码Q?/span>

<parameter name="hotdeployment">true</parameter>

 

 

 

    ?/span>true改ؓfalse卛_。要注意的是Q?/span>Axis2在默认情况下虽然是热发布Q但q不是热更新Q也是_一旦成功发布了WebServiceQ再x新该WebServiceQ就必须重启Tomcat。这对于开发h员调?/span>WebService非常不方便,因此Q在开?/span>WebServiceӞ可以?/span>Axis2设ؓ热更新。在axis2.xml文g中找?/span><parameter name="hotupdate">false</parameter>Q将false改ؓtrue卛_?/span>

    3. 在浏览器中测?/span>WebServiceӞ如果WebServiceҎ有参敎ͼ需要?/span>URL的请求参数来指定?/span>WebServiceҎ参数的|h参数名与Ҏ参数名要一_例如Q要试getGreetingҎQ请求参数名应ؓnameQ如上面?/span>URL所C?/span>

    4. 发布WebService?/span>pojo目录只是默认的,如果读者想在其他的目录发布WebServiceQ可以打开axis2.xml文gQƈ?/span><axisconfig>元素中添加如下的子元素:

    <deployer extension=".class" directory="my" class="org.apache.axis2.deployment.POJODeployer"/>

 

 

 

    上面的配|允许在<Tomcat安装目录>"webapps"axis2"WEB-INF"my目录中发?/span>WebService。例如,本例中?/span>SimpleService.class复制?/span>my目录中也可以成功发布Q但要删?/span>pojo目录中的SimpleService.classQ否?/span>WebService会重名)?/span>

三?/span> ?/span>Java实现调用WebService的客LE序

    WebService是ؓE序服务的,只在览器中讉KWebService是没有意义的。因此,在本节?/span>Java实现了一个控制台E序来调用上一节发布的WebService。调?/span>WebService的客L代码如下Q?/span>

package client;

import javax.xml.namespace.QName;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.client.Options;
import org.apache.axis2.rpc.client.RPCServiceClient;

public class RPCClient
{
    
public static void main(String[] args) throws Exception  
    {
        
//  使用RPC方式调用WebService        
        RPCServiceClient serviceClient = new RPCServiceClient();
        Options options 
= serviceClient.getOptions();
        
//  指定调用WebService的URL
        EndpointReference targetEPR = new EndpointReference(
                
"http://localhost:8080/axis2/services/SimpleService");
        options.setTo(targetEPR);
        
//  指定getGreetingҎ的参数?/span>
        Object[] opAddEntryArgs = new Object[] {"h"};
        
//  指定getGreetingҎq回值的数据cd的Class对象
        Class[] classes = new Class[] {String.class};
        
//  指定要调用的getGreetingҎ及WSDL文g的命名空?/span>
        QName opAddEntry = new QName("http://ws.apache.org/axis2""getGreeting");
        
//  调用getGreetingҎq输Ҏ的返回?/span>
        System.out.println(serviceClient.invokeBlocking(opAddEntry, opAddEntryArgs, classes)[0]);
        
//  下面是调用getPriceҎ的代码,q些代码与调用getGreetingҎ的代码类?/span>
        classes = new Class[] {int.class};
        opAddEntry 
= new QName("http://ws.apache.org/axis2""getPrice");
        System.out.println(serviceClient.invokeBlocking(opAddEntry, 
new Object[]{}, classes)[0]);
    } 
}

 

 

 

 

q行上面的程序后Q将在控制台输出如下的信息:


你好 h
443

    在编写客L代码时应注意如下几点Q?/span>

    1. 客户端代码需要引用很?/span>Axis2?/span>jar包,如果读者不太清楚要引用哪个jar包,可以?/span>Eclipse的工E中引用Axis2发行包的lib目录中的所?/span>jar包?/span>

    2. 在本例中使用?/span>RPCServiceClientinvokeBlockingҎ调用?/span>WebService中的Ҏ?/span>invokeBlockingҎ有三个参敎ͼ其中W一个参数的cd?/span>QName对象Q表C调用的方法名Q第二个参数表示要调用的WebServiceҎ的参数|参数cd?/span>Object[]Q第三个参数表示WebServiceҎ的返回值类型的Class对象Q参数类型ؓClass[]。当Ҏ没有参数ӞinvokeBlockingҎ的第二个参数g能是nullQ而要使用new Object[]{}?/span>

    3. 如果被调用的WebServiceҎ没有q回|应?/span>RPCServiceClientinvokeRobustҎQ该Ҏ只有两个参数Q它们的含义?/span>invokeBlockingҎ的前两个参数的含义相同?/span>

    4. 在创?/span>QName对象ӞQNamecȝ构造方法的W一个参数表C?/span>WSDL文g的命名空间名Q也是<wsdl:definitions>元素?/span>targetNamespace属性|下面?/span>SimpleServicecȝ成的WSDL文g的代码片D:

<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:ns1="http://org.apache.axis2/xsd"
xmlns:ns
="http://ws.apache.org/axis2" xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl"
xmlns:http
="http://schemas.xmlsoap.org/wsdl/http/" xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:mime
="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:soap12
="http://schemas.xmlsoap.org/wsdl/soap12/"
targetNamespace
="http://ws.apache.org/axis2"
>
    
<wsdl:types>
         
    
</wsdl:types>
     
</wsdl:definitions>

四、用wsdl2java化客L的编?/span>

    也许有很多读者会?#8220;有没有搞错啊Q只调用两个WebServiceҎ用要写这么多代码Q太ȝ?#8221;?/span>

    不过q好Axis2提供了一?/span>wsdl2java.bat命o可以ҎWSDL文g自动产生调用WebService的代码?/span>wsdl2java.bat命o可以?/span><Axis2安装目录>"bin目录中找到。在使用wsdl2java.bat命o之前需要设|?/span>AXIS2_HOME环境变量Q该变量值是<Axis2安装目录>?/span>

    ?/span>Windows控制台输出如下的命o行来生成调用WebService的代码:

%AXIS2_HOME%\bin\wsdl2java -uri http://localhost:8080/axis2/services/SimpleService?wsdl -p client -s -o stub

    其中-url参数指定?/span>wsdl文g的\径,可以是本地\径,也可以是|络路径?/span>-p参数指定了生成的Javacȝ包名Q?/span>-o参数指定了生成的一pd文g保存的根目录。在执行完上面的命o后,读者就会发现在当前目录下多了个stub目录Q在."stub"src"client目录可以扑ֈ一?/span>SimpleServiceStub.java文gQ该文g复杂调用WebServiceQ读者可以在E序中直接用这个类Q代码如下:

package client;

import javax.xml.namespace.QName;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.client.Options;
import org.apache.axis2.rpc.client.RPCServiceClient;

public class StubClient
{
    
public static void main(String[] args) throws Exception  
    {
        SimpleServiceStub stub 
= new SimpleServiceStub();
        SimpleServiceStub.GetGreeting gg 
= new SimpleServiceStub.GetGreeting();
        gg.setName(
"比尔");
        System.out.println( stub.getGreeting(gg).get_return());
        System.out.println(stub.getPrice().get_return());
    } 
}

 

    上面的代码大大简化了调用WebService的步骤,q代码更加z。但要注意的是,wsdl2java.bat命o生成?/span>StubcdWebServiceҎ的参数都装在了相应的类中,cd为方法名Q例如,getGreetingҎ的参数都装在了GetGreetingcMQ要惌?/span>getGreetingҎQ必d创徏GetGreetingcȝ对象实例?/span>

五、?/span>C#调用WebService

    从理Z_WebService可以被Q何支?/span>SOAP协议的语a调用。在Visual Studio中?/span>C#调用WebService是在所有语a中最Ҏ实现的(VB.net的调用方法类|也同样很单)?/span>

    新徏一?/span>Visual Studio工程Qƈ在引?/span>Web服务的对话框中输入如下的URLQƈ输入Web引用名ؓ“WebService”Q?/span>

    http://localhost:8080/axis2/services/SimpleService?wsdl

    然后引用Web服务的对话框׃昄?/span>WebService中的所有的ҎQ如?/span>5所C?br />



?

 

    在完成上面的工作后,只需要如下三?/span>C#代码可以调?/span>getGreeting?/span>getPriceҎQƈ昄q两个方法的q回|

WebService.SimpleService simpleService = new WSC.WebService.SimpleService();
MessageBox.Show( simpleService.getGreeting(
"比尔"));
MessageBox.Show(simpleService.getPrice().@return.ToString());

 

 

 

    ?/span>.net解析WSDL文g时直接将getGreetingҎ的参数映ؓStringcdQ因此,可以直接q行传倹{?/span>
    从上面的调用q程可以看出Q添?/span>Web引用的过E就相当于在Java中调?/span>wsdl2java.bat自动生成stubcȝq程。只是在调用stubcL?/span>C#有一定的区别Q但从M上来_都大大简化了调用WebService的过E?br />
转自Qhttp://www.aygfsteel.com/nokiaguy/



CONAN 2009-01-22 15:38 发表评论
]]>
WebService无法q接Oraclehttp://www.aygfsteel.com/conans/articles/214080.htmlCONANCONANThu, 10 Jul 2008 11:17:00 GMThttp://www.aygfsteel.com/conans/articles/214080.htmlWebService无法q接Oracle

2008-7-9 cheungmine

1 问题的来源:我在WebService中无法连接Oracle10g

2 解决的办法:     9i: ORACLE_HOME 目录增加用户Authenticated Users (dq行的权? ?    10g: OracleClient10g 目录增加用户Authenticated Users (dq行的权?

ORACLE_HOME 是oracle安装的主目录Q?OracleClient10g?0g客户端安装的ȝ录?/p>

为目录增加用LҎ是在目录上右?>属?>安全->d->Q输入对象和名称框里输入Authenticated UsersQ?>选中允许dq行?/p>

我采用oradbi? 用于在WebService和Oracleq接。oradbi库是我写的开放源码的OCI装库,

旨在对大数据字段BLOB的读写提供更高效的访问,您可以在我的资源中下载?



CONAN 2008-07-10 19:17 发表评论
]]>
实战 JDK 6.0 自带web service http://www.aygfsteel.com/conans/articles/213463.htmlCONANCONANTue, 08 Jul 2008 15:02:00 GMThttp://www.aygfsteel.com/conans/articles/213463.html
   我以前也用java开发过web service Q但是当初用了一个apache 下axis 开源项目。如果axis夜进化了Q反正我不认识了。不qjava自带有何必舍q求q呢。今天我把自己创徏的最单java webservice 范例q程记录下来Q与大家分n?br />
   我用的是netbeans 6Q首先徏立一个java 应用E序工程,名ؓWebServices。徏立一个服务端E序?br />
package  WebServices;

import  javax.jws. * ;
import  javax.xml.ws.Endpoint;

/**
 * 
@author  hecm
 
*/
@WebService(targetNamespace 
=   " http://www.aygfsteel.com/JAVA-HE " , serviceName  =   " HelloService " )
public   class  WSProvider
{

   
//  @WebResult(name = "Greetings") // 自定义该Ҏq回值在WSDL中相关的描述    
    @WebMethod(action  =   " sayHi " , operationName  =   " sayHi " )
    
public  String sayHi(@WebParam(name  =   " MyName " ) String name)
    {
        
return   " Hi, "   +  name;  // @WebParam是自定义参数name在WSDL中相关的描述

    }

    @Oneway 
// 表明该服务方法是单向?既没有返回?也不应该声明查异?/span>

    @WebMethod(action 
=   " printSystemTime " , operationName  =   " printSystemTime " ) // 自定义该Ҏ在WSDL中相关的描述
     public   void  printTime()
    {
        System.out.println(System.currentTimeMillis());
    }

    
public   static   void  main(String[] args)
    {
        Thread wsPublisher 
=   new  Thread( new  WSPublisher());
        wsPublisher.start();
    }

    
private   static   class  WSPublisher  implements  Runnable
    {

        
public   void  run()
        {
            
// 发布WSProvider到http: // localhost:8888/hechangmin/WSProviderq个地址,之前必须调用wsgen命o
            
// 生成服务cWSProvider的支持类,命o如下:
            
// wsgen -cp . WebServices.WSProvider
             Endpoint.publish("http://localhost:8888/JAVA-HE/WSProvider", new WSProvider());
     
}
    }
}

当然建立对应的包Q就不用说了?br /> 然后~译文g?br /> q入命o提示W下Q进入classes目录Q运行:wsgen -cp . WebServices.WSProvider

可以看到刚才的class 生成了几个java文g和class文g?br />
现在要做的是发布ws到http://localhost:8888/chinajash/WSProvider
而实际上的动作就是:Endpoint.publish("http://localhost:8888/chinajash/WSProvider",new WSProvider());
当然直接q行WSProvider ?br />
然后输入http://localhost:8888/JAVA-HE/WSProvider?wsdl

已l查看到生成的wsdl Qwebservice 描述语言Q?br />
也就是服务端OK了?br />
保持q行。编写一个测试客LQ?br />
首先选择目Q右键新?web服务客户端。其中ws url填入刚才生成的wsdl地址Q?br /> http://localhost:8888/JAVA-HE/WSProvider?wsdl

Q实际上Q和wsimport http://localhost:8888/JAVA-HE/WSProvider?wsdl 一L效果Q?br />

产生一个效果:在classes?按照 之前指定的名字空间生的包下Q目录结构)生成?个帮助class?br />
然后我们建立一个包 client 建立试文gQ?br />

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 
*/

package  client;

import  net.blogjava.java_he. * ;
/**
 *
 * 
@author  hecm
 
*/
public   class  Test {
    
public   static   void  main(String args[])
    {
        HelloService hs 
=   new  HelloService();
        WSProvider ws 
=  hs.getWSProviderPort();
        System.out.println(ws.sayHi(
" hechangmin " ));
        ws.printSystemTime();
    }

}


q行q个试c:
Hi,hechangmin

输出了。顺利完成!

一点个人经验,你发布的地址最好写成可配置。还有就是wsdl 中会严格按照你指定的url来访问,比如你指定的127.0.0.1 那么你用本机IP的时候也许ƈ不能利讉K?br />

posted on 2008-07-08 02:59 -274°C 阅读(880) 评论(1)  ~辑  收藏 所属分c? JAVA ?a href="http://www.aygfsteel.com/JAVA-HE/category/19891.html">JSP



CONAN 2008-07-08 23:02 发表评论
]]>
վ֩ģ壺 ̴| ȫ| | | Դ| | ֦| | | | | ÷| ڽ| | | ɽ| | ɽʡ| ګ| ŷ| ƽ½| | | ־| | | | | ʡ| | | μ| ƽ| կ| | ԫ| | | | | |