您的位置:首页 > 其它

搭建maven web项目并配置quartz定时任务【业务:对比数据变化内容】 历程(一)

2018-03-03 10:51 806 查看
前提说明:
    之前的博客  http://blog.csdn.net/xiaoanzi123/article/details/78843037   记录了当时开发的一个功能,就是从数据库一个表的某个字段(这个字段存的是xml字符串)取出xml字符串,在程序中解析,取出各个标签的值,封装到不同的bean,然后hibernate存入各自bean对应的表。 这个功能当时开发时,该项目中的基础是spring框架和maven。别的什么都没有。
现在:要把该maven项目,转换成maven web项目,每天对比一次前面提到的xml内容是否发生变化,并且把变化 的内容返回到页面给技术人员展示。同时提供一个确认功能,意思是让技术人员手动确认他已经知道该条内容发生变化的详情。
关键点: 备份旧数据:每日材料(xml)内容要先解析再入库,既然那要对比昨日和今日的变化内容,那就要对比两天的额数据。创建 储存解析后入库数据的表   的   备份表   就很有必要了,以用来存储昨日数据。因为之前做的解析xml时,若一个材料内容发生变化,会先删除 旧数据,再把新解析的新数据插入。 
过程问题:   
    整个过程遇到了好多问题,一直也没顾着整理,现在集中记录整理下,遇到的问题越多,说明自己越弱,月能积累经验提升解决问题的能力。

①    maven项目红色感叹号, 一般常用的maven项目问题处理办法有如下:项目点击右键--maven--update dependencies  ;
    项目右键--maven--update  project  configuration  ;  maven clean  ;maven  install ;项目  clean   等等。目前为止遇到的maven  疑问 基本都是这几步都试一下,差不多就解决了。当然一些具体问题得具体分析。

②    maven  构建build   时报  test  错误。一句话,采用跳过test。参考文章:
http://blog.csdn.net/honghailiang888/article/details/50687079    声明:图片来自该文章。



