国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
電子商務(wù)模型的JSP、JavaBean實(shí)現(xiàn)

電子商務(wù)模型的JSP、JavaBean實(shí)現(xiàn)



引言

      現(xiàn)在,開發(fā)和管理一個(gè)電子商務(wù)系統(tǒng)需要高效率的開發(fā)和利用網(wǎng)絡(luò)資源,特別是如果你想讓你的顧客在網(wǎng)上購買你的產(chǎn)品或是取得你提供的服務(wù)的話,更要注意這一點(diǎn)。構(gòu)建一個(gè)這樣的商務(wù)網(wǎng)站來實(shí)現(xiàn)你商業(yè)上的目的并不是一件非常簡單的工作,在開發(fā)電子商務(wù)網(wǎng)站的時(shí)候,我們就要充分的利用搞技術(shù)含量的技術(shù),我們可以利用到最先進(jìn)的Java 技術(shù):Java Server Pages(JSP),Java Servlets 和JavaBeans(甚至是EJB),它們各自都有自己的不同的優(yōu)點(diǎn),因此了解在構(gòu)建一個(gè)電子商務(wù)網(wǎng)站時(shí)如何合理的利用它們各自的優(yōu)勢,并且把它們聯(lián)合起來以完成你想達(dá)到的效果是非常重要的。

  當(dāng)然,我們可以只使用 JSP來構(gòu)建電子商務(wù)系統(tǒng),比如一個(gè)簡單的購物車系統(tǒng),但是如果你要想完成一個(gè)有效的的應(yīng)用程序,并使它用于商業(yè)上,則需要綜合以上我所說的三種技術(shù)相互補(bǔ)充的力量。讓我們來看怎么把它們聯(lián)合起來以完成最好的效果吧!我們都知道,JSP是Sun公司倡導(dǎo)的用來替代微軟ASP的純Java替代品,JSP技術(shù)發(fā)展壯大了Java Servlet技術(shù),事實(shí)上, JSP引擎在運(yùn)行JSP時(shí)也把JSP頁面翻譯成 Servlets;而不用我多說,大家一定都知道Servlets在網(wǎng)絡(luò)編程世界是非常流行的,因?yàn)樗诶碚撋虾蛯?shí)踐上都是可以完全取代 CGI腳本的,Servlets能產(chǎn)生動態(tài)的網(wǎng)頁,這是通過把靜態(tài)的HTML與數(shù)據(jù)庫查詢或事務(wù)性服務(wù)提供的內(nèi)容混合起來實(shí)現(xiàn)的。JSP則是通過在HTML頁面中內(nèi)嵌Java代碼這條途徑來實(shí)現(xiàn)生成動態(tài)的網(wǎng)頁的目的的,把Java代碼插入到HTML頁的這種能力極大的增加了基于Java Servlet網(wǎng)絡(luò)體系結(jié)構(gòu)的靈活性。

  為了產(chǎn)生 HTML , servlet 必須用println()輸出格式化的HTML字符串,如:

   out.println("<html>");
   out.println("<br><br>購物車系統(tǒng)");
   out.println("</html>");

  從上面的代碼段中可以看出,servlet用println()輸出HTML頁面,也就是說,當(dāng)編寫一個(gè) Java Servlet時(shí),開發(fā)者必須充當(dāng)程序員和網(wǎng)頁設(shè)計(jì)師兩個(gè)身份。而JSP則是在HTML中嵌入簡單的Java代碼,使普通的HTML網(wǎng)頁設(shè)計(jì)師也能寫出優(yōu)秀的動態(tài)網(wǎng)頁,這樣就使網(wǎng)站的設(shè)計(jì)沿著兩條平行的軌道,即Java程序設(shè)計(jì)和HTML頁面設(shè)計(jì)共同進(jìn)行下去,從而加快網(wǎng)站開發(fā)的速度和開發(fā)的質(zhì)量。JSP也支持業(yè)務(wù)邏輯組件和現(xiàn)有的組件之間的寬松連接,從而做到可重用性。

  下面,我想通過一個(gè)簡單的購物車程序來說明一下 JSP,Servlet和Bean在網(wǎng)絡(luò)體系結(jié)構(gòu)中是怎樣相互作用的,并且借這個(gè)例子解釋編寫一個(gè)實(shí)際可用的電子商務(wù)應(yīng)用程序應(yīng)該注意的一些問題。



