posts - 78, comments - 34, trackbacks - 0, articles - 1
            BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

          今日的北京氣溫回升,昨天是降溫。天氣的變暖,讓大家感覺十分溫暖,課上睡意連綿。湯兄弟有發(fā)現(xiàn)大家的狀況,所以今天拿出了一點時間與大家交流學習方法或技術上的一些問題。授課進度完全在掌握之中。

          未來三天的內容,學習使用JBMP解決審批流轉這一大模塊的需求。今日的課程內容比較簡單,但在實際項目中的應用卻十分重要。把WEB基礎搞的差不多了,這些框架并沒什么難的。更多的是應該多使用,多熟悉他們。兩大重點內容:通用超強分頁功能、JBPM審批流程管理。

          一、通用超強分頁功能

          1.分頁效果

          wps_clip_image-26256

          (圖1.1

          1.1中顯示的分頁功能是目前我見到的,功用最全的分頁功能。當然也是論壇中比較常用的分頁功能。我們今日就實現(xiàn)這個通用超級分頁功能。

          2.分頁Bean

          湯老師使用自己的講課風格(應該也是他做項目時的編寫風格),由廣入微、由粗糙到細致。使用他的方法做分析比較好,這或許是通用的分析方式吧!

          我們看圖1.1中具有的屬性:

          v 頁碼:1/11

          v 每頁顯示:30

          v 總記錄數(shù):301

          v 分頁: [首頁] [上一頁] [下一頁] [尾頁] 1 2 3 4 5 6 7 8 9 10

          OK,我們根據(jù)頁面信息取出了分頁Bean的屬性,并設計分頁Bean

          import java.util.List;

          public class PageView {

          // 通過參數(shù)指定的信息

          private int currentPage;// 當前頁碼

          private int pageSzie;// 每頁顯示記錄數(shù)量

          // 通過查詢數(shù)據(jù)庫獲取的信息,外部獲取

          private int recordTotal;// 總記錄數(shù)

          private List recordList;// 當前面記錄信息列表

          // 通過計算生成的信息

          private int pageTotal;// 總頁面數(shù)量

          private int startIndex;// 起始頁面索引

          private int endIndex;// 結束頁面索引

          // 顯示的頁面數(shù)量

          private static final int PAGE_INDEX_COUNT = 10;

          // 在構造方法中生成各種需要的信息

          public PageView(int currentPage, int pageSize, int recordTotal,

          List recordList) {

          this.currentPage = currentPage;

          this.pageSzie = pageSize;

          this.recordTotal = recordTotal;

          this.recordList = recordList;

          // 通過計算生成startIndex和endIndex

          /*

          * 因為顯示的頁面索引數(shù)量是有限的 我們不能把所以的頁面索引一下子全列出來 我們需要動態(tài)顯示頁面索引列表

          */

          this.pageTotal = (this.recordTotal + this.pageSzie - 1) / this.pageSzie;

          // 如果頁面總數(shù)<=顯示頁面索引數(shù)量

          if (this.pageTotal <= PAGE_INDEX_COUNT) {

          this.startIndex = 1;

          this.endIndex = this.pageTotal;

          } else {

          // 根據(jù)當前頁面索引生成,頁面起始索引和結束索引。

          // 區(qū)分偶數(shù)和奇數(shù) 頁面索引數(shù)量

          if (PAGE_INDEX_COUNT % 2 == 0) {

          this.startIndex = this.currentPage - (PAGE_INDEX_COUNT / 2 - 1);

          this.endIndex = this.currentPage + (PAGE_INDEX_COUNT / 2);

          } else {

          this.startIndex = this.currentPage - (PAGE_INDEX_COUNT / 2);

          this.endIndex = this.currentPage + (PAGE_INDEX_COUNT / 2);

          }

          // 如果生成的起始索引小于1

          if(this.startIndex < 1){

          this.startIndex = 1;

          this.endIndex = PAGE_INDEX_COUNT;

          }

          // 如果生成的結束索引大于總頁面索引數(shù)量

          if(this.endIndex > this.pageTotal){

          this.endIndex = this.pageTotal;

          this.startIndex = this.pageTotal - PAGE_INDEX_COUNT;

          }

          }

          }

          // ...getters AND setters

          }

          3.審批流程的DispathcAction

          我們與上次課程一樣,需要為審批流程編寫一個DispatchAction。涉及到顯示審批流程列表只有一個方法——list

          /** 

           * 顯示審批流程列表 

           */

          public ActionForward list(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response)

          throws Exception {

          int pageNum = Integer.parseInt(request.getParameter("pageNum"));

          // 調用ProcessDefinitionService接口的getPageView方法獲取PageView對象

          PageView pageView = processDefinitionService.getPageView(pageNum);

          // 將PageView對象存放到request的pageView屬性中

          request.setAttribute("pageView", pageView);

          return mapping.findForward("list"); // list.jsp

          }

          其中用到的“processDefinitionService.getPageView”方法:

          /**

           * 獲取pageView信息

           */

          public PageView getPageView(int pageNum) {

          // 每面顯示10條記錄

          int pageSize = 10;

          // 查詢數(shù)據(jù)庫

          // 使用Number防止不同數(shù)據(jù)庫返回的數(shù)值類型不同,而引發(fā)的異常。

          int count = ((Number) this.getSession().createQuery(

          "SELECT COUNT(*) FROM " + ProcessDefinition.class.getName()

          + " pd").uniqueResult()).intValue();

          // 第一條記錄的索引

          int firstRecoderIndex = (pageNum - 1) * pageSize;

          // 獲取記錄列表

          List list = this.getSession().createQuery(

          "FROM " + ProcessDefinition.class.getName() + " pd")

          .setFirstResult(firstRecoderIndex).setMaxResults(pageSize)

          .list();

          return new PageView(pageNum, pageSize, count, list);

          }

          4.顯示分頁信息的pageView.jspf頁面

          多處使用到分頁頁面,所以我們將分頁頁面單獨提取出來。如果有哪個頁面需要顯示分頁信息,直接include就可以了。

          <%@ page language="java" pageEncoding="utf-8" %>

          <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

          <c:if test="${pageView.totalPage gt 1 }">

          <!-- 分頁信息 -->

          頁碼:${pageView.currentPage}/${pageView.totalPage}頁

          每頁顯示:${pageView.pageSize}條

          總記錄數(shù):${pageView.recordCount}條

          分頁:

          <a href="javascript:gotoPage(1)">[首頁]</a> 

          <c:if test="${pageView.currentPage gt 1}">

          <a href="javascript:gotoPage(${pageView.currentPage - 1})">[上一頁]</a> 

          </c:if>

          <c:if test="${pageView.currentPage lt pageView.totalPage}">

          <a href="javascript:gotoPage(${pageView.currentPage + 1})">[下一頁]</a> 

          </c:if>

          <a href="javascript:gotoPage(${pageView.totalPage})">[尾頁]</a>

          <!-- 顯示頁碼 -->

          <c:forEach begin="${pageView.startPageIndex}" end="${pageView.endPageIndex}" var="pageNum">

          <c:if test="${pageNum eq pageView.currentPage}">

          <span class="current_page">${pageNum}</span>

          </c:if>

          <c:if test="${pageNum ne pageView.currentPage}">

          <a href="javascript:gotoPage(${pageNum})">${pageNum}</a>

          </c:if>

          </c:forEach>

          轉到:

          <input type="text" id="txtPageNum" size="4" class="input_pagenum"/>

          <input type="button" onclick="gotoPage(document.getElementById('txtPageNum').value)" value="Go"/>

          <script type="text/javascript">

          /**

          * 跳轉到指定的頁碼

          */

          function gotoPage( pageNum ){

          if( isNaN(pageNum) ){ // not a number

          alert("請輸入正確的頁碼");

          document.getElementById('txtPageNum').focus();

          return false;

          }

          if( pageNum < 1 || pageNum > ${pageView.totalPage} ){

          alert("請輸入正確的頁碼,范圍為 1-${pageView.totalPage}");

          document.getElementById('txtPageNum').focus();

          return false;

          }

          window.location.href = getPageViewUrl( pageNum );

          // getPageViewUrl為在include頁面添加的javscript代碼

               // 所以此頁面可以適用于任何分頁信息的顯示例如下:

          //function getPageViewUrl( pageNum ){

          // return "?method=list&pageNum=" + pageNum;

          //}

          }

          </script>

          </c:if>

          二、審批流轉管理

          審批流轉就是把單位內部的各項審批電子化,如工作請求、出差申請、采購申請、請假、報銷等日常工作流程。

          審批流轉(工作流):

          1.流程與表單管理

          2.執(zhí)行流程

          3.查詢

          有類似的審批請求,有兩大重點:流程定義和表單模板,一個表單對應一個流程。

          要求:

          1.方便 定義/修改 與 管理 流程定義

          2.方便 定義/修改 與 管理 表單模板

          3.執(zhí)行流程(讓表單(數(shù)據(jù))按指定的流程進行流轉,并且記錄)

          4.方便查詢所有的表單實例(數(shù)據(jù)) 記錄(查詢流轉過的表單)

          今日沒有講解設計與審批流轉相關的模塊,只是講解將打包成zipJBPM工作流自動部署到OA項目中,并可查看顯示工作流的文件信息以及刪除工作流。

          1.顯示部署流程

          /** 

           * 部署流程頁面 

           */

          public ActionForward deployUI(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response)

          throws Exception {

          return mapping.findForward("deployUI"); // deployUI.jsp

          }

          2.部署流程

          /** 

           * 部署流程 

           */

          public ActionForward deploy(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response)

          throws Exception {

          try {

          // 獲取<html:file>表單提交過來的流程資源

          ProcessDefinitionActionForm adaf = (ProcessDefinitionActionForm) form;

          ZipInputStream zipIn = new ZipInputStream(adaf.getParResource().getInputStream());

          // 創(chuàng)建流程定義

          ProcessDefinition pd = ProcessDefinition.parseParZipInputStream(zipIn);

          // 部署流程定義

          this.processDefinitionService.deploy(pd);

          } catch (Exception e) {

          // 發(fā)生異常顯示錯誤

          ActionErrors errors = new ActionErrors();

          errors.add("error", new ActionMessage("非法的文件格式!",false));

          this.saveErrors(request, errors);

          return mapping.findForward("deployUI");

          }

          return mapping.findForward("toList"); // path="/pd.do?method=list" redirect="true"

          }

          因為部署流程時確保一個線程使用的是同一個“JbpmContext”,并確保Jbpm事件的正確提交或回滾。所以我們還需要為JbpmContext添加一個過濾器。

          3.刪除流程

          /**

           * 刪除流程

           */

          public ActionForward del(ActionMapping mapping, ActionForm form,

          HttpServletRequest request, HttpServletResponse response)

          throws Exception {

          // 獲取流程ID并刪除

          Long id = Long.parseLong(request.getParameter("id"));

          this.processDefinitionService.delete(id);

          // 需要刷新流程顯示列表

          String pageNum = request.getParameter("pageNum");

          ActionForward af = mapping.findForward("toList");

          return new ActionForward(af.getPath() + "&pageNum=" + pageNum, af.getRedirect());

          }

          4.查看流程中的“processdefinition.xml”文件

          /**

           * 查詢流程定義文件(processdefinition.xml

           */

          public ActionForward showProcessFile(ActionMapping mapping,

          ActionForm form, HttpServletRequest request,

          HttpServletResponse response) throws Exception {

          // 獲取流程id

          Long id = Long.parseLong(request.getParameter("id"));

          // 獲取流程定義

          ProcessDefinition pd = this.processDefinitionService.getById(id);

          // 獲取文件

          byte[] content = pd.getFileDefinition().getBytes(

          "processdefinition.xml");

          // 寫出文件

          response.setContentType("text/xml;charset=UTF-8");

          response.getWriter().write(new String(content, "UTF-8"));

          return null;

          }

          5.查看流程中的“processimage.jpg”文件

          /**

           * 查詢流程圖片(processimage.jpg

           */

          public ActionForward showProcessImage(ActionMapping mapping,

          ActionForm form, HttpServletRequest request,

          HttpServletResponse response) throws Exception {

          // 獲取流程id

          Long id = Long.parseLong(request.getParameter("id"));

          // 獲取流程定義

          ProcessDefinition pd = this.processDefinitionService.getById(id);

          // 獲取文件

          byte[] content = pd.getFileDefinition().getBytes("processimage.jpg");

          // 寫出文件

          response.setContentType("image/jpeg");

          response.getOutputStream().write(content);

          return null;

          }

          明天將學習自定義表單模板,和向流程中加入控制代碼。今天的內容還需要在大腦里整理整理...

          加油!


          只有注冊用戶登錄后才能發(fā)表評論。


          網(wǎng)站導航:
           
          主站蜘蛛池模板: 四子王旗| 乌苏市| 正宁县| 大石桥市| 灵台县| 庆元县| 沙坪坝区| 岐山县| 晋州市| 仙游县| 绩溪县| 西平县| 宁阳县| 湘潭县| 布拖县| 凤冈县| 巧家县| 郎溪县| 凤凰县| 竹溪县| 永平县| 内乡县| 榆树市| 福泉市| 北碚区| 宝山区| 华池县| 涪陵区| 社会| 民县| 陇西县| 嫩江县| 米易县| 尚义县| 高要市| 册亨县| 四平市| 永修县| 竹溪县| 嘉善县| 章丘市|