1. 程式人生 > >基於ssm框架的績效管理系統

基於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_autoinc
     minvalue 1
     maxvalue 9999999999
     start with 1
     increment by 1
     nocycle
觸發器:
create or replace trigger insert_table_autoinc
     before insert on PerformanceTable
     for each row
          begin
               select 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 {
	@Autowired
	private 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("[email protected]");
			// 主題
			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。