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_4\webapps下的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.53\webapps\axis\WEB-INF\attachments"/>
<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进阶(二)



Java WebService学习笔记 - Axis(一)的更多相关文章

  1. Java WebService学习笔记 - Axis进阶(二)

    上一篇  Java WebService学习笔记 - Axis(一) 前一篇博文中简单介绍了Axis的使用方法,这篇将介绍一些Axis的一些高级特性 Axis中Handler的使用 Handler ...

  2. 20145213《Java程序设计学习笔记》第六周学习总结

    20145213<Java程序设计学习笔记>第六周学习总结 说在前面的话 上篇博客中娄老师指出我因为数据结构基础薄弱,才导致对第九章内容浅尝遏止地认知.在这里我还要自我批评一下,其实我事后 ...

  3. [原创]java WEB学习笔记95:Hibernate 目录

    本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...

  4. java JDK8 学习笔记——助教学习博客汇总

    java JDK8 学习笔记——助教学习博客汇总 1-6章 (by肖昱) Java学习笔记第一章——Java平台概论 Java学习笔记第二章——从JDK到IDEJava学习笔记第三章——基础语法Jav ...

  5. java JDK8 学习笔记——第16章 整合数据库

    第十六章 整合数据库 16.1 JDBC入门 16.1.1 JDBC简介 1.JDBC是java联机数据库的标准规范.它定义了一组标准类与接口,标准API中的接口会有数据库厂商操作,称为JDBC驱动程 ...

  6. [原创]java WEB学习笔记75:Struts2 学习之路-- 总结 和 目录

    本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...

  7. [原创]java WEB学习笔记66:Struts2 学习之路--Struts的CRUD操作( 查看 / 删除/ 添加) 使用 paramsPrepareParamsStack 重构代码 ,PrepareInterceptor拦截器,paramsPrepareParamsStack 拦截器栈

    本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...

  8. Android(java)学习笔记267:Android线程池形态

    1. 线程池简介  多线程技术主要解决处理器单元内多个线程执行的问题,它可以显著减少处理器单元的闲置时间,增加处理器单元的吞吐能力.     假设一个服务器完成一项任务所需时间为:T1 创建线程时间, ...

  9. java多线程学习笔记——详细

    一.线程类  1.新建状态(New):新创建了一个线程对象.        2.就绪状态(Runnable):线程对象创建后,其他线程调用了该对象的start()方法.该状态的线程位于可运行线程池中, ...

随机推荐

  1. GNS3配置问题(持续更新)

    GNS3配置问题 1.关于All in One的GNS3提示"判断dynamips版本失败"的解决办法 当我们找到GNS3根目录里的dynamips.exe,执行会报错告诉我们缺少 ...

  2. [组合数学] 圆排列和欧拉函数为啥有关系:都是polya定理的锅

    本文是一个笨比学习组合数学的学习笔记,因为是笨比,所以写的应该算是很通俗易懂了. 首先,我们考虑这么一个问题:你有无穷多的\(p\)种颜色的珠子,现在你想要的把他们中的\(n\)个以圆形的形状等间距的 ...

  3. JAVASE(十六) IO流 :File类、节点流、缓冲流、转换流、编码集、对象流

    个人博客网:https://wushaopei.github.io/    (你想要这里多有) 1.File类型 1.1.File类的理解 File类是在java.io包下 File可以理解成一个文件 ...

  4. background-color的覆盖范围

    1. 一般div的background-color覆盖范围 到 border,margin的颜色由外层元素决定 2. body的background-color覆盖范围 到 margin,但 当htm ...

  5. elasticsearch中保存时间格式

    利用logstash从文档中导入数据到es中,若未事先设定数据格式,有可能存储时间并未保存为date格式而是text格式. 时间若保存为text,则在会以字符串数组格式存储在es中,是乱序,不好查询. ...

  6. 如何获取CSDN的积分?

    个人感觉就是写博客就给积分 具体给多少? CSDN应该有自己的积分规则 总之一句话:写博客涨积分

  7. Java实现 蓝桥杯 算法提高 P0101

    算法提高 P0101 时间限制:1.0s 内存限制:256.0MB 提交此题  一个水分子的质量是3.0*10-23克,一夸脱水的质量是950克.写一个程序输入水的夸脱数n(0 <= n &l ...

  8. Java实现 LeetCode 399 除法求值

    399. 除法求值 给出方程式 A / B = k, 其中 A 和 B 均为代表字符串的变量, k 是一个浮点型数字.根据已知方程式求解问题,并返回计算结果.如果结果不存在,则返回 -1.0. 示例 ...

  9. Java实现 蓝桥杯 算法训练 纪念品分组

    问题描述 元旦快到了,校学生会让乐乐负责新年晚会的纪念品发放工作.为使得参加晚会的同学所获得的纪念品价值 相对均衡,他要把购来的纪念品根据价格进行分组,但每组最多只能包括两件纪念品,并且每组纪念品的价 ...

  10. Java实现 LeetCode 14 最长公共前缀

    14. 最长公共前缀 编写一个函数来查找字符串数组中的最长公共前缀. 如果不存在公共前缀,返回空字符串 "". 示例 1: 输入: ["flower",&quo ...