WebService 学习

(一) WebService

WebService课程由徐培成老师主讲,依然发扬传智播客的特点——深入理论和实践。今天老徐讲的原理的专业术语比较多,但我只做WebService的应用总结。如果你的JavaJavaWeb基础好些,我想你看到WebService的应用,自然就能想到它的实现原理。

WebService又是一种高级应用,与之前学习的StrutsSpringHibernate等框架不同。WebService是面向服务的架构(SOA),看起来像是比SSH框架要大。那么它到底是做什么用的?什么才是面向服务的架构?

让我们来看一种需求,集团公司可能具有多种WEB应用。比如,前年开发了个进销存系统、去年开发了一个ERP、今年又开发了一个OA。现在这家集团公司需要将这三个系统整合,难道需要重新编码将它们整合吗?而这三个系统又是用不同语言编写的,这种成本对公司来说无疑是一种浪费。WebService可以很好的解决这种需求。

WebService是可以进行跨语言、跨平台、分布式系统间整合的方案,WebService像是一条线将这些系统穿起来——企业服务总线(ESB)。WebService使用简单对象访问协议(SOAP)使用http协议传输xml数据(xml是最常用的,也有其他格式数据。)来完成系带间的整合。

什么是整合?当然是功能和数据的整合,也就是一个系统可以调用另一个系统的WebService接口来完成数据的交互。这样我们就需要知道,提供WebService服务功能的应用公开了哪些接口,我们可以通过WebService描述文档(WSDL)得知。WSDL不需要我们手动编写,JavaWebService实现可以为我们自动生成。JDK1.6新增支持WebService,但还不够成熟。所以我们使用Apache第三方开源组织提供的WebService实现——Axis

Axis的当前版本是Java版本,它的C++版本正在开发中。Axis是一个功能强大的soap引擎,关于它们的详细信息在此就不做介绍了。下面,让我们来编写一个例子程序,以了解WebService的应用流程。

一、编写支持WebServiceWEB应用

1.创建工程

Project Name:TestWebService

Target runtime:Apache Tomcat V6.0

其他的默认

2.添加AxisJar

axisjar包目录lib子目录中的所有jar文件添加到工程中。

3.配置web.xml

axiswebapps子目录中有一个axisWeb应用,我们直接使用它的web.xml文件内容。

4.添加功能类

packagecom.changcheng.webservice;

importcom.changcheng.webservice.entity.User;

publicclassTestWebService {

/**

*基本数据的远程

*@paramwords

*@return

*/

publicString hello(String words) {

return"WebService say: hello "+ words;

}

/**

*

*@paramuser

*@return

*/

publicUser update(User user){

System.out.println(user);

user.setName("new_name_haha");

user.setPassword("new_password_123");

returnuser;

}

}

其中使用到的User实体类在此就不列出了。

5.部署WebService

我们可以将需要公开的类文件复制到WEB应用目录下,并修改文件后缀名为jws。把类文件更名并放到WEB目录下?这样做并不好,它被暴露了。

所以在这里我们使用一个常量的部署方法,在工程中(根目录)添加一个deploy.wsdd文件:

<!--部署描述符 -->

<deploymentxmlns="http://xml.apache.org/axis/wsdd/"

xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">

<!--定义处理器 -->

<handlername="track"type="java:com.changcheng.webservice.handler.LogHandler">

<parametername="filename"value="d:/MyService.log"/>

</handler>

<!--定义服务,并且在服务中使用处理器 -->

<servicename="HandlerService"provider="java:RPC">

<requestFlow>

<handlertype="track"/>

</requestFlow>

<parametername="className"value="com.changcheng.webservice.TestWebService"/>

<parametername="allowedMethods"value="*"/>

</service>

</deployment>

首先将工程部署到Tomcat服务器上,并启动Tomcat服务器。然后在工程上右键-->Run As...-->Run Configurations...,新建一个JavaApplication。在main页面中,project指定为我们的TestWebServiceMainClass指定为org.apache.axis.client.AdminClient。在Arguments页面下设置Program arguments-l http://localhost:8080/TestWebService/servlet/AxisServlet deploy.wsdd。点击Run按钮。

完成上面的操作后,AdminClient会为我们部署在TomcatTestWebServiceWEB-INF目录下生成一个server-config.wsdd文件,它是提供给Axis使用的配置文件。

我们需要将向server-config.wsdd文件的HandlerService元素添加一个beanMapping子元素:

<service name="HandlerService" provider="java:RPC">

<requestFlow>

<handler type="track"/>

</requestFlow>

<parameter name="allowedMethods" value="*"/>

<parameter name="className" value="com.changcheng.webservice.TestWebService"/>

<beanMapping qname="myNS:User" xmlns:myNS="urn:pojo:ws:changcheng:com" languageSpecificType="java:com.changcheng.webservice.entity.User"/>

</service>

其中的添加的处理器是WebService的一项功能,在远程调用指定的方法时,会先由处理器进行处理。

packagecom.changcheng.webservice.handler;

importjava.io.FileOutputStream;

importjava.io.PrintWriter;