簡單購物車的實(shí)現(xiàn)方案


      我們的購物車方案實(shí)際上是一種簡化了的在線商店的模型:顧客選擇商品,添加到他們的購物車中,然后通過一系列形式最終購買這些商品。上圖中就顯示了我們的應(yīng)用程序體系結(jié)構(gòu)是如何把 JSP、servlets 和 JavaBeans有機(jī)的結(jié)合起來的,從圖上更可以看出,只使用 JSP來構(gòu)建一個(gè)簡單網(wǎng)絡(luò)應(yīng)用程序是可行,但是一個(gè)有效的應(yīng)用程序是這三種技術(shù)共同作用的結(jié)果。

      圖2解釋了model-view-controller( MVC )模式,它把應(yīng)用程序劃分成獨(dú)立的數(shù)據(jù)管理(Model),表現(xiàn)形式(View)和控制組件(Controller),成為最先進(jìn)的圖形用戶接口的基礎(chǔ),這些劃分模塊支持獨(dú)立開發(fā)并且可以重復(fù)使用組件。我們也能把 MVC 模式應(yīng)用于我們的網(wǎng)絡(luò)應(yīng)用程序中:JSP最適合充當(dāng)實(shí)現(xiàn)網(wǎng)絡(luò)應(yīng)用程序的對外表現(xiàn)的部分;而JavaBeans封裝了提供給Web網(wǎng)站的服務(wù)信息內(nèi)容并且簡化了數(shù)據(jù)在體系結(jié)構(gòu)組件之間的傳輸;Servlet則正好充當(dāng)控制者和協(xié)調(diào)用戶請求和應(yīng)用程序信息、更新程序數(shù)據(jù)等功能。



    好,前面我們已經(jīng)有了“CustomerServlet”大致的設(shè)計(jì)方案,現(xiàn)在讓我們來看看編寫我們應(yīng)用程序上的一些細(xì)節(jié)問題。

  代碼1 CustomerServlet.java

  package shoppingcart;

  import javax.servlet.*;
  import javax.servlet.http.*;
  import java.io.IOException;
 
  public class CustomerServlet extends HttpServlet {
  public void doGet(HttpServletRequest request,
   HttpServletResponse response) 
   throws ServletException, IOException {
    doPost(request, response);
   }
  // 處理顧客請求
  public void doPost(HttpServletRequest request,HttpServletResponse response) 
      throws ServletException, IOException {

   // 取得請求的Session對象 
   HttpSession session = request.getSession(true);
   BasketBean basket = null;

   file://如果沒有購物車則創(chuàng)建一個(gè)新的如果已存在,則更新它
   basket = (BasketBean)session.getAttribute(BasketBean.BASKET);
   if(basket == null) {
    // 新的顧客,創(chuàng)建一個(gè)購物車。
    basket = new BasketBean();
    session.setAttribute(BasketBean.BASKET, basket);
   }
   else {
    // 已存在的顧客,保存籃中的內(nèi)容。
    basket.savePurchases(request);
   }

   // 取得當(dāng)前的工作流程。

   RequestDispatcher rd = null;
   String nextPage = request.getParameter(BasketBean.PAGE);

   if (nextPage == null || 
    nextPage.equals(BasketBean.UPDATE)) {
    // 從目錄中查找選擇

    rd = getServletConfig().getServletContext().getRequestDispatcher("Inventory.jsp");
   }
   else if (nextPage.equals(BasketBean.PURCHASE)) { 
    // 提供購買信息
    rd = getServletConfig().getServletContext()
    .getRequestDispatcher("Purchase.jsp");
   }
   else if (nextPage.equals(BasketBean.RECEIPT)) {
    file://  提供購買信息

    rd = getServletConfig().getServletContext().getRequestDispatcher("Receipt.jsp");
   }

   if (rd != null) {
    rd.forward(request, response);
   }
  }

  }


      上面的程序段顯示了CustomerServlet類中的doGet()和doPost()方法。CustomerServlet類做了兩件事情來控制我們應(yīng)用程序的工作流程:

       一、通過 BasketBean 類實(shí)現(xiàn),保持購物車組件的狀態(tài),;

       二、它通過一系列的JSP頁面向顧客發(fā)送請求。

       一旦我們的購物車與某一個(gè)特定的顧客session相聯(lián)系,顧客的BasketBean對象的實(shí)例就會存儲在 HttpSession對象中。一個(gè)以普通ID進(jìn)入CustomerServlet工作流程的客戶,他會產(chǎn)生很多動作,servlet引擎提供了HttpSession對象來組織并存儲這一系列的相互作用(Session對象為存儲和取回任何使用唯一的鍵/值對的Java對象提供了方便的方法)。在CustomerServlet類中 ,我們首先通過HttpSession session = request.getSession(true)從 servlet 引擎中取得Session對象,大家都可以看到,我們傳遞了true值,意思是我們告訴Servlet引擎,如果一個(gè)session對象已經(jīng)不存在了,就新建一個(gè);然后我們查看Session中是否有我們的購物車,如果我們找不到購物車,我們就知道這個(gè)購物Session剛剛開始,我們必須新建一輛購物車,并且把它保存在Session對象中,如果我們能夠在Session中找到購物車,那我們就知道顧客正處在一個(gè)購物期間,那時(shí)就必須存儲購物車當(dāng)前的狀態(tài)。在查看了購物車的狀態(tài)之后,我們把顧客的請求發(fā)送到相應(yīng)的JSP頁中去,請求本身包含一個(gè)狀態(tài)參數(shù)(BasketBean.PAGE)告訴CustomerServlet把請求發(fā)送到哪里,我們的控制器取回這個(gè)參數(shù),然后使用一個(gè)RequestDispatcher對象把請求提交給下一個(gè)JSP頁。


  代碼段2:BasketBean類

  package shoppingcart;

  import javax.servlet.http.HttpServletRequest;
  import java.util.Hashtable;
  import java.util.Enumeration;

  public class BasketBean {
   final static public String BASKET = "Basket" ;
   final static public String PAGE = "Page" ;
 
   /*
    工作流程的狀態(tài)
   */ 

   final static public String UPDATE = "Update" ;
   final static public String PURCHASE = "Purchase" ;
   final static public String RECEIPT = "Receipt" ;

   /* 
    當(dāng)前購物籃中有那些商品。 
    主鍵是商品號 ,值為 Product對象
   */ 
  private Hashtable products_ = new Hashtable();
 
  public BasketBean() {
   }

  /* 
   計(jì)算籃中的商品的總價(jià)值。 
  */ 
  public double getTotal() {
   double totalPrice = 0.0 ;
   Enumeration e = products_.elements();
   while(e.hasMoreElements()) {
    Product product = (Product)e.nextElement();
    totalPrice += product.getPieces() *
    product.getPrice();
   }
   return totalPrice;
   }
 
  /*
   取得籃中某個(gè)商品的個(gè)數(shù)。
  */ 
  public double getPieces(Product p_in_inv) {
   int SKU = p_in_inv.getSKU();
   Product p = (Product)products_.get(
   Integer.toString(SKU));
   if(p == null)
    return 0.0 ;
   else
    return p.getPieces();
   }
 
   /*
    用當(dāng)前的選擇更換籃中的內(nèi)容。

   */
  public void savePurchases(HttpServletRequest request) {
   Product[] products = InventoryBean.getCatalogue();
   String[] lbValues = request.getParameterValues("pieces" );
   if (lbValues != null) {
    products_.clear();
    for (int i = 0 ; i < lbValues.length; i++) {
     double lbs = Double.parseDouble(lbValues[i]);
     if(lbs > 0 ) {
      Product p = null;
      p = (Product)products[i].clone();
      p.setPieces(lbs);
      products_.put(Integer.toString(p.getSKU()), p);
     }
    }
   }
  }

  file://利用一個(gè)函數(shù)實(shí)現(xiàn)統(tǒng)一的顯示商品價(jià)格的方式
  public static String getStringifiedValue(double value) {
   String subval = "0.00" ;
   if (value > 0.0 ) {
    subval = Double.toString(value);
    int decimal_len = subval.length() - (subval.lastIndexOf('.') + 1 );
    if(decimal_len > 1 )
     subval = subval.substring(0 , subval.lastIndexOf('.') + 3 );
    else
     subval += "0" ;
    }
    return subval;
   }

   /* 
   清空籃內(nèi)的東西

   */ 
   public void clear() {
    products_.clear();
   }
  }

  代碼段2中 BasketBean類實(shí)現(xiàn)購物車應(yīng)用程序中一個(gè)簡單的數(shù)據(jù)管理模型,它提供了一個(gè)方法,用于取得一個(gè)顧客正在購買的貨物的信息,還提供了一個(gè)方法用來更新購物車的內(nèi)容,我們使用一張哈希表來維護(hù)顧客請求的商品列表。InventoryBean對象管理商品的目錄,我們是使用一個(gè)數(shù)組來實(shí)現(xiàn)商品的目錄的。每個(gè)Product類的實(shí)例存儲四個(gè)屬性:商品名字,商品標(biāo)識號,單價(jià)和購買的數(shù)量,只要顧客購買了東西,Product類的實(shí)例就會改變。

  JSP顯示頁面

          我們的購物車方案中設(shè)定了3個(gè)JSP 頁面: Inventory.jsp , Purchase.jsp和Receipt.jsp (代碼見下)。應(yīng)用程序發(fā)送Inventory.jsp頁面給新來的顧客,顧客通過不斷的更新Inventory.jsp,來挑選商品;顧客選擇好想要購買的商品以后,應(yīng)用程序就會把顧客的購買請求發(fā)送到Purchase.jsp頁,進(jìn)行處理;最后,顧客證實(shí)確實(shí)購買這些商品,應(yīng)用程序把顧客請求發(fā)送到Receipt.jsp(其過程請參看圖三)。


        我和說明的方便,我想把JSP的基本內(nèi)容再簡要的向大家介紹一下。JSP頁面是使用特定的JSP標(biāo)記與標(biāo)準(zhǔn)的 HTML混合,除了固定的模板數(shù)據(jù)以外,JSP頁還能包括指令,腳本單元和動作,我們購物車系統(tǒng)也說明了以上三點(diǎn),現(xiàn)在我想就這三個(gè)問題簡單的談一談。

          在JSP頁面中,我們可以使用JSP指令將一些與頁面有關(guān)的信息傳遞到JSP引擎,指令的主要作用就是用來與JSP引擎之間進(jìn)行溝通的,JSP中的指令是有語法規(guī)范的:<%@ directive %> 

  page指令

      page指令定義了一系列與JSP頁面相關(guān)的屬性,并用它們與JSP引擎進(jìn)行通信。例如, 在Inventory.jsp中使用的一條page指令:<%@ page buffer="5kb" language="java" import="shoppingcart.*" errorPage="Error.jsp" %> 這條指令告訴JSP引擎,輸出緩沖區(qū)大小是5k,在溢出之前輸出緩沖區(qū)的輸出流,它也向JSP引擎說明,當(dāng)前頁使用的腳本語言是Java語言,并請求引擎導(dǎo)入shoppingcart包中的所有Java類,最后,它還指示如果有任何無法處理的錯(cuò)誤,就重定向到Error.jsp頁面中去。因?yàn)樵贘SP1.1中,只能使用 Java作為腳本語言,所以我們可以省略page指令中關(guān)于腳本語言的那部分說明。

         include指令用來指定JSP文件被編譯的時(shí)候,需要插入的文本或者代碼,被包含的文件要能夠被JSP引擎控制和訪問。Inventory.jsp文件也使用了include指令:

  <%@ include file="header.html" %> 
 ?。?@ include file="footer.html" %> 

  第一個(gè)指令為我們的頁面插入了一個(gè)標(biāo)準(zhǔn)的頁眉;第二個(gè)指令則插入一個(gè)標(biāo)準(zhǔn)的注腳。我們可以使用這些指令為我們的JSP頁面創(chuàng)造一致的外觀。

  JSP腳本元素為你提供了把Java代碼插入由當(dāng)前的JSP頁面產(chǎn)生的Servlet功能。在JSP中,有三種腳本語言元素---聲明、小腳本和表達(dá)式。這些元素的語法形式是:

 ?。?! declaration; %>
  <% scriptlet %>
 ?。?= expression %>


           Inventory.jsp中三種元素都使用了。

        下面的JSP片段用來聲明局部變量保存當(dāng)前購物籃(BasketBean的實(shí)例)和產(chǎn)品目錄。

 ?。?! BasketBean basket;
        Product[] catalogue;
      %> 

  從上面我們可以看出,JSP 聲明必須以一個(gè)分號結(jié)束,并且這個(gè)聲明的范圍是整個(gè)JSP頁。

  
