国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發(fā)設計 > 正文

Petstore源碼追蹤記(3)-商業(yè)邏輯處理(四)

2019-11-18 16:21:47
字體:
來源:轉載
供稿:網(wǎng)友

  接續(xù)上期...
http://www.javatwo.net/JavaPaper/Petstore-3_business_logic.pdf
我們已了解SignOnFilter在Web tier處理登入工作的步驟,它需要透過EJB tier從數(shù)據(jù)庫讀取資料進行比對,所以接下來探討在EJB tier的運作情形,從圖14、15可找出實際對應的EJB,從圖上面可知此EJB的屬性是Local Stateless
session Bean,這很少見,大部份的書介紹到Local Bean的用法都用在Entity Bean,由此可知Local Bean的用法亦可用在Session Bean。
     SignOnEJB,源碼在Petstore_home/src/components/signon/src/com/sun/j2ee/bluePRints/signon/ejb/SignOnEJB.java,請讀者順便加上偵察程序代碼:
    
public class SignOnEJB implements SessionBean {

    private static final String USER_HOME_ENV_NAME =
"java:comp/env/ejb/local/User";
    private InitialContext ic = null;
    private UserLocalHome ulh = null;

    public void ejbCreate() throws CreateException {
      try {
        ic = new InitialContext();
        //取得UserLocalHome Reference,它是代表使用者基本資料的Local Entity Bean
        ulh = (UserLocalHome) ic.lookup(USER_HOME_ENV_NAME);
      } catch (NamingException ne) {
         throw new EJBException("SignOnEJB Got naming exception! " +
ne.getMessage());
      }
    }

