实例讲解JSP Model2体系结构(中)
程序员文章站
2023-12-18 10:38:34
理解“音乐无国界” “音乐无国界”的主界面是jsp页 eshop.jsp(见代码清单1)。你会注意到,这个页面几乎只作为专门的用户界面,不承担任何处理任务――是一个最理...
理解“音乐无国界”
“音乐无国界”的主界面是jsp页 eshop.jsp(见代码清单1)。你会注意到,这个页面几乎只作为专门的用户界面,不承担任何处理任务――是一个最理想的jsp方案。另外,请注意另一个jsp页cart.jsp(见代码清单2)被eshop.jsp通过指令<jsp:include page="cart.jsp" flush="true" />包含于其中。
代码清单 1:eshop.jsp
<%@ page session="true" %>
<html>
<head>
<title>music without borders</title>
</head>
<body bgcolor="#33ccff">
<font face="times new roman,times" size="+3">
music without borders
</font>
<hr><p>
<center>
<form name="shoppingform"
action="/examples/servlet/shoppingservlet"
method="post">
<b>cd:</b>
<select name=cd>
<option>yuan | the guo brothers | china | $14.95</option>
<option>drums of passion | babatunde olatunji | nigeria | $16.95</option>
<option>kaira | tounami diabate| mali | $16.95</option>
<option>the lion is loose | eliades ochoa | cuba | $13.95</option>
<option>dance the devil away | outback | australia | $14.95</option>
<option>record of changes | samulnori | korea | $12.95</option>
<option>djelika | tounami diabate | mali | $14.95</option>
<option>rapture | nusrat fateh ali khan | pakistan | $12.95</option>
<option>cesaria evora | cesaria evora | cape verde | $16.95</option>
<option>ibuki | kodo | japan | $13.95</option>
</select>
<b>quantity: </b><input type="text" name="qty" size="3" value=1>
<input type="hidden" name="action" value="add">
<input type="submit" name="submit" value="add to cart">
</form>
</center>
<p>
<jsp:include page="cart.jsp" flush="true" />
</body>
</html>
代码清单 2:cart.jsp
<%@ page session="true" import="java.util.*, shopping.cd" %>
<%
vector buylist = (vector) session.getvalue("shopping.shoppingcart");
if (buylist != null && (buylist.size() > 0)) {
%>
<center>
<table border="0" cellpadding="0" width="100%" bgcolor="#ffffff">
<tr>
<td><b>album</b></td>
<td><b>artist</b></td>
<td><b>country</b></td>
<td><b>price</b></td>
<td><b>quantity</b></td>
<td></td>
</tr>
<%
for (int index=0; index < buylist.size();index++) {
cd anorder = (cd) buylist.elementat(index);
%>
<tr>
<td><b><%= anorder.getalbum() %></b></td>
<td><b><%= anorder.getartist() %></b></td>
<td><b><%= anorder.getcountry() %></b></td>
<td><b><%= anorder.getprice() %></b></td>
<td><b><%= anorder.getquantity() %></b></td>
<td>
<form name="deleteform"
action="/examples/servlet/shoppingservlet"
method="post">
<input type="submit" value="delete">
<input type="hidden" name= "delindex" value='<%= index %>'>
<input type="hidden" name="action" value="delete">
</form>
</td>
</tr>
<% } %>
</table>
<p>
<form name="checkoutform"
action="/examples/servlet/shoppingservlet"
method="post">
<input type="hidden" name="action" value="checkout">
<input type="submit" name="checkout" value="checkout">
</form>
</center>
<% } %>
这里,cart.jsp操纵着基于会话的购物车的表达,在mvc体系中,购物车就充当model的角色。
观察cart.jsp开头处的脚本片段:
<%
vector buylist = (vector) session.getvalue("shopping.shoppingcart");
if (buylist != null && (buylist.size() > 0)) {
%>
这段脚本主要是从会话中取出购物车。如果购物车是空的或尚未创建,则它什么都不显示;因此,当用户第一次访问这个应用程序时,呈现给他的视图如图3所示:
图3:音乐无国界,主视图
图中按钮文字:放入购物车
如果购物车不为空,则选中的物品被依次从购物车中取出,如下面的脚本片段所示:
<%
for (int index=0; index < buylist.size(); index++) {
cd anorder = (cd) buylist.elementat(index);
%>
描述物品的变量一旦被创建,就会被用jsp表达式直接嵌入静态html模板中去。图4显示了当用户向购物车中放入一些物品后的视图。
图4:音乐无国界,购物车视图
图中文字:music without borders:音乐无国界;quantity:数量;album:唱片;artist:演唱者;country:国家;price:价格;delete:删除;checkout:结帐。
这里需要注意的重要一点是,在eshop.jsp和cart.jsp中实现的对所有动作的处理都由一个servlet――shoppingservlet.java控制,如代码清单3所示:
代码清单3:shoppingservlet.java
import java.util.*;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import shopping.cd;
public class shoppingservlet extends httpservlet {
public void init(servletconfig conf) throws servletexception {
super.init(conf);
}
public void dopost (httpservletrequest req, httpservletresponse res)
throws servletexception, ioexception {
httpsession session = req.getsession(false);
if (session == null) {
res.sendredirect("http://localhost:8080/error.html");
}
vector buylist=
(vector)session.getvalue("shopping.shoppingcart");
string action = req.getparameter("action");
if (!action.equals("checkout")) {
if (action.equals("delete")) {
string del = req.getparameter("delindex");
int d = (new integer(del)).intvalue();
buylist.removeelementat(d);
} else if (action.equals("add")) {
//以前是否购买了同样的cd?
boolean match=false;
cd acd = getcd(req);
if (buylist==null) {
//将第一张cd放入购物车
buylist = new vector(); //第一份定单
buylist.addelement(acd);
} else { // 不是第一次购买
for (int i=0; i< buylist.size(); i++) {
cd cd = (cd) buylist.elementat(i);
if (cd.getalbum().equals(acd.getalbum())) {
cd.setquantity(cd.getquantity()+acd.getquantity());
buylist.setelementat(cd,i);
match = true;
} //if name matches结束
} // for循环结束
if (!match)
buylist.addelement(acd);
}
}
session.putvalue("shopping.shoppingcart", buylist);
string url="/jsp/shopping/eshop.jsp";
servletcontext sc = getservletcontext();
requestdispatcher rd = sc.getrequestdispatcher(url);
rd.forward(req, res);
} else if (action.equals("checkout")) {
float total =0;
for (int i=0; i< buylist.size();i++) {
cd anorder = (cd) buylist.elementat(i);
float price= anorder.getprice();
int qty = anorder.getquantity();
total += (price * qty);
}
total += 0.005;
string amount = new float(total).tostring();
int n = amount.indexof('.');
amount = amount.substring(0,n+3);
req.setattribute("amount",amount);
string url="/jsp/shopping/checkout.jsp";
servletcontext sc = getservletcontext();
requestdispatcher rd = sc.getrequestdispatcher(url);
rd.forward(req,res);
}
}
private cd getcd(httpservletrequest req) {
//想象一下如果这些都在一个脚本片段中会有多么难看
string mycd = req.getparameter("cd");
string qty = req.getparameter("qty");
stringtokenizer t = new stringtokenizer(mycd,"|");
string album= t.nexttoken();
string artist = t.nexttoken();
string country = t.nexttoken();
string price = t.nexttoken();
price = price.replace('$',' ').trim();
cd cd = new cd();
cd.setalbum(album);
cd.setartist(artist);
cd.setcountry(country);
cd.setprice((new float(price)).floatvalue());
cd.setquantity((new integer(qty)).intvalue());
return cd;
}
}
“音乐无国界”的主界面是jsp页 eshop.jsp(见代码清单1)。你会注意到,这个页面几乎只作为专门的用户界面,不承担任何处理任务――是一个最理想的jsp方案。另外,请注意另一个jsp页cart.jsp(见代码清单2)被eshop.jsp通过指令<jsp:include page="cart.jsp" flush="true" />包含于其中。
代码清单 1:eshop.jsp
<%@ page session="true" %>
<html>
<head>
<title>music without borders</title>
</head>
<body bgcolor="#33ccff">
<font face="times new roman,times" size="+3">
music without borders
</font>
<hr><p>
<center>
<form name="shoppingform"
action="/examples/servlet/shoppingservlet"
method="post">
<b>cd:</b>
<select name=cd>
<option>yuan | the guo brothers | china | $14.95</option>
<option>drums of passion | babatunde olatunji | nigeria | $16.95</option>
<option>kaira | tounami diabate| mali | $16.95</option>
<option>the lion is loose | eliades ochoa | cuba | $13.95</option>
<option>dance the devil away | outback | australia | $14.95</option>
<option>record of changes | samulnori | korea | $12.95</option>
<option>djelika | tounami diabate | mali | $14.95</option>
<option>rapture | nusrat fateh ali khan | pakistan | $12.95</option>
<option>cesaria evora | cesaria evora | cape verde | $16.95</option>
<option>ibuki | kodo | japan | $13.95</option>
</select>
<b>quantity: </b><input type="text" name="qty" size="3" value=1>
<input type="hidden" name="action" value="add">
<input type="submit" name="submit" value="add to cart">
</form>
</center>
<p>
<jsp:include page="cart.jsp" flush="true" />
</body>
</html>
代码清单 2:cart.jsp
<%@ page session="true" import="java.util.*, shopping.cd" %>
<%
vector buylist = (vector) session.getvalue("shopping.shoppingcart");
if (buylist != null && (buylist.size() > 0)) {
%>
<center>
<table border="0" cellpadding="0" width="100%" bgcolor="#ffffff">
<tr>
<td><b>album</b></td>
<td><b>artist</b></td>
<td><b>country</b></td>
<td><b>price</b></td>
<td><b>quantity</b></td>
<td></td>
</tr>
<%
for (int index=0; index < buylist.size();index++) {
cd anorder = (cd) buylist.elementat(index);
%>
<tr>
<td><b><%= anorder.getalbum() %></b></td>
<td><b><%= anorder.getartist() %></b></td>
<td><b><%= anorder.getcountry() %></b></td>
<td><b><%= anorder.getprice() %></b></td>
<td><b><%= anorder.getquantity() %></b></td>
<td>
<form name="deleteform"
action="/examples/servlet/shoppingservlet"
method="post">
<input type="submit" value="delete">
<input type="hidden" name= "delindex" value='<%= index %>'>
<input type="hidden" name="action" value="delete">
</form>
</td>
</tr>
<% } %>
</table>
<p>
<form name="checkoutform"
action="/examples/servlet/shoppingservlet"
method="post">
<input type="hidden" name="action" value="checkout">
<input type="submit" name="checkout" value="checkout">
</form>
</center>
<% } %>
这里,cart.jsp操纵着基于会话的购物车的表达,在mvc体系中,购物车就充当model的角色。
观察cart.jsp开头处的脚本片段:
<%
vector buylist = (vector) session.getvalue("shopping.shoppingcart");
if (buylist != null && (buylist.size() > 0)) {
%>
这段脚本主要是从会话中取出购物车。如果购物车是空的或尚未创建,则它什么都不显示;因此,当用户第一次访问这个应用程序时,呈现给他的视图如图3所示:
图3:音乐无国界,主视图
图中按钮文字:放入购物车
如果购物车不为空,则选中的物品被依次从购物车中取出,如下面的脚本片段所示:
<%
for (int index=0; index < buylist.size(); index++) {
cd anorder = (cd) buylist.elementat(index);
%>
描述物品的变量一旦被创建,就会被用jsp表达式直接嵌入静态html模板中去。图4显示了当用户向购物车中放入一些物品后的视图。
图4:音乐无国界,购物车视图
图中文字:music without borders:音乐无国界;quantity:数量;album:唱片;artist:演唱者;country:国家;price:价格;delete:删除;checkout:结帐。
这里需要注意的重要一点是,在eshop.jsp和cart.jsp中实现的对所有动作的处理都由一个servlet――shoppingservlet.java控制,如代码清单3所示:
代码清单3:shoppingservlet.java
import java.util.*;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import shopping.cd;
public class shoppingservlet extends httpservlet {
public void init(servletconfig conf) throws servletexception {
super.init(conf);
}
public void dopost (httpservletrequest req, httpservletresponse res)
throws servletexception, ioexception {
httpsession session = req.getsession(false);
if (session == null) {
res.sendredirect("http://localhost:8080/error.html");
}
vector buylist=
(vector)session.getvalue("shopping.shoppingcart");
string action = req.getparameter("action");
if (!action.equals("checkout")) {
if (action.equals("delete")) {
string del = req.getparameter("delindex");
int d = (new integer(del)).intvalue();
buylist.removeelementat(d);
} else if (action.equals("add")) {
//以前是否购买了同样的cd?
boolean match=false;
cd acd = getcd(req);
if (buylist==null) {
//将第一张cd放入购物车
buylist = new vector(); //第一份定单
buylist.addelement(acd);
} else { // 不是第一次购买
for (int i=0; i< buylist.size(); i++) {
cd cd = (cd) buylist.elementat(i);
if (cd.getalbum().equals(acd.getalbum())) {
cd.setquantity(cd.getquantity()+acd.getquantity());
buylist.setelementat(cd,i);
match = true;
} //if name matches结束
} // for循环结束
if (!match)
buylist.addelement(acd);
}
}
session.putvalue("shopping.shoppingcart", buylist);
string url="/jsp/shopping/eshop.jsp";
servletcontext sc = getservletcontext();
requestdispatcher rd = sc.getrequestdispatcher(url);
rd.forward(req, res);
} else if (action.equals("checkout")) {
float total =0;
for (int i=0; i< buylist.size();i++) {
cd anorder = (cd) buylist.elementat(i);
float price= anorder.getprice();
int qty = anorder.getquantity();
total += (price * qty);
}
total += 0.005;
string amount = new float(total).tostring();
int n = amount.indexof('.');
amount = amount.substring(0,n+3);
req.setattribute("amount",amount);
string url="/jsp/shopping/checkout.jsp";
servletcontext sc = getservletcontext();
requestdispatcher rd = sc.getrequestdispatcher(url);
rd.forward(req,res);
}
}
private cd getcd(httpservletrequest req) {
//想象一下如果这些都在一个脚本片段中会有多么难看
string mycd = req.getparameter("cd");
string qty = req.getparameter("qty");
stringtokenizer t = new stringtokenizer(mycd,"|");
string album= t.nexttoken();
string artist = t.nexttoken();
string country = t.nexttoken();
string price = t.nexttoken();
price = price.replace('$',' ').trim();
cd cd = new cd();
cd.setalbum(album);
cd.setartist(artist);
cd.setcountry(country);
cd.setprice((new float(price)).floatvalue());
cd.setquantity((new integer(qty)).intvalue());
return cd;
}
}