処理の流れ(使用例)
スレッドの処理が終わるまで待機画面を表示し、
スレッドが完了すれば完了画面に遷移する処理の流れ。
使用方法(Springでの例)
スレッドの実行側
@Controller public class OfferController { @Autowired OfferService offerLogic; @Autowired HttpSession session; @RequestMapping(value = "/offer", method = RequestMethod.GET) public String home(Model model) { OfferForm form = new OfferForm(); form.setUserId(7); // スレッド初期化 SampleThread thread = new SampleThread(offerLogic, form); // スレッド実行 thread.start(); // スレッドの処理状況をセッションで受け取れるようにする session.setAttribute("threadStatus", thread.getThreadStatus()); return "offer/confirmThread"; } @RequestMapping(value = "/waitThreadCompleted", method = RequestMethod.POST) public String waitThreadCompleted(Model model) { try { Thread.sleep(5000); } catch (InterruptedException e) { } // スレッドの値を取得 SampleThreadStatusForm statusform = (SampleThreadStatusForm)session.getAttribute("threadStatus"); // スレッドが終了した場合 if ("1".equals(statusform.getStatus())) { // タイムアウトした場合 if (statusform.isTimeOutFlg()) { return "offer/timeOutThread"; } // 正常に完了した場合 else { return "offer/completeThread"; } } // スレッドが終了していない場合(今回の例では通らないがメモ用に記載) else { // 待機画面に戻る return "offer/confirmThread"; } } }
スレッド内の処理側
public class SampleThread extends Thread { // スレッド状態フォーム private SampleThreadStatusForm threadStatus = new SampleThreadStatusForm(); // ビジネスロジック private OfferService offerLogic; // フォーム private OfferForm offerForm; public SampleThreadStatusForm getThreadStatus() { return threadStatus; } // コンストラクタ public SampleThread (OfferService logic, OfferForm form) { this.offerLogic = logic; this.offerForm = form; } // スレッド実行する public void run() { try { // スリープ時間(ミリ秒) final long waitMillis = 5000; // 最大スリープ時間(ミリ秒) final long maxWaitMillis = 30000; // スリープ時間合計 long totalWaitMillis = 0; // スレッドの処理状態(0:処理中、1:処理完了) threadStatus.setStatus("0"); do { // スリープ Thread.sleep(waitMillis); // スリープの合計時間を更新 totalWaitMillis += waitMillis; // ビジネスロジックを実行(例としてDB検索を行う) MemberBean member = offerLogic.selectMember(offerForm.getUserId()); // 検索がヒットした場合 if (member != null) { // 検索結果をスレッド状態フォームに格納して渡す threadStatus.setMember(member); // ループを抜ける break; } } while (totalWaitMillis < maxWaitMillis); // タイムアウトした場合 if (totalWaitMillis >= maxWaitMillis) { // フラグでタイムアウトしたことが分かるようにする threadStatus.setTimeOutFlg(true); } } catch (Exception e) { } // スレッドの処理状態を処理完了にする threadStatus.setStatus("1"); } }
待機画面のjsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title> <script type="text/javascript"> function action(){ document.frm.action="waitThreadCompleted"; document.frm.submit(); } </script> </head> <body onload="action()"> <form:form modelAttribute="offerForm" name="frm"> スレッド処理中 </form:form> </body> </html>
スレッドのフォーム
public class SampleThreadStatusForm implements Serializable{ private static final long serialVersionUID = -4098194215772825545L; private String status; private MemberBean member; private boolean timeOutFlg; public String getStatus() { return status; } public void setStatus(String status) { this.status = status; } public MemberBean getMember() { return member; } public void setMember(MemberBean member) { this.member = member; } public boolean isTimeOutFlg() { return timeOutFlg; } public void setTimeOutFlg(boolean timeOutFlg) { this.timeOutFlg = timeOutFlg; } }