???? 最近接触到了两种WebService开发的方式,想自己好好总结,以加深理解,自己接触也不是很久,也许有误,请大家指教。
????? 好,废话少说,直入正题。首先说明我不是讲xFire或者Axis等区别,而是WebService开发的两种方式:实时和非实时:
?
?
????? 一. 实时:实时也就是我们直接调用服务,即调用—>响应模式。什么时候调用由我们自己是否触发来决定,下面来说说具体实现的过程:
?
以一个jsp前台页面为例,假设此页面有个按钮,点击此按钮即可调用我们的接口服务。按钮以一个Action(假设为testAction.jsp)响应,其中可以用以下方式包含一个jsp页面:??<%@ include file="/process/actionPage/gmcc/test.jsp"%>。在此页面中我们可以把需要传入的参数组装好,具体是组长成xml,map还是其他类型数据自己具体决定。好,关键时刻到了,我们在test.jsp页面就可以直接
引用一个我们调用接口的服务java类<%@ page import = "outersystem.service.impl.OutSystemClient"%>
在OutSystemClient.java代码中调用我们的接口服务类的关键步骤如下:
用Axis:?Call call = WebServiceClient.getCall(url,outSystemPackage,?methodName);
用xFire:Object client = WebServiceClient.getClient(url,?outSystemPackage);
?
WebServiceClient类的具体实现:
public class WebServiceClient {
?/**
? * 掉用第三方数webService 统一接口,适用于Axis方式调用
? *?
? * */
?
?public static Call getCall(String url,String qName,String method) throws Exception{
??Call call = null;
??Service service1 = new Service();
??call = (Call) service1.createCall();
??call.setOperationName(new QName(qName,method));
??call.setTargetEndpointAddress(new java.net.URL(url));
??return? call;
?}
?
?/**
? * 掉用第三方数webService 统一接口,适用于XFire方式调用
? *?
? * */
?public static Object getClient(String url,String classPath) throws Exception {
??Class serviceClass=Class.forName(classPath);
??org.codehaus.xfire.service.Service serviceModel=new ObjectServiceFactory().create(serviceClass);
??XFire xfire=XFireFactory.newInstance().getXFire();
??XFireProxyFactory factory=new XFireProxyFactory(xfire);
??Object client=factory.create(serviceModel,url);
??return client;
?}
}
?
好了,实时调用基本完成,这只是一个思路,具体实现可以灵活。总结:我们通过响应jsp的Action可以直接调用我们的服务java类。这样就达到了实时。
?
?
?
?二. 非实时:非实时也就是我们不直接调用服务,由Servlet调用线程。线程周期性调用我们的服务(例如,我操作了表,使得表中有符合要求的数据,线程一扫描到就提取数据,组装数据,调用接口)。这是周期性的,不是你触发他就响应的。具体实现方法如下:
?
在web.xml中加入我们开发的servlet类:
?? <servlet>?
??? <servlet-name>appealcentersyncinitservlet</servlet-name>?
??? <servlet-class>?
??????? client.servlet.SyncInitServlet
??? </servlet-class>?
? <load-on-startup>99</load-on-startup>
? </servlet>
?
SyncInitServlet类实现:
public class SyncInitServlet extends HttpServlet {
?private static WebServiceLogger logger = WebServiceLogger.getLogger("gjkf");
?/**
? * serialVersionUID 序列化接口的版本号
? */
?private static final long serialVersionUID = 1L;
?public void init() throws javax.servlet.ServletException {
??
???? NewWorkSheetThread.getInstance().start();??
??logger.info("1线程启动。。。");
??
??BranchSheetThread.getInstance().start();??
??logger.info("2线程启动。。。");
??
??UpgradeSheetThread.getInstance().start();??
??logger.info("3线程启动。。。");
??
??AddNoteSheetThread.getInstance().start();??
??logger.info("4线程启动。。。");
??
??SuspendWorkSheetThread.getInstance().start();
??logger.info("5线程启动。。。");
??DisSuspendThread.getInstance().start();
??logger.info("6线程启动。。。");
????//工单反馈线程初始化
??logger.info("webservice线程初始化...");
??new Thread(new HastenFeedBackThread()).start();
??
??//故障单销障操作
??
??logger.info("webservice线程初始化...");
??new Thread(new FaultCloseThread()).start();
?????
?}
}
这样我们就启动了线程。以NewWorkSheetThread线程为例,实现如下:
public class NewWorkSheetThread extends Thread?
{
?private static WebServiceLogger logger = WebServiceLogger.getLogger("gjkfNewWork");
?private static NewWorkSheetThread thread = null;
?
?private NewWorkSheetThread()?
?{
?}
?/**
? * 获取线程实例
? * @return
? */
?public static NewWorkSheetThread getInstance()?
?{
??if (thread == null)?
??{
???thread = new NewWorkSheetThread();
???// changes the default name of this thread to EOMSNewWorkSheetThread
???thread.setName("NewWorkSheetThread");
??}
??return thread;
?}
?public void run()?
?{
??try?
??{
???sleep(5000);
???// 判断是否启用
???boolean sys_startNewWorkSheetThread = "true".equalsIgnoreCase(SysParameter.getValue("sys_startNewWorkSheetThread"));
???while (sys_startNewWorkSheetThread)?
???{
????try?
????{
?????//?调用
?????String returnValue = GJKFClient.callNewWorkSheet(null,
?????????"client.GJKFCaller");
?????if (returnValue.equals(KeyConstant.CLIENT_INVOKE_SUCCESS))
?????{
??????logger.info("调用WEBSERVICE 接口成功,并且接口返回正确结果");
?????}?
?????else if (returnValue.equals(KeyConstant.PROCEDURE_EXECUTE_FAIL))?
?????{
??????logger.info("调用存储过程失败或异常");
?????}?
?????else if (returnValue.equals(KeyConstant.CLIENT_INVOKE_FAIL))?
?????{
??????logger.info("调用WEBSERVICE接口失败");
?????}?
?????else if (returnValue.equals(KeyConstant.OUT_SERVICE_NOT_EXISTS))
?????{
??????logger.info("数据库中已无需操作的数据");
?????}
????}?
????catch (Exception e)?
????{
?????logger.error("调用WEBSERVICE接口 GJKFNewWorkSheet 出现异常:"
?????????+ e.toString());
?????e.printStackTrace();
????}
????
????int sys_newWorkSheetInterval = Integer.valueOf(SysParameter.getValue("sys_newWorkSheetInterval")).intValue();
????logger.info("GJKFNewWorkSheet 延迟" + sys_newWorkSheetInterval + "秒");
????sleep(sys_newWorkSheetInterval * 1000);
???}
??}?
??catch (NumberFormatException e1)?
??{
???logger.error("线程间隔必须为数字");
???//e1.printStackTrace();
??}?
??catch (InterruptedException ex)?
??{
???ex.printStackTrace();
??}
?}
}
上面的关键是这段代码:String returnValue = GJKFClient.callNewWorkSheet(null,"client.GJKFCaller");GJKFClient类的callNewWorkSheet方法实现了数据(调用服务所需参数)的组装,调用
服务:
TransmitServiceHttpImplServiceSoapBindingStub binding = (TransmitServiceHttpImplServiceSoapBindingStub) new TransmitServiceHttpImplServiceLocator()
??????????? ?.getTransmitServiceHttpImplPort();
interfaceResult = binding.transmit(transmitRequest);
transmitRequest这是我们传入的参数。
?
我们还可以直接在Thread类中run方法中直接组装数据调用服务:也就是上面的代码可以直接放在NewWorkSheetThread 类的run方法中。这样少写几个类,但是显得代码臃肿。
?
时间有限,以后有时间再加深修改。