聲明這些局部變量以后,Inventory.jsp 使用一段小腳本從session對象中取回購物車對象(BasketBean)和商名目錄,如下。

  
<% basket =(BasketBean) session.getAttribute( BasketBean.BASKET);
          catalogue = InventoryBean.getCatalogue();
      %>


          所以我們可以看出,JSP 聲明和 JSP小腳本只是放在特定的JSP標(biāo)記之間的Java代碼,當(dāng)JSP引擎把一個(gè)JSP程序翻譯成一個(gè)servlet時(shí),它就把這些Java代碼內(nèi)嵌到新的Servlet代碼中去。

          前面我們說過,我們從一個(gè)session對象中取得購物車對象,這個(gè)session對象是一個(gè)內(nèi)部物體。JSP引擎提供一些內(nèi)部隱含對象,這些對象可以直接被引用,我們可以不事先聲明,也不需要專門的代碼來創(chuàng)建他們的實(shí)例。它們在小腳本和表達(dá)式中總是可以使用的,而不需要預(yù)先聲明。JSP 1.1 規(guī)范中列出內(nèi)部隱含對象完整的集合。在程序中,另一個(gè)象這樣的對象就是 HttpServletRequest對象(request),它在CustomerServlet類中作為一個(gè)參數(shù)被傳遞到 doPost()方法中,這就意味著Inventory.jsp 能夠通過調(diào)用request.getSession(true).getAttribute(BasketBean.BASKET)來取回購物車的信息了。

  在JSP中表達(dá)式和小腳本為JSP動態(tài)生成網(wǎng)頁提供一個(gè)強(qiáng)有力的工具。從下面的Inventory.jsp程序中我們可以看出,JSP代碼段循環(huán)訪問商品目錄并且動態(tài)地為每個(gè)產(chǎn)品產(chǎn)生HTML表格,我們使用小腳本編寫循環(huán),然后在每一行中都混合使用HTML和JSP表達(dá)式。

