WEB开发网
开发学院软件开发Java Petstore源码追踪记(3)-商业逻辑处理(三) 阅读

Petstore源码追踪记(3)-商业逻辑处理(三)

 2007-12-23 12:24:03 来源:WEB开发网   
核心提示:图10 编译成功画面重新部署如:build deploy图11 部署成功画面现在我们可开启浏览器,依上述流程重新执行一次,Petstore源码追踪记(3)-商业逻辑处理(三),当进入http://localhost:8080/petstore/index.jsp,观察RI Console秀出登入页、登入失败页之URL:

  图10 编译成功画面

重新部署
如:build deploy

图11 部署成功画面

现在我们可开启浏览器,依上述流程重新执行一次,当进入http://localhost:8080/petstore/index.jsp,观察RI Console秀出
登入页、登入失败页之URL:

图12 登入页、登入失败页之URL

从首页点选使用者帐号浏览页,RI Console秀出目的页URL及找出customer.do为保护页:

图13 目的页URL及找出customer.do为保护页

第二阶段

登入画面(signon.screen)可从screendefinitions_en_US.xml找出内容对应档案为signon.jsp,它源码位置在petstore_home\src\apps\petstore\src\docroot,开启它请看约53列:

<waf:form name="existingcustomer" action="j_signon_check" method="POST">
  <table cellpadding="5" cellspacing="0" border="0">
   <tr>
   <td class="petstore" align="center" colspan="2">
    <b>Yes.</b>
   </td>
   </tr>
   <tr>
   <td class="petstore_form" align="right">
    <b>User Name:</b>
   </td>
   <td class="petstore_form">
   <c:choose>
   <c:when test="${cookie['bp_signon'] != null && cookie['bp_signon']
!=''}">
    <waf:input CSSClass="petstore_form"
               type="text"
               size="15"
              name="j_username"
          validation="validation">
    <waf:value><c:out value="${cookie['bp_signon'].value}"/></waf:value>
   </waf:input>
   </td>
  </tr>
  <tr>
以下略...

这是一个典型的Web-Form输入画面,使用了JSTL及Petstore自已写的自订卷标(Custom Tag),这些卷标的用法不是本文的讨论重点,请读者自行参阅相关文件、书籍,我们将焦点放在流程上,请注意上述的程序片段粗体部份,使用者将帐号(User Name)及密码(PassWord)输入后按登入(Sign In)钮,服务器(Web Server)会将request传送给” j_signon_check”这个奇怪的URL,我们再回到SignOnFilter,在初始的变量宣告上,可找到这个URL,约70列:

public static final String FORM_SIGNON_URL = "j_signon_check";

在doFilter()函式可发现下列程序接收Request进行验证,顺便加上侦察程序代码(Debug code),方便待会程序验证:

//判断使用者从登入画面(signon.screen)进行验证工作
if ((targetURL != null) && targetURL.equals(FORM_SIGNON_URL)) {
  System.out.PRintln("FORM SIGNON CHECK");
  validateSignOn(request, response, chain);
  // jump out of this method
  return;
}
接着在validateSignON()函式进行使用者验证工作,从Request取出使用者输入的字段值,若使用者有勾选Remember My UserName(记住我的帐号)功能,则产生Cookie记录使用者帐号,再来透过EJB tier从数据库读取资料进行比对,验证成功则将使用者帐号(USER_NAME)及是否已登入(SIGNED_ON_USER)参数存入session,从Request取出目的URL(ORIGINAL_URL),将网页转导就会到达我们的目的地-使用者基本资料浏览画面(customer.do)
;若验证有误则将网页转导到登入失败画面(signon_error.screen)
,请读者顺便加上侦察程序代码。


public void validateSignOn(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
    //从Request取出使用者输入的字段值
    // convert to a http servlet request for now
    HttpServletRequest hreq = (HttpServletRequest)request;
    HttpServletResponse hres = (HttpServletResponse)response;
    // get the user name
    String userName = hreq.getParameter(FORM_USER_NAME);
    // get the password
    String password = hreq.getParameter(FORM_PASSWORD);
    // check if the user wants userName set in cookie
    String rememberUserName =
     hreq.getParameter(REMEMBER_USERNAME);
    //若使用者有勾选Remember My User Name(记住我的帐号)功能,则产生Cookie记录使用者帐号
    if (rememberUserName != null) {
     // set a cookie with the username in it
     Cookie userNameCookie = new Cookie(COOKIE_NAME, userName);
     // set cookie to last for one month
     userNameCookie.setMaxAge(2678400);
     hres.addCookie(userNameCookie);
    } else {
      // see if the cookie exists and remove accordingly
      Cookie[] cookies = hreq.getCookies();
      if (cookies != null) {
        for (int loop=0; loop < cookies.length; loop++) {
          if (cookies[loop].getName().equals(COOKIE_NAME)) {
            cookies[loop].setMaxAge(0);
            hres.addCookie(cookies[loop]);

          }
        }
      }
    }
    //透过EJB从数据库读取资料进行比对
    //validate against the registered users
    SignOnLocal signOn = getSignOnEjb();
    //请加入侦察程序代码,方便稍候程序验证
    System.out.println("进行EJB tier使用者验证");
    //帐号及密码验证
    boolean authenticated = signOn.authenticate(userName, password);
    if (authenticated) {
      //验证成功则将使用者帐号(USER_NAME)及是否已登入(SIGNED_ON_USER)参数
存入Session
      // place a true boolean in the session
      if (hreq.getSession().getAttribute(USER_NAME) !
= null) {
        hreq.getSession().removeAttribute(USER_NAME);
      }
      hreq.getSession().setAttribute(USER_NAME, userName);
      // remove the sign on user key before putting it back in
      if (hreq.getSession().getAttribute(SIGNED_ON_USER) != null) {
        hreq.getSession().removeAttribute(SIGNED_ON_USER);
      }
      hreq.getSession().setAttribute(SIGNED_ON_USER, new Boolean(true));
//将网页转导就会到达我们的目的地-使用者基本资料浏览画面(customer.do)
      // redirect to the original destination
      String targetURL =
(String)hreq.getSession().getAttribute(ORIGINAL_URL);
      hres.sendRedirect(targetURL);
      return;
    } else {
      //若验证有误则将网页转导到登入失败画面(signon_error.screen)
      hres.sendRedirect(signOnErrorPage);
      return;
    }
   }

   //取得SignOn Local Stateless Session Bean Reference
   private SignOnLocal getSignOnEjb() throws ServletException {
     SignOnLocal signOn = null;
     try {
      InitialContext ic = new InitialContext();
      Object o = ic.lookup("java:comp/env/ejb/local/SignOn");
      SignOnLocalHome home =(SignOnLocalHome)o;
      signOn = home.create();
     } catch (javax.ejb.CreateException cx) {
       throw new ServletException("Failed to Create SignOn EJB: caught "
+ cx);

     } catch (javax.naming.NamingException nx) {
       throw new ServletException("Failed to Create SignOn EJB: caught "
+ nx);
    }
    return signOn;
   }

Object o = ic.lookup("java:comp/env/ejb/local/SignOn");

透过上述程序代码可追纵SignOnEJB相关信息:

(出处:http://www.cncms.com)


Tags:Petstore 源码 追踪

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接