zoukankan      html  css  js  c++  java
  • Java WebService学习笔记

    WebService 简介

    实际开发中,很多系统都是基于历史遗留系统进行开发,有时,这些系统基于不同的语言,如C,C++,C#,java,PHP等等。为了实现历史系统的再利用,或向外部程序暴露调用接口,于是就产生了WebService规范。WebService用于实现系统的透明访问,其最终目的:实现异构系统间通信。

    单从Java方面考虑,实现WebService的方法有jdk1.6版本添加的JWS,Axis1/2,XFIRE,Celtix,CXF(Xfire和Celtix的整合)。

    综合来看Axis1,Xfire,Celtix成熟但即将退出的版本。内置的JWS,Axis和CXF却也不是很成熟(哎,青黄不接)。


    Apache Axis1实现WebService

    当利用Java版Axis有两个途径,以Java码作为Web服务。最简单的一种是使用原生的jws(Java Web Service的文件)。另一种方法是使用定制的部署文件。定制部署让您能自选资源,什么要予以曝光。

    第一种实现方式:即时发布

    实现此功能需要借助 axis-1_4webapps下的axis工程,将其部署到apache服务器webapps目录下。

    原生的jws和java源代码的唯一区别是后缀名,当然采用这种方式也不能使用package进行打包.下面提供简单的原生jws和远程调用实现。

    Hello.jws内容:

    public class Hello
    {
    	public String sayHello(String name)
    	{
    		StringBuffer greeting = new StringBuffer("Hello ");
    		if ( name != null )
    		{
    			greeting.append(name);
    		}
    		greeting.append(", nice to see you!");
    		return greeting.toString();
    	}
    }
    将Hello.jws文件放到apache服务器webapps/axis/目录下,启动服务器。

    通过 http://localhost:8080/axis/Hello.jws?wsdl 可以获得Hello.jws的WebService定义,内容如下

    <?xml version="1.0" encoding="UTF-8"?>
    <wsdl:definitions targetNamespace="http://localhost:8080/axis/Hello.jws" 
     xmlns:apachesoap="http://xml.apache.org/xml-soap" 
     xmlns:impl="http://localhost:8080/axis/Hello.jws" 
     xmlns:intf="http://localhost:8080/axis/Hello.jws" 
     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 created by Apache Axis version: 1.4
    Built on Apr 22, 2006 (06:55:48 PDT)-->
    
       <wsdl:message name="sayHelloResponse">
    
          <wsdl:part name="sayHelloReturn" type="xsd:string"/>
    
       </wsdl:message>
    
       <wsdl:message name="sayHelloRequest">
    
          <wsdl:part name="name" type="xsd:string"/>
    
       </wsdl:message>
    
       <wsdl:portType name="Hello">
    
          <wsdl:operation name="sayHello" parameterOrder="name">
    
             <wsdl:input message="impl:sayHelloRequest" name="sayHelloRequest"/>
    
             <wsdl:output message="impl:sayHelloResponse" name="sayHelloResponse"/>
    
          </wsdl:operation>
    
       </wsdl:portType>
    
       <wsdl:binding name="HelloSoapBinding" type="impl:Hello">
    
          <wsdlsoap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
    
          <wsdl:operation name="sayHello">
    
             <wsdlsoap:operation soapAction=""/>
    
             <wsdl:input name="sayHelloRequest">
    
                <wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://DefaultNamespace" use="encoded"/>
    
             </wsdl:input>
    
             <wsdl:output name="sayHelloResponse">
    
                <wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://localhost:8080/axis/Hello.jws" use="encoded"/>
    
             </wsdl:output>
    
          </wsdl:operation>
    
       </wsdl:binding>
    
       <wsdl:service name="HelloService">
    
          <wsdl:port binding="impl:HelloSoapBinding" name="Hello">
    
             <wsdlsoap:address location="<span style="color:#FF0000;">http://localhost:8080/axis/Hello.jws</span>"/>
    
          </wsdl:port>
    
       </wsdl:service>
    
    </wsdl:definitions>
    
    至此,简单的Service端就部署成功了,接下来要通过一段程序对Hello.jws进行访问。

    使用eclipse创建一个java project,并添加jar包,必须的jar包包括axis.jar;jaxrpc.jar;commons-loggin-1.x.jar;commons-discovery-0.x.jar

    import javax.xml.namespace.QName;
    
    import org.apache.axis.client.Call;
    import org.apache.axis.client.Service;
    
    public class HelloClient {
    
    	public static void main(String[] args) {
    		System.out.println(new HelloClient().sayHello("Han MeiMei"));
    	}
    
    	public String sayHello(String name)
    	{
    		String result = null;
    		try
    		{
    			//1.设置远程访问链接
    			String url = "http://localhost:8080/axis/Hello.jws";
    			//2.获取Service对象
    			Service service = new Service();
    			//3.通过Service对象获取远程调用对象Call
    			Call call = (Call) service.createCall();
    			//4.设置远程调用桩
    			call.setTargetEndpointAddress(url);
    			//5.设置远程操作方法名
    			call.setOperationName(new QName(url, "sayHello"));
    			//6.设置参数,执行远程方法
    			result = (String)call.invoke(new Object[]{name});
    		}
    		catch(Exception e)
    		{
    			e.printStackTrace();
    		}
    		
    		return result;
    	}
    }

    执行结果如下:

    May 19, 2014 2:11:40 PM org.apache.axis.utils.JavaUtils isAttachmentSupported
    WARNING: Unable to find required classes (javax.activation.DataHandler and javax.mail.internet.MimeMultipart). Attachment support is disabled.
    <span style="color:#FF0000;">Hello Han MeiMei, nice to see you!</span>
    第二种实现方式:定制发布

    第一种发布方式比较快捷,发布方式简单,但有以下缺点

    1.必须要有源文件,同时不能包含package结构

    2.发布之后所有方法均开放,不可控制

    针对以上缺点,axis提供定制发布方式,具体步骤如下

    编写Hello.java类

    package com.webservice.wsdd;
    
    public class Hello
    {
        public String sayHello(String name)
        {
            StringBuffer greeting = new StringBuffer("Hello ");
            if(name != null)
            {
                greeting.append(name);
            }
            greeting.append(",nice to see you!");
            
            return greeting.toString();
        }
        
        public int add(int a,int b)
        {
            return a + b;
        }
    }

    使用命令行进行编译,得到class文件(包括包)

    javac -d ./ Hello.java

    com包所有内容拷贝到apache服务器webapps/axis/WEB-INF/classes下。

    编写hello.wsdd配置文件,放置到webapps/axis/WEB-INF/classes/com下   WSDD文档具体意义可查看Axis WSDD文件参考文档

    <deployment name="test" xmlns="http://xml.apache.org/axis/wsdd/" 
        xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">
      <!--Service name:服务名称,自己确定-->
      <service name="Hello" provider="java:RPC">
        <!--parameter 
            className:类路径及名称
            allowedMethods:可以指定方法名,也可以使用×代表全部
        -->
        <parameter name="className" value="com.webservice.wsdd.Hello" />
        <!-- 定制方法,此处指定制sayHello方法 -->
        <parameter name="allowedMethods" value="sayHello" />
      </service>
    
    </deployment><span style="color:#FF0000;"><strong></strong></span>
    启动服务器,进入到hello.wsdd位置,使用命令生成server-config.wsdd配置文件

    java org.apache.axis.client.AdminClient hello.wsdd  --需要自己配置classpath环境变量

    生成的server-config.wsdd配置文件位于webapps/axis/WEB-INF/路径下,内容如下,如果不想生成,也可以拷贝一份放在该路径下

    <?xml version="1.0" encoding="UTF-8"?>
    <deployment xmlns="http://xml.apache.org/axis/wsdd/" xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">
     <globalConfiguration>
      <parameter name="sendMultiRefs" value="true"/>
      <parameter name="disablePrettyXML" value="true"/>
      <parameter name="adminPassword" value="admin"/>
      <parameter name="attachments.Directory" value="E:apache-tomcat-7.0.53webappsaxisWEB-INFattachments"/>
      <parameter name="dotNetSoapEncFix" value="true"/>
      <parameter name="enableNamespacePrefixOptimization" value="false"/>
      <parameter name="sendXMLDeclaration" value="true"/>
      <parameter name="sendXsiTypes" value="true"/>
      <parameter name="attachments.implementation" value="org.apache.axis.attachments.AttachmentsImpl"/>
      <requestFlow>
       <handler type="java:org.apache.axis.handlers.JWSHandler">
        <parameter name="scope" value="session"/>
       </handler>
       <handler type="java:org.apache.axis.handlers.JWSHandler">
        <parameter name="scope" value="request"/>
        <parameter name="extension" value=".jwr"/>
       </handler>
      </requestFlow>
     </globalConfiguration>
     <handler name="URLMapper" type="java:org.apache.axis.handlers.http.URLMapper"/>
     <handler name="LocalResponder" type="java:org.apache.axis.transport.local.LocalResponder"/>
     <handler name="Authenticate" type="java:org.apache.axis.handlers.SimpleAuthenticationHandler"/>
     <service name="AdminService" provider="java:MSG">
      <parameter name="allowedMethods" value="AdminService"/>
      <parameter name="enableRemoteAdmin" value="false"/>
      <parameter name="className" value="org.apache.axis.utils.Admin"/>
      <namespace>http://xml.apache.org/axis/wsdd/</namespace>
     </service>
     <service name="Version" provider="java:RPC">
      <parameter name="allowedMethods" value="getVersion"/>
      <parameter name="className" value="org.apache.axis.Version"/>
     </service>
    <span style="background-color: rgb(255, 255, 51);"> <service name="Hello" provider="java:RPC">
      <parameter name="allowedMethods" value="sayHello"/>
      <parameter name="className" value="com.webservice.wsdd.Hello"/>
     </service></span>
     <transport name="http">
      <requestFlow>
       <handler type="URLMapper"/>
       <handler type="java:org.apache.axis.handlers.http.HTTPAuthHandler"/>
      </requestFlow>
      <parameter name="qs:list" value="org.apache.axis.transport.http.QSListHandler"/>
      <parameter name="qs:wsdl" value="org.apache.axis.transport.http.QSWSDLHandler"/>
      <parameter name="qs.list" value="org.apache.axis.transport.http.QSListHandler"/>
      <parameter name="qs.method" value="org.apache.axis.transport.http.QSMethodHandler"/>
      <parameter name="qs:method" value="org.apache.axis.transport.http.QSMethodHandler"/>
      <parameter name="qs.wsdl" value="org.apache.axis.transport.http.QSWSDLHandler"/>
     </transport>
     <transport name="local">
      <responseFlow>
       <handler type="LocalResponder"/>
      </responseFlow>
     </transport>
    </deployment>
    

    使用http://localhost:8080/axis/services/Hello?wsdl 可以查看WebService描述,内容如下

    <?xml version="1.0" encoding="UTF-8"?>
    <wsdl:definitions targetNamespace="http://localhost:8080/axis/services/Hello" xmlns:apachesoap="http://xml.apache.org/xml-soap" xmlns:impl="http://localhost:8080/axis/services/Hello" xmlns:intf="http://localhost:8080/axis/services/Hello" 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 created by Apache Axis version: 1.4
    Built on Apr 22, 2006 (06:55:48 PDT)-->
    
       <wsdl:message name="sayHelloResponse">
    
          <wsdl:part name="sayHelloReturn" type="soapenc:string"/>
    
       </wsdl:message>
    
       <wsdl:message name="sayHelloRequest">
    
          <wsdl:part name="in0" type="soapenc:string"/>
    
       </wsdl:message>
    
       <wsdl:portType name="Hello">
    
          <wsdl:operation name="sayHello" parameterOrder="in0">
    
             <wsdl:input message="impl:sayHelloRequest" name="sayHelloRequest"/>
    
             <wsdl:output message="impl:sayHelloResponse" name="sayHelloResponse"/>
    
          </wsdl:operation>
    
       </wsdl:portType>
    
       <wsdl:binding name="HelloSoapBinding" type="impl:Hello">
    
          <wsdlsoap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
    
          <wsdl:operation name="sayHello">
    
             <wsdlsoap:operation soapAction=""/>
    
             <wsdl:input name="sayHelloRequest">
    
                <wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://wsdd.webservice.com" use="encoded"/>
    
             </wsdl:input>
    
             <wsdl:output name="sayHelloResponse">
    
                <wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://localhost:8080/axis/services/Hello" use="encoded"/>
    
             </wsdl:output>
    
          </wsdl:operation>
    
       </wsdl:binding>
    
       <wsdl:service name="HelloService">
    
          <wsdl:port binding="impl:HelloSoapBinding" name="Hello">
    
             <wsdlsoap:address location="<span style="color:#FF0000;">http://localhost:8080/axis/services/Hello</span>"/>
    
          </wsdl:port>
    
       </wsdl:service>
    
    </wsdl:definitions>
    

    此时定制服务发布完成。

    访问方式只需把第一步的访问链接替换成上面红字部分即可

    补充:开发中,有时候需要通过WebService传递对象,此时的处理方式与上述方法又有不同

    Axis处理对象参数/返回值

    编写Question.java和Answer.java   注意:Bean对象一定要实现Serializable接口。

    package com.webservice.wsdd;
    
    import java.io.Serializable;
    
    @SuppressWarnings("serial")
    public class Question implements Serializable
    {
    	private int id;
    	
    	private String question;
    	
    	private String answer;
    	
    	public void setId(int id)
    	{
    		this.id = id;
    	}
    	
    	public int getId()
    	{
    		return this.id;
    	}
    	
    	public void setQuestion(String question)
    	{
    		this.question = question;
    	}
    	
    	public String getQuestion()
    	{
    		return this.question;
    	}
    	
    	public void setAnswer(String answer)
    	{
    		this.answer = answer;
    	}
    	
    	public String getAnswer()
    	{
    		return this.answer;
    	}
    }

    package com.webservice.wsdd;
    
    public class Answer
    {
    	public Question answerQuestion(Question question)
    	{
    		Question tmp = question;
    		
    		doRead(tmp);
    		tmp.setAnswer("do not know the answer!");
    		
    		return tmp;
    	}
    	
    	private void doRead(Question question)
    	{
    		System.out.println("read question:"+question.getQuestion());
    	}
    }

    编译后放到服务器classes目录下,在server-config.wsdd中注册服务,较之前多了红字部分。

            <service name="Answer" provider="java:RPC">
    		<parameter name="className" value="com.webservice.wsdd.Answer"/>
    		<parameter name="allowedMethods" value="*"/>
    		<span style="color:#FF0000;"><!-- 
    			qname:自定义bean名称
    			xmlns:自定义的xml命名空间,xmlns冒号后面部分取自qname属性,必须要有,否则报错
    			languageSpecificType:语言类型及类路径
    		-->
    		<beanMapping
    			qname="bean:Question"
    			xmlns:bean="BeanManger"
    			languageSpecificType="java:com.webservice.wsdd.Question"
    		/></span>
    	</service>

    启动服务器,服务发布成功。可以在 http://localhost:8080/axis/servlet/AxisServlet 下查看到该服务

    客户端代码QuestionClient.java

    package com.client;
    
    import javax.xml.namespace.QName;
    import javax.xml.rpc.ParameterMode;
    
    import org.apache.axis.client.Call;
    import org.apache.axis.client.Service;
    import org.apache.axis.encoding.ser.BeanDeserializerFactory;
    import org.apache.axis.encoding.ser.BeanSerializerFactory;
    
    import com.webservice.wsdd.Question;
    
    public class QuestionClient {
    
    	public static void main(String[] args) {
    		Question question = new Question();
    		question.setQuestion("先有鸡还是先有蛋!");
    		
    		new QuestionClient().askAndAnswer(question);
    	}
    
    	/**
    	 * @param question
    	 */
    	public void askAndAnswer(Question question)
    	{
    		String url = "http://localhost:8080/axis/services/Answer";
    		Service service = new Service();
    		
    		try
    		{
    			Call call = (Call)service.createCall();
    			
    			call.setTargetEndpointAddress(url);
    			
    			//注册Bean及序列化和反序列化工程映射关系
    			QName qname = new QName("bean:BeanManger","Question");
    			call.registerTypeMapping(Question.class, qname, 
    					new BeanSerializerFactory(Question.class, qname),
    					new BeanDeserializerFactory(Question.class, qname)
    			);
    			call.setOperationName(new QName(url, "answerQuestion"));
    			call.setReturnClass(Question.class);
    			
    			//设置调用方法的参数
    			call.addParameter("question", qname, ParameterMode.IN);
    			
    			Question tmp = (Question)call.invoke(new Object[]{question});
    			
    			if(tmp!=null)
    			{
    				System.out.println("Question:"+tmp.getQuestion());
    				System.out.println("Answer:"+tmp.getAnswer());
    			}
    		}
    		catch(Exception e)
    		{
    			e.printStackTrace();
    		}
    	}
    }
    

    执行结果:

    Question:先有鸡还是先有蛋!
    Answer:do not know the answer!

    下一篇  Java WebService学习笔记 - Axis进阶(二)

    
  • 相关阅读:
    微信分享链接出现config:invalid signature错误的解决方法
    微信开发,分享部分出现的问题
    thinkphp 3.2 去除调试模式后报错,怎么解决
    MySQL添加新用户、为用户创建数据库、为新用户分配权限
    xshell工具source导入几个G的数据库
    thinkphp5引入公共部分header、footer等
    用样本估计总体
    随机抽样
    平面几何相关定理
    直线和曲线相切,曲线和曲线相切
  • 原文地址:https://www.cnblogs.com/ssp2110/p/3797670.html
Copyright © 2011-2022 走看看