2018年5月24日接到人生第一个开发任务:利用webservice将本地客户端数据定时上传给服务端。
一、首先补充webservice的基础知识,弄清楚流程如下:
1.客户端把调用方法参数转换成符合WSDL格式定义的XML文档片段(包含SOAP消息,input消息);
2.通过网络将XML文档片段发送给服务器;
3.服务器接收XML文档;
4.服务器解析XML文档,提取其中的数据,并把数据转换成webservice所需的参数值;
5.服务器执行方法,把执行方法得到的返回值再次转换为XML文档片段(包含SOAP消息,output消息);
6.通过网络将XML文档片段发送给客户端;
7.客户端接收XML文档片段,解析并提取其中的数据,数据转换成webservice的返回值。
即唯一的要求就是编写webservice的语言要能够支持XML文档生成和解析、网络传输。
二、接下来解析WSDL文档:
三、接下来说明理论开发过程(使用CXF开发框架):
1.使用CXF开发webservice服务器端(包括接口和实现类):开发业务接口(该接口用@webservice修饰);开发实现类(也需要用@webservice修饰);发布webservice(使用endpoint类的静态publish方法暴露webservice即可)
2.使用CXF开发webservice客户端:调用cxf提供的wsdl2java工具,根据wsdl文档生成java代码;找到生成的类中,继承了service的类(该类的实例可以当工厂来使用);调用service子类的实例的getXXXPort方法,返回远程webservice的代理。
四、接下来说明我的操作步骤,源码附在最后。
1.服务端已将wsdl文件暴露,因此根据服务端提供的wsdl地址生成客户端类(dos下,打开到相应目录下,执行wsimport -keep XXXX.wsdl,即可在目录中生成客户端类),再编写一个类进行调用。
以上将三个测试定值以xml文本格式上送服务端,执行得到如下反馈说明正确:
2.现在加入15分钟定时器代码
执行得到如下反馈说明正确:
3.现在要去数据库取相应的值替代第一步中的固定测试值即可,首先在数据库中建立一个视图,将所需的数据放在一起(一个虚拟表里),java程序直接访问视图,取出对应时间的数值即可。CREATE or replace VIEW senddata AS
SELECT c.OCCUR_TIME,a.cur_083,b.cur_035 ,c.plus
FROM YC_HS_000011 a,YC_HS_640002 b ,
(select ych.cur_035-nvl(lead(cur_035) over(ORDER BY OCCUR_TIME desc),0)plus ,cur_035 , OCCUR_TIME from YC_HS_640002 ych order by OCCUR_TIME desc) c
WHERE a.OCCUR_TIME = b.OCCUR_TIME and a.OCCUR_TIME = c.OCCUR_TIME ORDERBY c.OCCUR_TIME
检查生成的视图,无误即可。这一部中要学会怎么在数据库客户端测试sql语法。
4.java代码中访问视图,按照对应的时间取出三个字段的值作为一个结果集,首先需要一个提供jdbc服务的标准类,这里从老员工处拷贝SqlBean.java文件(注意修改其中数据库的地址、端口、用户名、密码等数据)。结果集中的数据依次赋值给变量,将变量替换xml文本中的固定测试数值。
5.附上源代码
package ttt;
import ToSqlBean.SqlBean;
import org.apache.axis.client.Call;
import org.apache.axis.client.Service;
import javax.servlet.ServletContext;
import javax.xml.namespace.QName;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
/**
* Created by hht on 2018/6/5.
*/
public class ToTimer {
public static void main(String[] args){
final SimpleDateFormat dateFormatter =new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
final Calendar calendar = Calendar.getInstance();
Date startDate =null;
try {
startDate = dateFormatter.parse("2018/06/07 15:40:00");
}catch (ParseException e) {
e.printStackTrace();
}
Timer timer =new Timer();
//以下每15分钟定时执行
timer.scheduleAtFixedRate(new TimerTask(){
@Override
public void run() {
//System.out.println("execute task!" + this.scheduledExecutionTime());
// System.out.println("execute task!" +dateFormatter.format(calendar.getTime()));
//确认目前的时间
System.out.println("execute task!" +dateFormatter.format(new Date()));
//连接数据库,去读数据
ServletContext application=null;
SqlBeansqlbean=new SqlBean(application);
sqlbean.GetConn();
ResultSet rs=sqlbean.executeSqlQuery("select CUR_083,CUR_035,PLUS from SENDDATA where OCCUR_TIME=(select * from (SELECT OCCUR_TIME FROM SENDDATA order by OCCUR_TIME DESC ) where ROWNUM = 1)");
try {
while(rs!=null && rs.next()) {
int id1=rs.getInt(1);
int id2=rs.getInt(2);
int id3=rs.getInt(3);
// int id4=rs.getInt("4");
// int id5=rs.getInt("5");
// int id6=rs.getInt("6");
System.out.println(id1);
System.out.println(id2);
System.out.println(id3);
}
}catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
sqlbean.CloseDataBase();
//开始将读到的数据上传
try {
String wsdlUrl ="http://114.215.157.224:8086/mds/services/DataService";//提交数据服务地址
String nameSpaceUri ="http://ws.outnet.metl.suypower.com.cn/";//接口方法所在地址
//创建service实例,通过service实例创建call实例,提供发出soap请求。
Service service =new Service();
Call call = (Call) service.createCall();//实例化调用对象
call.setTargetEndpointAddress(new java.net.URL(wsdlUrl));//调用对象中添加webservice地址
//在调用对象中添加webservice对应的命名空间,以及将要调用的函数名
call.setOperationName(new QName(nameSpaceUri,"uploadAllData"));
//设置入参:参数名,参数类型,参数模式
call.addParameter(new QName(nameSpaceUri,"value"), org.apache.axis.encoding.XMLType.XSD_STRING, javax.xml.rpc.ParameterMode.IN);
call.setUseSOAPAction(true);//说明这是soapaction格式
call.setReturnType(org.apache.axis.encoding.XMLType.SOAP_STRING);//设置返回格式
call.setSOAPActionURI(nameSpaceUri +"uploadAllData");
//call.setUsername("sapuser");
//call.setPassword("sappass");
//调用call实例的invoke方法,invoke方法负责向soap服务器发出客户端指定的soap请求,
// 服务器在接收到soap请求后,会在服务端执行相应的服务方法,然后把返回值传给客户。
String ret = (String) call.invoke(new Object[]{postdata});
System.out.println("Successful = " + ret);
}catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
},startDate,15*60*1000);//15分钟定时
}
}