基于ssm框架的绩效管理系统
技術選型:mybatis,spring,springMVC,quartz,oracle
功能模塊:績效匯報表的查詢、填寫、審批;郵件的發送;定時任務
工作流程:員工填寫完績效匯報表,提交后,系統發送郵件給主管,提醒主管及時審批,當主管審批完績效匯報表后,系統發送郵件給填寫該績效匯報表的員工,提醒員工查看審批結果,若審批通過,則無需處理;若審批不通過,則該員工需修改績效匯報表等待再次審批。發送失敗的郵件會被記錄,系統會每30min查詢是否有發送失敗的郵件并發送。
在系統開發時遇到的問題如下:
1.在spring-mybatis的整合xml文件中,若數據庫需要從properties動態取值
直接刪掉<property name="sqlSessionFactory" ref="sqlSessionFactory"/>
注意:在沒有配置這一行時,必須配置一個以sqlSessionFactory命名的org.mybatis.spring.SqlSessionFactoryBean。
2.不支持org.springframework.jdbc.datasource.DriverManagerDataSource數據源嗎?
當修改為org.apache.commons.dbcp.BasicDataSource數據源時編譯成功。
反正我當時是報錯了,另外查了一下,這個數據源沒有用到連接池,推薦的也是下面這種呢
3.mybatis從數據庫查詢到數據,超級智能的,我這里試過修改構造器,刪除get、set方法,他依然能獨處數據,究竟是采用的什么詭異的方法?
根據測試結果寫入采用的是構造器的方式。
4.Oracle數據庫自增序列:
create sequence table_autoincminvalue 1maxvalue 9999999999start with 1increment by 1nocycle 觸發器: create or replace trigger insert_table_autoincbefore insert on PerformanceTablefor each rowbeginselect table_autoinc.nextval into :new.PerformanceId from dual;end;實現數據表中ID的自增,即使你輸入了ID值,也會被序列值取代。
5.當jsp有頁面請求時,例如src="${pageContext.request.contextPath }/js/checkCode.js"。
這時,我們需在springmvc配置文件聲明默認的servlet。
<mvc:default-servlet-handler/>
否則,他會去controller中尋找對應requestmapping,然后報錯。
6、textaera的換行問題
問題出在EL表達式中,在js中使用EL表達式會不能正確獲得參數,導致錯誤顯示內容。
采用隱藏域的方式獲取后臺傳來的值,替代EL表達式。
經過測試,textaera里面的換行似乎也是使用的\n。
7.在頁面中使用EL表達式:
若在jsp頁面中,可以直接使用,但是要加引號,因為js的數據類型和EL表達式的數據類型不匹配,加上引號則會將EL表達式的內容轉換成String類型,所以當EL表達式的值為null,false,true這些關鍵字時,其也是以String類型存在的。
若在js文件中使用,目前還沒有找到很好的辦法,但我的解決思路是在jsp頁面獲取其值,然后存入input的hidden域中,在js文件中就可以直接調用。
8.EL表達式獲取不到值時若為字符串則為空串,而<%=%>獲取不到值時,若為字符串則為null。
9.郵件發送
郵件的發送我最開始用的126的服務器,查詢錯誤信息,發現服務器一直將我發送的郵件當垃圾郵件處理而發送失敗。
當我使用公司的exchange服務器的時候,發送郵件才成功,但是在一段時間內發送郵件有數量限制。
我的發送郵件的方法是一個靜態方法,當我用quartz來執行這個靜態方法的時候,總是導致我的tomcat重啟,問題很詭異,還沒有找到原因。
我把發送郵件的方法修改為普通方法之后問題解決。
<!-- 郵件發送器 --><bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl"><property name="host" value="${mail.host}" /><property name="username" value="${mail.username}" /><property name="password" value="${mail.password}" /><property name="defaultEncoding" value="UTF-8"></property><property name="javaMailProperties"><props><prop key="mail.smtp.auth">${mail.smtp.auth}</prop><prop key="mail.smtp.timeout">${mail.smtp.timeout}</prop><prop key="mail.smtp.port">${mail.smtp.port}</prop></props></property></bean>@Component public class MailSend {@Autowiredprivate JavaMailSender mailSender;public void send(Mail mail) {JavaMailSenderImpl senderImpl = new JavaMailSenderImpl();MimeMessage mailMsg = senderImpl.createMimeMessage();try {MimeMessageHelper messageHelper = new MimeMessageHelper(mailMsg, true, "utf-8");// 接受者messageHelper.setTo(mail.getRecipient());// 發送者messageHelper.setFrom("huangjiangbo@jlpay.com");// 主題messageHelper.setSubject(mail.getSubject());// 郵件內容,注意加參數true,表示啟用html格式messageHelper.setText(mail.getContent(), true);mailSender.send(mailMsg);} catch (MessagingException e) {e.printStackTrace();}}}
10.線程池相關。
因為涉及到發送郵件功能,該功能可能非常耗時,我決定為其開辟線程執行該功能。
<!-- 異步線程池 --><bean id="threadPoolTaskExecutor"class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor"><!-- 核心線程數 --><property name="corePoolSize" value="${corePoolSize}" /><!-- 最大線程數 --><property name="maxPoolSize" value="${maxPoolSize}" /><!-- 隊列最大長度 >=mainExecutor.maxSize --><property name="queueCapacity" value="${queueCapacity}" /><!-- 線程池維護線程所允許的空閑時間 --><property name="keepAliveSeconds" value="${keepAliveSeconds}" /><property name="rejectedExecutionHandler"><!-- AbortPolicy:直接拋出java.util.concurrent.RejectedExecutionException異常 --><!-- CallerRunsPolicy:主線程直接執行該任務,執行完之后嘗試添加下一個任務到線程池中,可以有效降低向線程池內添加任務的速度 --><!-- DiscardOldestPolicy:拋棄舊的任務、暫不支持;會導致被丟棄的任務無法再次被執行 --><!-- DiscardPolicy:拋棄當前任務、暫不支持;會導致被丟棄的任務無法再次被執行 --><bean class="java.util.concurrent.ThreadPoolExecutor$CallerRunsPolicy" /></property></bean>mailThread繼承了Thread類,在run方法中發送郵件,發送郵件相關的類我都是通過構造器傳入的。
taskExecutor是注入的上面寫的bean。
lfcs是我繼承ListenableFutureCallback<Boolean>接口后重寫了onsuccess和onFailure方法,很顯然,你可以把你想要處理線程正常完成或者拋出異常的內容寫在里面。
所以最關鍵的一行代碼是futureTask.addCallback(lfcs)
@SuppressWarnings("unchecked")public void sendMail(Mail mail) {Thread mailThread = new MailThread(mail, mailSend);lfcs.setMail(mail);ListenableFutureTask<Boolean> futureTask = (ListenableFutureTask<Boolean>) taskExecutor.submitListenable(mailThread);futureTask.addCallback(lfcs);}11、filter如果要引用bean的情況。攔截器中是可以通過@autowire來獲取的。
作者:容偉新鏈接:https://www.zhihu.com/question/22977026/answer/23317656
來源:知乎
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。
眾所周知,web應用啟動的順序是:listener->filter->servlet,而因為項目應用了spring mvc,所以我們會有兩個配置文件(applixationContext.xml和springMVC-sevlet.xml),我們在配置spring時會用到spring的listener,它會讀取application.xml里的配置對spring context進行初始化;而springMVC-servlet.xml則是在spring mvc的dispathServlet啟動的時候讀取進行配置。而如果項目里用到了注解,則需要在springMVC-servlet.xml中加上“”。ok,經過上面的鋪墊后,進入重點。問題就是項目啟動時,先初始化listener,因此配置在applicationContext.xml里的bean會被初始化和注入;然后再來就filter的初始化,再接著才到我們的dispathServlet的初始化,因此,當我們需要在filter里注入一個注解的bean時,就會注入失敗,因為filter初始化時,注解的bean還沒初始化,沒法注入。所以,如果想要在filter里注入注解bean的話,就要在applicationContext.xml里配置context,也就是上面說的那句配置。在這里配置時需要注意的是,需要把tx和aop的配置放在最下面,否則也會導致spring的context初始化失敗。把配置弄好之后,我們就在filter的init方法里,通過獲取webApplicationContext的getBean方法對需要的bean進行注入。以上是個人折騰了很久后的總結,希望能幫助到同樣遇到這問題的小伙伴們……
12、開發環境和服務器環境使用一樣的JDK,不然會出現任務的class not found。
總結
以上是生活随笔為你收集整理的基于ssm框架的绩效管理系统的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Vue 学习13——Vue元素过渡
- 下一篇: 如何修改Windows(可移植)桌面文件