最近公司要做webservice,在网上看了不少资料,结果还是走了不少的弯路。分享下自己的经历:
一。webservice 简介:
1.思考 webservice是什么东西?干什么用的?
个人理解:它就像是 客户端与服务之间的桥梁,而它是夸平台的,不限于具体的客户端与服务器!
它提供了一系列的标准,可以根据这些标准 第三方提供了一些框架 诸如:xFire;Axis1.x/2.x ,这次开发我应用的Axis2
(如果想快点开发 可跳过下面的介绍){
待续
}
参考:http://wenku.baidu.com/link?url=3juCZHUdw5Egon9RTymNRzUHYNYiHxj8okRY6cLmT7PIFSVMkZ9FT1pddsoxuf5yWFrTKoeT332gEeDJ8HHyOnK8EbTdn03Zv7Gq5IEZXXG
2.怎么工作的?(如果想快点开发 可跳过){
待续
}
3.为什么会出现这东东(如果想快点开发 可跳过)
{
待续
}
二。建立helloWorld
1、去官网下载 需要的包(axis2-1.6.2-war.zip)这个就可以啦
将其解压后 放到tomcat webApps 中 启动 tomcat 。开始敲地址:http://localhost:8080/axis2/services/listServices
看到这个 页面 就说明部署成功啦!
ps:这个跟我们 要做的webservice 有毛关系?
这就是一个webservice 但是里面没有具体的服务。
2.填加 我们 自己的服务,并写我们 自己的客户端
首先我们需要些一个pojo, 类似这个样子
package com.bjsasc.webservice;
public class SimpleService
{
public String getGreeting(String name)
{
return "你好 " + name;
}
public int getPrice()
{
return new java.util.Random().nextInt(1000);
}
}
然后 在web-info文件夹里面,创建pojo文件夹,将编译好的SimpleService.class放到pojo文件夹里面!
重新启动tomcat,再次访问:
http://localhost:8080/axis2/services/listServices
问题:
1.重新启动tomcat 比较麻烦!
在web-info/conf 文件夹中axis2.xml 可以进行热部署配置.
<parameter name="hotupdate">true</parameter>
2.为什么还要新建一pojo文件夹?
在web-info/conf 文件夹中axis2.xml
<deployer extension=".class" directory="pojo" class="org.apache.axis2.deployment.POJODeployer"/>
如果想换名称 可以更改 directory 属性值
3.出现 faulty services 错误!
这是因为 这个类放在了 包下面!不要把这个类放到包下面。
正确的图是这个样子:
在真正的工程中,良好的写法是要将类放到固定的包下面的。所以这种方式不太适合我们真正的开发
我们可以用另一种发布webservice的方法:
注意目录结构:
<serviceGroup>
<service name="HelloWorld">
<description>
HelloWorld Service Example
</description>
<parameter name="ServiceClass">
com.dm.service.HelloWorld
</parameter>
<operation name="sayHello">
<messageReceiver class="org.apache.axis2.rpc.receivers.RPCMessageReceiver" />
</operation>
<operation name="saySorry">
<messageReceiver class="org.apache.axis2.rpc.receivers.RPCMessageReceiver" />
</operation>
<operation name="getWorld">
<messageReceiver class="org.apache.axis2.rpc.receivers.RPCInOnlyMessageReceiver" />
</operation>
</service>
<service name="SimpleService">
<description>
SimpleService Example
</description>
<parameter name="ServiceClass">
com.bjsasc.webservice.SimpleService
</parameter>
<operation name="getGreeting">
<messageReceiver class="org.apache.axis2.rpc.receivers.RPCMessageReceiver" />
</operation>
<operation name="getPrice">
<messageReceiver class="org.apache.axis2.rpc.receivers.RPCMessageReceiver" />
</operation>
</service>
</serviceGroup>
当然啦,你要把带有包的class 文件放到tomcat 中去!
继续访问http://localhost:8080/axis2/services/listServices
三。整合到项目中去
1.我们需要修改web.xml,添加下面的东东
<servlet>
<servlet-name>AxisServlet</servlet-name>
<display-name>Apache-Axis Servlet</display-name>
<servlet-class>org.apache.axis2.transport.http.AxisServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>AxisServlet</servlet-name>
<url-pattern>/servlet/AxisServlet</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>AxisServlet</servlet-name>
<url-pattern>*.jws</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>AxisServlet</servlet-name>
<url-pattern>/services/*</url-pattern>
</servlet-mapping>
2.添加 包 本人自己工程测试 最少需要这些包:
工程中引入进来,还有放到web-APP 的lib 文件中!
3.导入需要的文件夹:
4.开始写客户端:
一个简单的客户端看起来是这个样子滴:
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://127.0.0.1:8080/axis2/services/SimpleService");
options.setTo(targetEPR);
// 指定getGreeting方法的参数值
Object[] opAddEntryArgs = new Object[] {"chaoren"};
// 指定getGreeting方法返回值的数据类型的Class对象
Class[] classes = new Class[] {String.class};
// 指定要调用的getGreeting方法及WSDL文件的命名空间
QName opAddEntry = new QName("http://webservice.bjsasc.com", "getGreeting");
// 调用getGreeting方法并输出该方法的返回值
System.out.println(serviceClient.invokeBlocking(opAddEntry, opAddEntryArgs, classes)[0]);
// 下面是调用getPrice方法的代码,这些代码与调用getGreeting方法的代码类似
classes = new Class[] {int.class};
opAddEntry = new QName("http://webservice.bjsasc.com", "getPrice");
System.out.println(serviceClient.invokeBlocking(opAddEntry, new Object[]{}, classes)[0]);
}
开始运行吧!命名空间那个地方可能报错,凭你的聪明才智 肯定会解决啦
============================================================到此 一个小小的Demo 暂时告一段落==========================================
问题一:
服务端接收的数据类型比较简单,在真正的项目中我们可能用到List<Model> 类似这种复杂的数据传递
import java.util.ArrayList;
import java.util.List;
import javax.xml.namespace.QName;
import org.apache.axiom.om.OMAbstractFactory;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMFactory;
import org.apache.axiom.om.OMNamespace;
import org.apache.axis2.Constants;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.client.Options;
import org.apache.axis2.client.ServiceClient;
import org.apache.axis2.databinding.utils.BeanUtil;
import org.apache.axis2.transport.http.HTTPConstants;
public class PrintViewClient {
String urlStr ="http://127.0.0.1:8080/xxxxxxx/services/PrintViewService"
String methorName ="receivePrintViews";
EndpointReference targetEPR = new EndpointReference(urlStr);
/**
* 向服务端 发送数据
* 格式:List<Model>
*/
public void sendDataToService(){
try {
Options options = new Options();
options.setTo(targetEPR);
options.setTransportInProtocol(Constants.TRANSPORT_HTTP);
options.setProperty(HTTPConstants.CHUNKED, "false");//设置不受限制.
ServiceClient sender = new ServiceClient();
sender.setOptions(options);
System.out.println("printView client start");
OMElement omElement = doSetOMElement();
OMFactory fac = OMAbstractFactory.getOMFactory();
OMNamespace omNs = fac.createOMNamespace("", "");
OMElement method = fac.createOMElement(methorName, omNs);
method.addChild(omElement);
OMElement result = sender.sendReceive(method);
System.out.println("结果:"+result.getText());
sender.cleanupTransport();
System.out.println("printView client end");
} catch (Exception e) {
e.printStackTrace();
}
}
/**
*创建调用webservice接口所需的参数OMElement对象。
*
* @return
*/
public static OMElement doSetOMElement() {
//查询 客户 数据库 初始化成 List 集合
List<PrintView> list = new.....
String typeName = "computer";
// 构建 OMFactory 工厂
OMFactory factory = OMAbstractFactory.getOMFactory();
OMNamespace omNamespace = factory.createOMNamespace("http://webservice.bjsasc.com", "ns");
OMElement omElement = BeanUtil.getOMElement(new QName("root"), list.toArray(), new QName("PrintView"), false, null);
omElement.addAttribute("name", typeName, omNamespace);
return omElement;
}
}
问题二:
但服务端接收到数据的时候,如何与客户通信呢
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMNode;
import org.apache.axis2.AxisFault;
import org.apache.axis2.databinding.utils.BeanUtil;
import org.apache.axis2.engine.DefaultObjectSupplier;
/**
* 服务端 工具类
*
*/
public class ServiceUtil {
/**
* 将 客户端 传递过来的数据 转成 list 集合
* @param element 客户端数据
* @param model 对应服务端的模型
* @return
* @throws AxisFault
*/
public static List getResults(OMElement element,Class model) {
if (element == null) {
return null;
}
element = (OMElement) element.getChildElements().next(); // 下个元素
Iterator iterator = element.getChildElements();
List list = new ArrayList();
try {
while (iterator.hasNext()) {
OMNode omNode = (OMNode) iterator.next();
if (omNode.getType() == OMNode.ELEMENT_NODE) {
OMElement omElement = (OMElement) omNode;
Object object;
object = (Object)BeanUtil.processObject(omElement,model, null, true, new DefaultObjectSupplier());
list.add(object);
}
}
} catch (AxisFault e) {
e.printStackTrace();
}
return list;
}
}
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.util.List;
import org.apache.axiom.om.OMAbstractFactory;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMFactory;
import org.apache.axiom.om.OMNamespace;
import org.apache.log4j.Logger;
import com.cascc.avidm.util.UUIDService;
import com.cascc.platform.aa.DBUtility;
public class PrintViewService {
/**
* 服务接口
* @param userEle 客户端数据
* @return
* @throws Exception
*/
public OMElement receivePrintViews(OMElement userEle) {
System.out.println("进入 载体打印服务!");
List<PrintView> clientData = ServiceUtil.getResults(userEle,PrintView.class);
return synchroPrintView(clientData);
}
public OMElement synchroPrintView(List<PrintView> list){
//反馈 客户段 服务
OMFactory fac = OMAbstractFactory.getOMFactory();
OMNamespace omNs = fac.createOMNamespace("", "");
OMElement soapMain = fac.createOMElement("sendClient", omNs);
soapMain.setText("success");
try{
} catch (Exception e) {
e.printStackTrace();
soapMain.setText("fail");
} finally {
closeConnection(cs, ps, conn);
}
return soapMain;
}
}
问题三:
当这些东西都搞定的时候,我们还要写 文档来给客户使用,有没有一些更好方式呢