importjava.text.SimpleDateFormat;

importjava.util.Date;

importorg.apache.axis.AxisFault;

importorg.apache.axis.Handler;

importorg.apache.axis.MessageContext;

importorg.apache.axis.handlers.BasicHandler;

/**

*日志处理器,类似于web中的filter

*/

publicclassLogHandlerextendsBasicHandler {

privatestaticfinallongserialVersionUID= 3227593680689235885L;

publicvoidinvoke(MessageContext arg0)throwsAxisFault {

try{

Handler serviceHandler = arg0.getService();

//提取配置文件(server-config)的配置信息

String filename = (String) getOption("filename");

//

FileOutputStream fos =newFileOutputStream(filename);

PrintWriter writer =newPrintWriter(fos);

// getOption()类似于request.getAttribute("")

//获得在handler对象中存放的访问次数

Integer numAccesses = (Integer) serviceHandler

.getOption("accesses");

//如果首次访问

if(numAccesses ==null)

numAccesses =newInteger(0);

//次数 ++

numAccesses =newInteger(numAccesses.intValue() + 1);

//

Date date =newDate();

//对日期进行格式化

SimpleDateFormat sdf =newSimpleDateFormat();

sdf.applyPattern("yyyy-MM-dd hh:mm:ss");

String result = sdf.format(date) +": service "

+ arg0.getTargetService() +" accessed "+ numAccesses

+" time(s).";

//将访问次数写入到handler对象中(request.setAttribute(..));

serviceHandler.setOption("accesses", numAccesses);

writer.println(result);

writer.close();

}catch(Exception e) {

throwAxisFault.makeFault(e);

}

}

}

二、编写运程调用WebServiceWEB应用的Java工程

1.添加上面WEB工程中所用到的Axisjar

2.编写测试类:

packagecom.changcheng.client;

importjava.net.URL;

importjavax.xml.namespace.QName;

importorg.apache.axis.client.Call;

importorg.apache.axis.client.Service;

importorg.apache.axis.encoding.ser.BeanDeserializerFactory;

importorg.apache.axis.encoding.ser.BeanSerializerFactory;

importorg.junit.Test;

importcom.changcheng.webservice.entity.User;

publicclassTestMain {

//测试一般方法

@Test

publicvoidhello()throwsException{

Service s =newService();

Call call = (Call) s.createCall();

String url ="http://localhost:8080/TestWebService/services/HandlerService";

call.setTargetEndpointAddress(newURL(url));

call.setOperationName("hello");

Object res = call.invoke(newObject[] {"itcast"});

System.out.println(res);

}

//测试实体方法

@Test

publicvoidupdate()throwsException {

Service s =newService();

Call call = (Call) s.createCall();

String url ="http://localhost:8080/TestWebService/services/HandlerService";

call.setTargetEndpointAddress(newURL(url));

call.setOperationName("update");

//客户端同样需要对pojo进行注册.以确保也能够进行序列化和反序列化.

Class clazz = User.class;

//限定名必须和服务器端注册限定名保持一致,严格区分大小写

QName qname =newQName("urn:pojo:ws:changcheng:com","User");

//注册类型映射,以便传递pojo对象

call.registerTypeMapping(clazz, qname,newBeanSerializerFactory(clazz,

qname),newBeanDeserializerFactory(clazz, qname));

//

User user =newUser();

user.setName("itcast");

user.setPassword("abcd");

Object res = call.invoke(newObject[] { user });

System.out.println(res);

}

}




3.运行测试

总结完成!

(二) WebService

今日继续我们的Axis学习,我只进行一下简单的总结。有机会再补上吧!

昨天我们学习了,使用WebService进行运程调用,传递基本类型数据和类实体数据。在传递基本数据类型时,我们不需要进行任何操作。但在传递类实体类型数据时,我们需要在服务器端和客户端进行序列化和反序列化注册。那还有哪些数据传递是我们需要注意的?

基本数据类型数组和集合、类类型数组和集合、远程异常。在传递基本类型数组或集合时,我们不需要添加任何声明。但在传递类类型数组或集合时,需要添加与传递类实例进行相同的注册。远程异常应该如何传递?

远程异常,需要通过fault元素注册一个 远程异常。

上面我们对基本数据类型和类类型的简单传输有了基本的认识,但是复合类型应该如何传递呢?类套类,这样下去,难道我们需要手动添加注册信息吗?当然不需要,Axis为我们提供了相应的工具,通过WSDL生成客户端和服务器端Java类,通过Java类(接口)生成WSDL文档,在此我就不详细总结了。

除了Axis,老徐又给我们介绍了xfire,它也是WebService的一种实现工具。在此也不做总结了。

有位网友跟我说还有一种WebService——xcf,是目前最流行的,我并未对此进行埋阅。但我想说的是,以后可能还会有其他流行的WebService实现,但无论出什么样的新东西,它的核心思想都是一样的。这也是我来传智学习的一大原因,如果只知道一种工具如何使用,而不知道它的道理,确实不高明。如果掌握了它的道理,那就是以不变应万变了


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值