    /**
     *此函數(shù)由SignOnFilter呼叫,依使用者帳號找出對應的User實體
   *(instance),然后呼叫User實體的密碼比對函數(shù)-user.matchPassWord()
     * business method used to check if a user is allowed to sign on
     */
    public boolean authenticate(String userName, String password) {
    //請加入偵察程序代碼,方便稍候程序驗證
System.out.println("SignOnEJB執(zhí)行authenticate()進行使用者驗證
userName="+userName+", password="+password);
        try {
            UserLocal user = ulh.findByPrimaryKey(userName);
            return user.matchPassword(password);
        } catch (FinderException fe) {
            return false; // User not found, so authentication failed.
        }
    }
     以下略...
    

圖16 SignOnEJB的EJB Reference
    
UserEJB,源碼在
Petstore_home/src/components/signon/src/com/sun/j2ee/blueprints/signon/user/ejb/
UserEJB.java,它是Local Entity Bean,對應數(shù)據(jù)庫中實際資料表-
UserEJBTable在約88列可看到SignOnEJB所呼叫的函數(shù),請讀者順便加
上偵察程序代碼:
    
    
public boolean matchPassword(String password) {
  //請加入偵察程序代碼,方便稍候程序驗證
  System.out.println("UserEJB執(zhí)行matchPassword()進行密碼比對");
    return password.equals(getPassword());
}
    

圖17 UserEJB為Entity Bean

點選圖17右下角”Deployment Settings”鈕,可見到圖18畫面,
選擇左下角”Method Implementation Queries”之”Container Methods”
之”createRow”,即可看到圖18之SQL Query:

圖18 UserEJB對應資料表為UserEJBTable

由上述所列程序代碼及圖,讀者應該可以了解使用者登入在EJBz tier的運作情形,在UserEJB也看到一個不一樣的用法,就是在Entity Bean上使用商業(yè)邏輯-matchPassword() 函數(shù),在大部份的EJB書籍或文件都告訴我們商業(yè)邏輯應該用Session Bean去實作,資料則用Entity Bean來實作,但在這里密碼比較的商業(yè)邏輯是非常簡單的,只用了一行程序就解決了,所以也不需為了它另外再做一個Session Bean,
也許讀者會問為什么不將此函數(shù)寫在SignOnEJB?筆者認為密碼比對不只在登入流程上會使用,在使用者基本資料編輯時也可能會用到,所以還是放在UserEJB比較適合:)     我們能夠知道使用者基本資料是存于UserEJBTable,我們要如何知道此資料表所存內(nèi)容是什么?請參閱注4。


現(xiàn)在請重復第一階段驗證步驟將程序重新編輯及部署,可發(fā)現(xiàn)程序如我們所預期般執(zhí)行!

圖19 第二階段程序驗證結果

第三階段
大家還記得在SignOnFilter之validateSignOn()函數(shù),驗證成功會將
SIGNED_ON_USER變量(對應實際變量為j_signon)的值設為真值(true):

hreq.getSession().setAttribute(SIGNED_ON_USER, new Boolean(true));

當我們再次從首頁進入使用者基本資料瀏覽頁,會再度給SignOnFilter攔截,從Session取出SIGNED_ON_USER變量(對應實際變量為j_signon),經(jīng)判斷為真值(true),SignOnFilter則會放行轉導至使用者基本資料瀏覽畫面(customer.do),讀者可參考下列程序代碼加入偵察碼,在約125列doFilter()函數(shù):

  
 boolean signedOn = false;
    if (hreq.getSession().getAttribute(SIGNED_ON_USER) != null) {
       signedOn
=((Boolean)hreq.getSession().getAttribute(SIGNED_ON_USER)).booleanValue();
        //加入偵察碼
System.out.println("signedOn="+signedOn);
    } else {
       hreq.getSession().setAttribute(SIGNED_ON_USER, new Boolean(false));
    }
       // jump to the resource if signed on
       //若已登入過,則結束此Filter工作,進入Filter chain,以本例來說,它為
Filter chain中最后一個Filter,所以就是不做任何事,讓使用者進入他的目的畫面
       if (signedOn) {
           //加入偵察碼
           System.out.println("使用者已登入過!");
           chain.doFilter(request,response);
           return;
       }

參考前面敘述重新編譯部署后執(zhí)行,可得下圖預期結果:

圖20 第三階段程序驗證結果

customer.do

到這里相信讀者能對Petstore登入流程控管有更深入的了解,通過登入流程就到達了使用者基本數(shù)據(jù)瀏覽畫面(customer.do),*.do與前二篇介紹的*.screen不同,*.screen代表的是一個畫面,如main.screen代表首頁,它可由多個.jsp所組成;*.do代表的是一個動作,customer.do代表對使用者基本資料相關動作,如新增、修改、刪除,它會透過EJB tier與資料庫互動,最后得到的結果也是要展現(xiàn),運用*.screen的機制組成結果畫面,所以我們可以這樣想象*.screen是名詞,*.do是動詞,以本例來說,只是讀取資料,雖然運用到*.do,但并沒有任何動作,為了能讓讀者了解整個架構,還是在此稍事說明。

請開?deploytool,點選左邊窗格Files > applications > PetstoreEAR > PetstoreWAR > MainServlet,選擇右邊 Alias頁,可發(fā)現(xiàn)處理*.do即是MainServlet

圖21 *.do對應MainServlet

點選General頁可找到實際對應類別,源碼在
Petstore_home/src/waf/src/controller/com/sun/j2ee/blueprints/waf/controller/web/MainServlet.java
,在約79列可找到初始函數(shù):

public void init(ServletConfig config) throws ServletException {
        //讀取預設語系,值為”en_US”
        String defaultLocaleString = config.getInitParameter("default_locale");
        defaultLocale = I18nUtil.getLocaleFromString(defaultLocaleString);
        this.context = config.getServletContext();
        String requestMappingsURL = null;
        try {
            //讀取mapping.xml
            requestMappingsURL =
context.getResource("/WEB-INF/mappings.xml").toString();
        } catch (java.net.MalformedURLException ex) {
            System.err.println("MainServlet: initializing ScreenFlowManager
malformed URL exception: " + ex);
        }
       //將mappings.xml轉成HashMap類別并存入ServletContext
       urlMappings = URLMappingsXmlDAO.loadRequestMappings(requestMappingsURL);
       context.setAttribute(WebKeys.URL_MAPPINGS, urlMappings);
       eventMappings = URLMappingsXmlDAO.loadEventMappings(requestMappingsURL);
       context.setAttribute(WebKeys.EVENT_MAPPINGS, eventMappings);
       //ScreenFlowManager初始化并存入ServletContext
       getScreenFlowManager();
       //RequestProcessor初始化并存入ServletContext
       getRequestProcessor();
}

圖22 MainServlet實際對應類別

MainServlet在初始化時會讀取預設語系及對應設定檔(mapping.xml),及初始化ScreenFlowManager、RequestProcessor,預設語系設定在MainServlet之init. Parameter頁,值為”en_US”(英語系)。


圖23 MainServlet之init. Parameter設定

對應設定文件位置在
Petstore_home/src/apps/petstore/src/docroot/WEB-INF/mappings.xml
,我們可在約95行找到customer.do的相關設定

<url-mapping url="customer.do" screen="customer.screen" >
<web-action-class>com.sun.j2ee.blueprints.petstore.controller.web.actions.CustomerHtmlAction</web-action-class>
</url-mapping>
這一段卷標(tag)有三個參數(shù):
url:標示對應動作
web-action-class:實際執(zhí)行類別
screen:結果顯示畫面

     *.do的運作機制是Servlet接收到request,從mappings.xml找到對應的url,
RequestProcessor將對應的web-action-class初始化并執(zhí)行,ScreenFlowManager
將執(zhí)行結果傳回給*.screen,再運用本系列前兩篇所介紹*.screen機制組成實際畫面,響應給使用者,大致的流程是這樣,實際上更復雜,因牽涉到Web tier與EJB tier間溝通,但以本例來說,RequestProcessor對應web-action-class(CustomerHTMLAction)并沒有做什么事,后續(xù)RequestProcessor接收到結果顯示畫面(customer.screen),則進行轉導(forward)動作。
     mappings.xml讀取后轉成HashMap類別存入ServletContext供所有進入
Petstore系統(tǒng)的人使用,接著將ScreenFlowManager及RequestProcessor初始
化并存入ServletContext。

bill-轉自:csdn

(出處:http://m.survivalescaperooms.com)



發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 平顶山市| 五台县| 马尔康县| 沙田区| 巴中市| 旬邑县| 云安县| 孙吴县| 扶绥县| 龙泉市| 鄂托克旗| 南溪县| 鸡泽县| 南城县| 遂宁市| 芜湖市| 五大连池市| 南召县| 揭阳市| 巨野县| 马鞍山市| 广昌县| 普格县| 鄢陵县| 凉山| 德江县| 翁牛特旗| 津南区| 新沂市| 临朐县| 迁西县| 盘锦市| 汝城县| 疏勒县| 平谷区| 呼伦贝尔市| 巴南区| 曲阳县| 行唐县| 周口市| 荥经县|