(注:JSP引擎把小腳本標(biāo)記之間的Java 代碼直接插入引擎內(nèi)部產(chǎn)生的 servlet 代碼。JSP引擎對待JSP表達(dá)式也是不同的。它先把JSP表達(dá)式變換成字符串,然后在內(nèi)部產(chǎn)生的servlet中把它們包入一個(gè)out.println()調(diào)用中。)

  代碼段3 Inventory.jsp

 ?。?--
    Inventory.jsp -
    顯示商品目錄并且獲取用戶購買的物品及其數(shù)量單價(jià)等信息

  -->

  <html>

 ?。?--
    頁面的頭部,使用另一個(gè)HTML頁面,通過include指令來實(shí)現(xiàn)

   --%>
 ?。?@ include file="header.html" %>

 ?。?--
    顯示標(biāo)題
   -->
  ?。糂R>
  ?。糃ENTER>
    ?。糡ITLE> 中國科學(xué)技術(shù)大學(xué)百貨商店</TITLE>
  ?。糉ONT SIZE="+1">
  ?。糂> 歡迎選購我們的商品</B>
  ?。?FONT>
 ?。糂ODY BGCOLOR="#FFFFF">

  ?。?--
    Page指令
   -->
  ?。?@ page import="shoppingcart.*" errorPage="error.jsp" %>

  ?。?--
    創(chuàng)建表單設(shè)定頁面布局

   --%>
  ?。糂R><BR>
  ?。糉ORM METHOD="post" ACTION="/shoppingcart/CustomerServlet">
  ?。糡ABLE WIDTH=450 CELLSPACING="0" CELLPADDING="0" BORDER="1">

  ?。?--
    創(chuàng)建表頭
   --%>
  ?。糡R>
   ?。糡D WIDTH=5% BGCOLOR="#ECA613"> <B>商品序列號</B></TD>
   ?。糡D BGCOLOR="#ECA613"> <B>商品描述</B></TD>
   ?。糡D WIDTH=5% ALIGN=center BGCOLOR="#ECA613" > <B>商品數(shù)量</B></TD>
   ?。糡D WIDTH=25% BGCOLOR="#ECA613"> <B>單價(jià)</B> </TD>
   </TR>

  ?。?--
    聲明一個(gè)購物籃,和一個(gè)Product商名目錄。
   --%>
  ?。?! BasketBean basket;
    Product[] catalogue;
   %>

   <%--
    從HttpSession對象中取回當(dāng)前的購物籃,然后從Inventory對象中取回商品列表
   --%>
   <%
    basket = (BasketBean)session.getAttribute(BasketBean.BASKET);
    catalogue = InventoryBean.getCatalogue();
   %>

  ?。?--
    循環(huán)顯示出Product中商品列表中的每一個(gè)商品
   --%>

   <%
    for(int i = 0; i < catalogue.length; i++) {
     Product product = catalogue[i];
   %>

  ?。糡R>
    <TD> <%= product.getSKU() %> </TD>
   ?。糡D> <%= product.getName() %> </TD>
   ?。糡D> <INPUT TYPE=text SIZE=6 MAXLENGTH=6
     NAME="pieces" VALUE=<%= basket.getPieces(product)%>>
   ?。?TD>
   ?。糡D ALIGN=right> <%= product.getPrice() %> </TD>
   </TR>
 ?。? } %>

  <%--
   表中顯示總共化去多少錢
   --%>
  ?。糡R>
   ?。糡D COLSPAN=4 align=right BGCOLOR="#ECA613"><B>
     總共人民幣<%= basket.getStringifiedValue(basket.getTotal()) %>元 </B></TD>
  ?。?TR>
 ?。?TABLE>

 ?。?--

   發(fā)送購買請求

  --%>

 ?。糂R>
  ?。糡ABLE WIDTH=450 CELLSPACING="0" CELLPADDING="0" BORDER="0">
    <TR>
    ?。糡D ALIGN=left><INPUT TYPE=submit
      NAME=<%= BasketBean.PAGE %> VALUE=<%= BasketBean.UPDATE %>></TD>
    ?。糡D ALIGN=left><INPUT TYPE=reset VALUE="取消"></TD>
     <TD ALIGN=right><INPUT TYPE=submit
      NAME=<%= BasketBean.PAGE %> VALUE=<%= BasketBean.PURCHASE %>></TD>
   ?。?TR>
  ?。?TABLE>
  </FORM>
 ?。?CENTER>

  <BR><BR>
 ?。?@ include file="footer.html" %>

  </body>
 ?。?html>

           Receipt.jsp程序中,我們使用了JSP動作,來處理顧客發(fā)送來請求的參數(shù)值。因此我也想簡要的介紹一下JSP中的動作元素。除了指令和腳本元素外,JSP動作也是 JSP頁面不可缺少的一部分,一個(gè)動作元素有兩種基本的語法形式:

 ?。紁refix:tag attr_list /> 
 ?。紁refix:tag attr_list> 
 ?。糱ody> 
 ?。?prefix:tag> 

  當(dāng)動作有語句體時(shí),我們必須使用后一種表式方法。動作背后基本的概念就是與特定的JSP標(biāo)簽聯(lián)系的“標(biāo)簽處理器”。這些處理器是基于標(biāo)簽的一些代碼段,用來執(zhí)行某些操作。JSP引擎提供了一些標(biāo)準(zhǔn)的動作,所有的這些動作都要以“ jsp ”為前綴。例如,我們的電子商店使用一個(gè)助手Bean來簡化請求參數(shù)分析,我們就要使用<jsp:useBean>元素聲明這樣一個(gè)Bean:<jsp:useBean id="receiptBean" scope="request" class="shoppingcart.ReceiptBean" /> JSP聲明了一個(gè)對象變量,取名為receiptBean,作為 ReceiptBean 的一個(gè)實(shí)例,在當(dāng)前請求完成時(shí)就會被釋放。使用Bean的主要優(yōu)點(diǎn)就是它分析并且返回 HTML請求參數(shù)的簡潔性。

         在聲明完Bean以后,我們就可以使用<jsp:setProperty>元素從HTML請求中獲取參數(shù),來設(shè)置它的屬性值。我們可以顯式的指出屬性和HTML 參數(shù)的名字,來設(shè)置屬性值。例如,下面是Receipt.jsp中用來設(shè)置我們的ReceiptBean實(shí)例的屬性的一些語句:<jsp:setProperty name="receipt_bean" property="name" param="name" /> 如果我們的屬性名和相應(yīng)的參數(shù)名相同,我們可以指示用一個(gè)JSP元素來設(shè)置所有的屬性:<jsp:setProperty name="receipt_bean" property="*" /> 這個(gè)單獨(dú)的元素告訴引擎,使用 Java映像來匹配所有的JSP參數(shù)和JavaBean屬性名,然后使用HTML請求信息中的值來設(shè)置JavaBean的屬性值。同樣,我們使用<jsp:getProperty>元素從助手Bean中返回屬性值。例如,下面是我們返回屬性的語句:<jsp:getProperty name="receipt_bean" property="name" /> 在ReceiptBean類的代碼中,每個(gè)在Receipt.jsp中被分析的參數(shù),在我們程序Bean中都有一個(gè)相關(guān)聯(lián)的用來設(shè)置了取得的方法:例如,<jsp:setProperty name="receipt_bean" property="name" param="name" />有一個(gè)相關(guān)聯(lián)的設(shè)置方法:void setName(String phone);同樣, <jsp:getProperty name="receipt_bean" property="name" />也有一個(gè)相關(guān)聯(lián)的取得方法:String getName();

  代碼段4:Receipt.jsp

 ?。?@ page import="shoppingcart.*" errorPage="error.jsp" %>

 ?。糷tml>
  ?。糡ITLE> 中國科學(xué)技術(shù)大學(xué)百貨商店收銀臺</title>

 ?。糂ODY BGCOLOR="#FFFFF">
  ?。糂R><BR>
  ?。?@ include file="header.html" %>

   <CENTER>
   ?。糂R>
   ?。糉ONT SIZE="+1"> <B> 顧客信息</B> </FONT> 
   ?。糂R><BR>
   ?。糉ORM METHOD="post" ACTION="/shoppingcart/CustomerServlet">
   ?。糡ABLE WIDTH=450 CELLSPACING="0" CELLPADDING="0" BORDER="1"> 
    ?。糡R>
      <TD WIDTH=10% BGCOLOR="#ECA613"> <B>姓名:</B></TD>
     ?。糡D WIDTH=90%> <INPUT TYPE=text SIZE=50 NAME="name" ></TD>
    ?。?TR>
     <TR>
     ?。糡D WIDTH=10% BGCOLOR="#ECA613"> <B>EMail: </B></TD>
      <TD WIDTH=90%> <INPUT TYPE=text SIZE=50 NAME="email"></TD>
    ?。?TR>
    ?。糡R>
     ?。糡D WIDTH=10% BGCOLOR="#ECA613" > <B>地址</B></TD>
     ?。糡D WIDTH=90%> <INPUT TYPE=text SIZE=50 NAME="address"></TD>
    ?。?TR>
    ?。糡R>
      <TD WIDTH=10% BGCOLOR="#ECA613"> <B>電話</B> </TD>
     ?。糡D WIDTH=90%> <INPUT TYPE=text SIZE=50 NAME="phone"></TD>
     </TR>
   ?。?TABLE>

   ?。?
     BasketBean basket = (BasketBean)session.getAttribute(BasketBean.BASKET);
    %>
   ?。糂>
     總共價(jià)格人民幣<%= basket.getStringifiedValue(basket.getTotal()) %>元
   ?。?B>
   ?。糂R>
   ?。糂R>
   ?。糡ABLE WIDTH=450 CELLSPACING="0" CELLPADDING="0" BORDER="0">
    ?。糡R>
      <TD ALIGN=left><INPUT TYPE=reset VALUE="Reset"></TD>
     ?。糡D ALIGN=right><INPUT TYPE=submit NAME=<%= BasketBean.PAGE %> VALUE=<%= BasketBean.RECEIPT %> ></TD>
     </TR>
   ?。?TABLE>
   ?。?FORM>
  ?。?CENTER>
  ?。糂R><BR>
  ?。?@ include file="footer.html" %>
  </body>
 ?。?html>

  代碼段5:Confirm.jsp

   <!--
    Confirm.jsp -
    確認(rèn)顧客購買商品,并且顯示賬單

   -->

  ?。糷tml>

  ?。?--
    頁眉

    -->
  ?。?@ include file="header.html" %>

  ?。糂ODY BGCOLOR="#FFFFF">

  ?。糃ENTER>
   ?。糡ITLE> Grocery Joe's</TITLE>
    <FONT SIZE="+1">
   ?。糂>Receipt</B>
  ?。?FONT>

  ?。?--
    使用Page指令導(dǎo)入頁面
   -->
   <%@ page import="shoppingcart.*" errorPage="error.jsp" %>

  ?。?--
    聲明ReceiptBean的實(shí)例,用從request流中的數(shù)據(jù)設(shè)置屬性
   -->
  ?。糺sp:useBean id="receipt_bean" scope="request" class="shoppingcart.ReceiptBean" />

   <%--
   ?。糺sp:setProperty name="receipt_bean" property="name" param="name" />
   ?。糺sp:setProperty name="receipt_bean" property="email" param="email" />
    <jsp:setProperty name="receipt_bean" property="street1" param="address" />
   ?。糺sp:setProperty name="receipt_bean" property="phone" param="phone" />
   --%>
  ?。糺sp:setProperty name="receipt_bean" property="*" />
  ?。?jsp:useBean>

 ?。?--
   創(chuàng)建一個(gè)表,輸出顧客信息,并列出賬單。
  -->
  <BR><BR>
 ?。糡ABLE WIDTH=450 CELLSPACING="0" CELLPADDING="0" BORDER="0"> 
  ?。糡R>
   ?。糡D WIDTH=100%> <B>姓名:
    ?。糺sp:getProperty name="receipt_bean" property="name"/></B></TD>
  ?。?TR>
   <TR>
   ?。糡D WIDTH=100%> <B>EMail: 
    ?。糺sp:getProperty name="receipt_bean" property="email"/></B></TD> 
  ?。?TR>
   <TR>
   ?。糡D WIDTH=100% > <B>地址: 
   ?。糺sp:getProperty name="receipt_bean" property="address"/></B></TD> 
  ?。?TR>
  ?。糡R>
   ?。糡D WIDTH=100%> <B>電話:
   ?。糺sp:getProperty name="receipt_bean" property="phone"/></B></TD>
  ?。?TR>
 ?。?TABLE>

 ?。?--
    顯示出共花去多少錢
  -->
 ?。?
   BasketBean basket = (BasketBean)session.getAttribute(BasketBean.BASKET);
  %>
 ?。糂>
   總共價(jià)格人民幣<%= basket.getStringifiedValue(basket.getTotal()) %>元 </B>
  <% 
   basket.clear();
  %>

  ?。糂R>
  ?。糂R>
  ?。?CENTER>
   <BR><BR>

  ?。?@ include file="footer.html" %>
 ?。?body>
 ?。?html>

  代碼六:Error.jsp

 ?。糎TML>

 ?。糎EAD>
  ?。糡ITLE> 錯(cuò)誤處理頁面 </TITLE>
  </HEAD>

 ?。?@ page isErrorPage="true" %>

 ?。糂ODY BGCOLOR=Black TEXT="#FFFFFF" LINK="#FFFFFF" VLINK="#FFFFFF">

  <H1> 發(fā)生了一個(gè)錯(cuò)誤... </H1>

 ?。糂R><BR><BR>
  是: <BR>

  ?。?= exception.toString() %> <BR>


 ?。?BODY>
 ?。?HTML> 

  現(xiàn)實(shí)中的應(yīng)用程序模型

  前面我們介紹的這個(gè)程序,只是一個(gè)簡單的應(yīng)用程序,僅供大家參考。然而,一個(gè)真實(shí)的應(yīng)用程序其實(shí)和我們介紹的這個(gè)簡單應(yīng)用程序一樣遵循著 MVC模式 ;讓我們來看一看如何修改這個(gè)程序的某方面,來創(chuàng)造出一個(gè)更有現(xiàn)實(shí)意義的電子商務(wù)應(yīng)用程序。我們的電子商店應(yīng)用程序通過使用 BasketBean 類來實(shí)現(xiàn)了它的模型(Model),這存在著一些問題:它沒能定義一個(gè)標(biāo)準(zhǔn)的接口,這樣的缺陷限制了它的可維護(hù)性,可擴(kuò)展性和作為一個(gè)應(yīng)用程序的可伸縮性。

  應(yīng)用程序應(yīng)該為訪問應(yīng)用程序模型定義一個(gè)標(biāo)準(zhǔn)的接口,接口實(shí)際上是建立一個(gè)約定,允許不同的實(shí)現(xiàn)應(yīng)當(dāng)按照要求被“插入(plugged-in)”,“可插入”的實(shí)現(xiàn)形式可以用橋模式來說明,橋模式的目的就是從功能的任何特定實(shí)現(xiàn)形式中分離出抽象的功能。例如,我們的存貨清單數(shù)據(jù)最初是作為靜態(tài)的信息被內(nèi)嵌到Java 代碼中的(見附錄一InventoryBean.java),為了獲得程序的靈活性,我們可以把數(shù)據(jù)從代碼中提取出來,并在文件系統(tǒng)上存儲它;而隨著數(shù)據(jù)體積的不斷膨脹,一個(gè)最直接的想法就是把數(shù)據(jù)轉(zhuǎn)移到一個(gè)關(guān)系型數(shù)據(jù)庫( RDBMS )中存儲,如果我們的 BasketBean 實(shí)現(xiàn)一個(gè)標(biāo)準(zhǔn)的接口,那么我們就能重新實(shí)現(xiàn)這個(gè)接口來使用一個(gè)文件系統(tǒng)或一個(gè)關(guān)系型數(shù)據(jù)庫,而不用重寫 CustomerServlet類。因此,實(shí)際的應(yīng)用程序要求從代碼中分離數(shù)據(jù),數(shù)據(jù)是經(jīng)常變化的,但是代碼應(yīng)該盡可能少的變化,為能夠把我們的應(yīng)用程序移植到一個(gè)商務(wù)平臺上,最小的要求就是把它分割成的數(shù)據(jù)存取層和數(shù)據(jù)管理層。兩層結(jié)構(gòu)允許在不影響代碼的情況下增加數(shù)據(jù)。


    上圖顯示了在把數(shù)據(jù)與數(shù)據(jù)存取分開后并在定義一個(gè)標(biāo)準(zhǔn)的接口的情況下如何進(jìn)行程序設(shè)計(jì)的流程圖。
    有時(shí)候,數(shù)據(jù)的可伸縮性和數(shù)據(jù)交易的要求迫使我們涉及數(shù)據(jù)管理體系的第三級結(jié)構(gòu),CORBA 或企業(yè)版JavaBean(EJB)提供的數(shù)據(jù)管理服務(wù)接口現(xiàn)在已經(jīng)被普便使用了,如果我們的BasketBean實(shí)現(xiàn)了一個(gè)標(biāo)準(zhǔn)的接口,那么我們就能把它作為一種分布式的服務(wù)來重新實(shí)現(xiàn)它。
    下圖顯示了我們應(yīng)用程序模型的三層實(shí)現(xiàn)形式。



  寬松組件連接

      JSP應(yīng)用程序能遵從 MVC 模式的原因之一就是這個(gè)模式支持清楚地定義model,view和controller組件所扮演的角色,我們應(yīng)該保持這些部件之間盡可能的寬松的聯(lián)合。

  然而,我們并沒有使 CustomerServlet類寬松聯(lián)合,請看下面的語句

  file://取得當(dāng)前的工作流程的狀態(tài)。

  RequestDispatcher rd = null;
  String state = request.getParameter( BasketBean.STATE);
  if (state == null || state.equals(BasketBean.UPDATE)) 
   { 
    // 從商品目錄中選擇
    rd = getServletConfig().getServletContext().getRequestDispatcher( "/jsp/Inventory.jsp"); 
   } 

      控制器(controller)和表現(xiàn)形式(view)組件之間的緊密連接,使程序中如果改變一個(gè)組件就會改變相應(yīng)其他的組件。在我們的例子中,如果我們想把附加的JSP頁面添加到購物車工作流程中,我們也必須把附加的條件添加到 CustomerServlet中,這樣怎能談得上高可維護(hù)性和高伸縮性呢?如果我們能去掉CustomerServlet類和它的JSP頁面之間的緊密連接,我們的應(yīng)用程序就會有更多的可維護(hù)性和可伸縮性。要使這種緊密連接減小到最少程度的一個(gè)方法就是為每一個(gè)JSP頁面都創(chuàng)造一個(gè)助手Bean,我們在 CustomerServlet 中安裝這些助手Bean來管理所有的相關(guān)聯(lián)的 JSP 頁到來的HTML請求。
    象這樣封裝每一個(gè)對象中的請求的模式是一種命令模式(command pattern)。


    就象橋模式(bridge pattern)一樣,實(shí)現(xiàn)一個(gè)命令模式的關(guān)鍵是聲明每個(gè)請求處理器必須實(shí)現(xiàn)的通用的接口。在我們的例子中,這個(gè)接口的最簡單的形式可能是一個(gè)單獨(dú)的方法讓我們傳遞請求參數(shù)和BasketBean對象—例如redirect()。因?yàn)榻涌诘拿恳环N具體的實(shí)現(xiàn)形式支持這個(gè)方法, CustomerServlet 就能在任何給定的處理機(jī)制上,在不知道實(shí)現(xiàn)形式的任何特定信息的情況下調(diào)用接口,我們可以為每一個(gè)JSP頁設(shè)定助手Bean,并且根據(jù)需要使它復(fù)雜化,例如,它能夠驗(yàn)證request發(fā)來的數(shù)據(jù)參數(shù),不管是簡單的判斷輸入的是否為空值還是更復(fù)雜的任務(wù)象驗(yàn)證信用卡信息等等。

  一個(gè)JSP頁面只有一個(gè)輸入,但是它卻有多個(gè)輸出,這取決于提交按鈕的數(shù)量,每個(gè)輸出都能與一個(gè)不同的JSP頁相聯(lián)系。例如,Inventory.jsp 有兩個(gè)輸出,一個(gè)指向Purchase.jsp,另一個(gè)指回自己,我們能使用一個(gè)隱藏標(biāo)簽把每個(gè)助手Bean和輸出聯(lián)系起來。在 Inventory.jsp 中,我們可以使用

 ?。糡D ALIGN=left> 

   <INPUT TYPE=hidden NAME=<%= BasketBean.UPDATE %> VALUE="shoppingcart.UpdateHandler"> 
  ?。糏NPUT TYPE=submit NAME=<%= BasketBean.PAGE %> VALUE=<%= BasketBean.UPDATE %>> 
  </TD>

  代替下面的行:

 ?。糡D ALIGN=left>

   ?。糏NPUT TYPE=submit NAME=<%= BasketBean.PAGE %> VALUE=<%= BasketBean.UPDATE %>> 
 ?。?TD> 

      JavaBean“shoppingcart.UpdateHandler”將被我們的CustomerServlet類實(shí)例化,它包括一個(gè) CustomerServlet 將調(diào)用的重定向方法。UpdateHandler 會知道怎么驗(yàn)證參數(shù),更新模型,并且把請求提交給相應(yīng)的JSP頁,因此這是一條完善CustomerServlet的編程的非常好的途徑。
    

      小結(jié)

      這樣一來,JSP就能極大的擴(kuò)展了 servlet 技術(shù),由于支持 Java 腳本,JSP和Servlet就使網(wǎng)頁設(shè)計(jì)師能夠隨心所欲的開發(fā)出高品質(zhì)的動態(tài)網(wǎng)頁程序。但不管怎么說,JSP也是不會代替 servlets的,因?yàn)閟ervlets,JSP和JavaBeans在網(wǎng)絡(luò)體系結(jié)構(gòu)中起著互相補(bǔ)足的作用。通過遵從MVC模式, JSP應(yīng)用程序能夠獨(dú)立地?cái)U(kuò)大或提高用于后臺控制的servlet,JSP頁面和現(xiàn)實(shí)的應(yīng)用程序模型。應(yīng)用程序模型能被擴(kuò)展到一個(gè)兩層或三層的方案,并且增加助手Bean,這都能管理JSP工作流程和支持應(yīng)用程序組件之間的寬松聯(lián)接。

      附錄一、 InventoryBean.java類(下面我將不會對代碼進(jìn)行過多的解釋)

      package shoppingcart;

  public class InventoryBean {

  /*
   商品名稱

  */
  private static final String[] names = 
   { "牙膏", "肥皂", "毛巾", 
    "口香糖", "牙刷", "練習(xí)本", 
    "鋼筆"};

  /*
   商品序列號。 
  */
  private static final int[] skus = 
   { 1, 2, 3, 4, 5, 6, 7 };

  /*
   商品每件的價(jià)格。 
  */

  private static final double[] prices = 
   { 2.50, 3.90, 5.25, 1.00, 
    3.50, 0.40, 11.80};

  private Product[] catalogue_ = null;

  private static InventoryBean inventory_ = new InventoryBean();
  private InventoryBean() {
   catalogue_ = new Product[skus.length];
   for (int i = 0; i < skus.length; i++) {
    catalogue_[i] = createProduct(skus[i]);
   }
  }

  public static Product[] getCatalogue() {
   return inventory_.catalogue_;
  }

  private Product createProduct(int sku) {
   return new Product(sku, names[sku-1], prices[sku-1]);
   }
  }