③    代码中  import部分报错,提示  the  im[port   xxxx   cannot be resolved  。但是确定引入的内容存在,路径正确。
首先,clean项目【我发现使用eclipse或者myeclipse ,一些问题怎么找也解决不掉,clean下就好了,这种情况遇到很多次了。所以不妨先试一下】,然后,基本上是还是因为maven引入以来的原因,参考上述①的内容。
④     在项目中配置spring mvc 等内容后,我把项目 把maven项目转成  maven  web项目。始终出不来页面。这个过程可把我折腾的够呛。我自身的原因是对maven web 项目  目录结构不熟悉,导致问题不断。
主要问题是项目转成web项目后,webcontent目录,src目录,编译后的class文件到底在哪?
经过这次算是记忆深刻,首先放上参考文章连接:
如何把maven项目转换成web项目

该文中  第五【修改部署项目时文件的发布路径,右键项目,Properties-->Deployment Assembly,删除test两项以及WebContent,因为test是测试时使用,并不需要部署】,
第六【添加src/main/webapp的部署路径以及】,
第七【添加Maven Dependencies的部署路径】  步是第一次清晰的接触,也是重点,不然就是各种问题困惑了,也是我走过的坑吧。
还有,该文中第二步少说了一点我觉得很重要:转换成web项目,选中Dynamic Web Module和JavaScript,这里我选的是Dynamic Web Module版本是3.0,然后先别着急点击ok,注意下面的黄色部分的提示:futher configuration available..... ,点击进入以后,将Context directory修改成src/main/webapp,并选择生成w
cf0d
eb.xml,保存。如下图:


此时你会看到你的工程结构如下图,src/main目录下出现了java/resources/webapp三个目录,这样就ok了。关于这一点:http://blog.csdn.net/yu616568/article/details/70739976  这篇文章中有提到。还有一片参考文章很清晰直观:maven和web项目标准目录结构
总结:web-content是 java 一般web项目下生成目录,里面存放web的相关内容。而 maven  web都在src目录下。熟悉maven web的创建过程就好,问题之所以这么多是没经验,我当时甚至手动去创建web-content目录,可笑了。
⑤   开始配置quartz定时任务。  quartz与spring怎么结合配置我就不再赘述,推荐一篇博客可以参考下:
http://blog.csdn.net/tanqian351/article/details/53584737

附上目前我的spring与quartz的配置文件spring-quartz.xml的代码:<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>

<!--quartz与spring整合 第一步 : 定义任务的bean(工作任务的job) -->

<bean id="getHcDataJob" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject">
<bean class=" com.hello.tasks.QuartzJob"></bean>
</property>
<property name="targetMethod" value="getNewestData" />
<property name="concurrent" value="false" />
</bean>

<bean id="dataCopyJob" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject">
<bean class=" com.hello.tasks.QuartzJob"></bean>
</property>
<property name="targetMethod" value="dataCopy" />
<property name="concurrent" value="false" />
</bean>

<bean id="resolveXmlJob" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject">
<bean class=" com.hello.tasks.QuartzJob"></bean>
</property>
<property name="targetMethod" value="resolveXml" />
<property name="concurrent" value="false" />
</bean>

<bean id="guideInfoJob" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject">
<bean class=" com.hello.tasks.QuartzJob"></bean>
</property>
<property name="targetMethod" value="guideInfo" />
<property name="concurrent" value="false" />
</bean>

<!-- quartz与spring整合 第二步 定义触发器的bean,定义一个Cron的Trigger,一个触发器只能和一个任务进行绑定 -->

<bean id="triggerGetData" class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail" ref="getHcDataJob" />
<property name="cronExpression" value="0 50 8 * * ?" /><!-- 获取远程数据job时间设置 -->
</bean>

<bean id="triggerCopyData" class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail" ref="dataCopyJob" />
<property name="cronExpression" value="0 50 8 * * ?" /><!-- 材料数据备份 job时间设置 -->
</bean>

<bean id="triggerResolveXML" class="org.springframework.scheduling.quartz.CronTriggerBean">
<!-- 指定Tirgger绑定的Job -->
<property name="jobDetail" ref="resolveXmlJob" />
<!-- 指定Cron 的表达式 ,-->
<property name="cronExpression" value="0 51 15 * * ?" /><!-- xml数据解析job时间设置 -->
</bean>

<bean id="triggerGuideInfo" class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail" ref="guideInfoJob" />
<property name="cronExpression" value="0 0 9 * * ?" /><!-- xxxx数据推送job时间设置 -->
</bean>

<!-- 总管理类 如果将lazy-init='false'那么容器启动就会执行调度程序 -->
<bean id="startQuertz" lazy-init="true" autowire="no" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<list>
<!-- 触发器列表 -->
<ref bean="triggerGetData" /> <!-- 获取远程的 数据 的 任务 -->
<ref bean="triggerCopyData" /> <!-- 插入新数据前 清空bak表 并 拷贝旧数据到bak表 任务 -->
<ref bean="triggerResolveXML" /> <!-- 解析xml数据任务 -->
<ref bean="triggerGuideInfo" /> <!-- 推送数据的定时任务 -->
</list>
</property>
</bean>
</beans>

我的问题是配置好以后启动,quartz的定时任务总是会同时运行两次,这肯定不对。我当时参考了这篇文章:
https://www.cnblogs.com/bingosblog/p/5802367.html  ,里面的重点内容如下:

【1. autodeploy属性值设置为false,如果此项设为true,表示Tomcat服务处于运行状态时,能够监测appBase下的文件,如果有新有web应用加入进来,会自运发布这个WEB应用,设成false就不会。    2.增加deployOnStartup="false",表示Tomcat服务器启动时, 不会自动发布appBase目录下所有的Web应用。

我就在tomcat的server.xmnl里面在<host>标签里  把 autodeploy属性值设置为false ,并添加deployOnStartup="false",  。然后启动发现quartz任务运行两次的问题的确没有了。但是web页面出不来,不是报404,就是根本无法加载,网页无法访问。这个问题缠绕了我很久,主要处理问题的方向错了。最后终于发现关键原因是 添加的deployOnStartup="false"导致项目根本就没有发布,怎么会访问到。无语了。host标签改回<Host appBase="webapps" autoDeploy="true" name="localhost" unpackWARs="true">。然后启动就ok了。等于白折腾半天,但是也学到点东西吧【比如tommcat当时日志显示启动时间很短,虽然没报错,但是不报错不意味着没问题啊,哈哈,这下记忆深刻了,以后别一看日志没报错就直接过了。。。】
至于为什么quartz任务运行了两次,我也解决有点莫名其妙。最初quartz的配置是在多个不同的配置文件写的(调度器,job分别在不同的配置文件),然后依次调用。   后来我把这些xml整合到一起了,放在一个xml文件【spring-quartz.xml】里面,然后在web.xml里面去加载


 <!-- 加载的时候需要通过上下文初始化参数指定spring配置文件的路径 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<!-- 目前基本上所有的框架在编写路径的时候,都支持“classpath:”这种语法,表示查找起点是从类路径中开始检索 -->
<param-value>classpath*:spring_schedule/**/*.xml</param-value>
</context-param>】,就没再出现任务跑两次的现象。
我的配置文件目录如下:



后来看了这篇文章算是明白了,讲得很详细全面(在最后)。
http://blog.csdn.net/chaijunkun/article/details/6925889 至此,搭建构造上基本没什么问题了,剩下的就是业务上的功能开发。后续如果有必要我会再写一篇来记录。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: