1. 程式人生 > >搭建maven web項目並配置quartz定時任務【業務:對比數據變化內容】 歷程

搭建maven web項目並配置quartz定時任務【業務:對比數據變化內容】 歷程

uid pan 整理 maven項目 factor www .com 參考 初始化

搭建maven web項目並配置quartz定時任務【業務:對比數據變化內容】 歷程
2018年03月03日 10:51:10 守望dfdfdf 閱讀數:100更多
個人分類: 工作 問題
編輯
版權聲明:本文為博主原創文章,轉載請註明文章鏈接。 https://blog.csdn.net/xiaoanzi123/article/details/79380777
前提說明:
之前的博客 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,並選擇生成web.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
至此,搭建構造上基本沒什麽問題了,剩下的就是業務上的功能開發。後續如果有必要我會再寫一篇來記錄。

搭建maven web項目並配置quartz定時任務【業務:對比數據變化內容】 歷程