附錄二、Product類

  package shoppingcart;

  public class Product implements Cloneable { 
  private int sku_ = 0;
  private String name_ = null;
  private double price_ = 0;
  private int Pieces_ = 0;

  public String toString() {
   return "商品序列號: " + sku_ + ", 商品名: " + name_ + 
   ", 單價(jià): " + price_ + ", 件數(shù): " + pieces_;
  }

  public Product(int sku,  String name, double price) {
   sku_ = sku;
   name_ = name;
   price_ = price;
  }

  public int getSKU() {
   return sku_;
  }

  public String getName() {
   return name_;
  }

  public double getPrice() {
   return price_;
  }

  public double getPieces() {
   return pounds_;
  }

  public void setPieces(int pieces) {
   pieces_ = pieces;
  }

  public Object clone() {
    Object dup = null;
    try {
     up = super.clone();
    }
    catch(CloneNotSupportedException ignore) { }
     return dup;
    }
  }


  附錄三、ReceiptBean類

  package shoppingcart;

  import javax.servlet.*;
  import javax.servlet.http.*;

  public class ReceiptBean {
  private String name_ = null;
  private String email_ = null;
  private String address_ = null;
  private String phone_ = null;
  public ReceiptBean() {
  }
  public void setName(String name) {
  name_ = name;
  }
  public String getName() {
   return name_;
  }
  public void setEmail(String email) {
   email_ = email;
  }
  public String getEmail() {
   return email_;
  }
  public void setAddress(String address) {
   address_ = address;
  }
  public String getAddress() {
   return address_;
  }
  public void setPhone(String phone) {
   phone_ = phone;
  }
  public String getPhone() {
   return phone_;
  }
  }
本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊舉報(bào)
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
JAVA面試題
JSP連接SQL數(shù)據(jù)庫實(shí)現(xiàn)查找/插入信息
JSP內(nèi)置對象
4.9 JSP的內(nèi)置對象 - request對象 - AJava
介紹一下JSP中application的用法。
關(guān)于JSP/Servlet字符編碼
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服