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进阶(二)

    
  • 相关阅读:
    HYSBZ 3813 奇数国
    HYSBZ 4419 发微博
    HYSBZ 1079 着色方案
    HYSBZ 3506 排序机械臂
    HYSBZ 3224 Tyvj 1728 普通平衡树
    Unity 3D,地形属性
    nginx 的naginx 种包含include关键字
    Redis 出现NOAUTH Authentication required解决方案
    mysql 8.0出现 Public Key Retrieval is not allowed
    修改jar包里的源码时候需要注意的问题
  • 原文地址:https://www.cnblogs.com/ssp2110/p/3797670.html
Copyright © 2011-2022 走看看