利用java定时器Timer实现定时传送数据的任务

题外话:说好的要时不时的把自己在编程方面所学习的点点滴滴记录下来,但是却迟迟没有坚持下来。自己的编程技术的提升,一定要有知识沉淀的过程,希望自己能够把写技术博客这件事一直坚持下去,成为更好的自己,也希望大家都能够为了自己心中的目标坚持去做一件事!

项目背景:最近公司的项目中有这样一个需求,希望我完成一个每天定时向一个webservice接口推送数据库的一些数据的功能,推送的数据是xml格式的。

1.定时器Timer的编写

    对于这个需求,第一个需要解决的就是如何完成定时执行任务?这里我用了java的定时器Timer来实现这个功能。这里我编写了两个类,DataListener类和DataTask类。前者是该定时器的监听类,用来设置定时任务执行的具体时间以及开启该定时任务;后者是执行定时任务的具体操作。
    DataListener代码如下:
    public class DataListener extends HttpServlet{
    private static final long serialVersionUID = 1L;
    private Timer timer = null;
    private DataTask datatask = null;

    public void init(){
        datatask = new DataTask();
        timer = new Timer(true);
        //设定推送数据的时间,该定时任务在早上8:00执行(24小时格式)
        Calendar calendar = Calendar.getInstance();  
        calendar.set(Calendar.HOUR_OF_DAY, 8);  
        calendar.set(Calendar.MINUTE, 0);  
        calendar.set(Calendar.SECOND, 0);  
        timer.schedule(timetask, calendar.getTime());
       }
    }
    该类继承了HttpServlet,主要是通过web项目启动时,启动该servlet定时任务。init()方法是HttpServlet启动时需要初始化的方法,所以定时器初始化的配置就写在该方法里。在web.xml文件中还需要配置该servlet启动信息,如下所示。
<servlet>
    <servlet-name>DataListener</servlet-name>
    <servlet-class>
        com.xxx.xxx.xxx.DataListener
    </servlet-class>
    <load-on-startup>0</load-on-startup>
</servlet>

接下来,需要编写执行具体任务的DataTask类,代码如下。

public class DataTask extends TimerTask {
    private JxfpService jxfpService;
    private XmlParser xmlParser= new XmlParser();
    //定时执行部分,查找数据库所需要的数据
    @Override
    public void run() {
        //通过ApplicationContext加载Spring配置文件完成service类的注入
        ApplicationContext beanFactory= new ClassPathXmlApplicationContext("classpath:spring-*.xml");
        jxfpService = (XxxxService) beanFactory.getBean("xxxxService");
        String dataXml = "";
        try {
            List<xxxx> list =xxxService.xxxxQuery();
            dataXml = xmlParser.pushDataToXml(list);
            System.out.println("自动传输的数据为:"+dataXml);
        } catch (Exception e) {
            e.printStackTrace();
        }
        pushData(dataXml);
    }
}
    DataTask类继承了TimerTask,在run()方法中需要补充该定时任务的具体操作内容。我在该任务里边主要编写了访问数据库的service类,还有将数据格式转换成xml格式的类。最后,将转换成的xml格式的数据推送出去。
    数据访问使用了springmvc+mybatis的访问方式,整个项目的数据访问都是注解的形式完成的类的注入,但是我使用这种方式service类总是加载不了,报NullPointException,所以就使用了ClassPathXmlApplicationContext来进行类的注入。

2.使用HttpClient完成xml格式数据推送

    xml格式的数据推送,这里采用了HttpClient类进行soap协议的webservice请求,然后把数据传送过去,具体的代码如下。
    该方法是编写在DataTask类中的。
// 向webservice发送请求,并推送数据库的数据
    public void pushData(String data) {
        String soapRequestData = "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:jx=\"http://jx.xxxx.com\">"
                + "<soapenv:Header/>"
                + "<soapenv:Body>"
                + "<jx:pushData>"
                + "<param>"+data+"</param>"
                + "</jx:pushData>"
                + "</soapenv:Body>" + "</soapenv:Envelope>";
        try {
            PostMethod postMethod = new PostMethod(
    "http://localhost:8080/xxxx/service/JxWebservice?wsdl");
            // 然后把Soap请求数据添加到PostMethod中
            byte[] b = soapRequestData.getBytes("utf-8");
            InputStream is = new ByteArrayInputStream(b, 0, b.length);
            RequestEntity re = new InputStreamRequestEntity(is, b.length,"application/soap+xml; charset=utf-8");
            postMethod.setRequestEntity(re);
            // 最后生成一个HttpClient对象,并发出postMethod请求
            HttpClient httpClient = new HttpClient();
            int statusCode;
            statusCode = httpClient.executeMethod(postMethod);
            if (statusCode == 200) {
                System.out.println("数据推送成功!");
                String soapResponseData = postMethod.getResponseBodyAsString();
                System.out.println("返回的报文为:" + soapResponseData);
            } else {
                System.out.println("接口访问失败!错误代码:" + statusCode);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    这个功能做完以后,有几点疑问,希望和大家共享一下,如果我的博客有幸被你看到,如果能解决我的这些问题,我将不胜感激。
    1.为什么我在定时任务中,使用@Resource注解或者@Autowired注解进行service类注入时,会报空指针的错误?
    2.向接口推送xml数据的方式还有其他的方法吗?我在网上查的一种方式,是使用axis来传输,但是我试了没有成功。
   最后,由于我的技术水平有限,博客中使用的术语或者代码有问题的,如果您看见了,可以给我提意见。

参考的网址:
HttpClient远程调用WebService
手动注入Spring的bean

  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值