一.URL 重写
URL 重写是一种会话跟踪技术,它将一个或多个token添加到URL的查询字符串中,每个token通常为 key=value形式,如下:
url?key-1=value-1&key-2=value-2 ... &key-n=value-n//url和token间用?号分割,token间用与号(&)
URL重写适合tokens无须在太多的URL间传递的情况;它有如下限制:
1.URL在某些浏览器上的最大传递为2000字符
2.静态页面很难传值
3.一个页面有多个URL,很难处理
4.某些字符,如问号,与和空格等必须用base64编码
5.所有信息都是可见的,某些情况不太合适
实例: 显示最受旅客青睐的10个伦敦和巴黎的景点
package app02a;
/*
* 显示最受旅客青睐的10个伦敦和巴黎的景点
*/
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; @WebServlet(name ="Top10Servlet", urlPatterns= {"/top10","/top"})
public class Top10Servlet extends HttpServlet {
private static final long serialVersionUID = 1L; private List<String> londonAttractions;
private List<String> parisAttractions; @Override
public void init() throws ServletException{
londonAttractions = new ArrayList<String>(10);
londonAttractions.add("Buckingham Palace");
londonAttractions.add("london Eye");
londonAttractions.add("British Museum");
londonAttractions.add("National Gallery");
londonAttractions.add("big ben");
londonAttractions.add("Tower of london");
londonAttractions.add("Canary Wharf");
londonAttractions.add("2012 Olympic Park");
londonAttractions.add("St Paul's CathedRal");
londonAttractions.add("newyork"); parisAttractions = new ArrayList<String>(10);
for(int i = 0; i < 10; i++)
parisAttractions.add("parisAttractions" + (i+1));
}
@Override
public void doGet(HttpServletRequest request,HttpServletResponse response)
throws ServletException,IOException{
String city = request.getParameter("city");
if(city != null && (city.equals("london") || city.equals("paris"))) {
// show attractions
showAttractions(request,response,city);
}else {
//show main page
showMainPage(request,response);
}
} private void showMainPage(HttpServletRequest requset,HttpServletResponse response)
throws ServletException,IOException{
response.setContentType("text/html");
PrintWriter writer = response.getWriter();
writer.print("<!DOCTYPE html>"
+ "<html><head><meta language='en' enconding='utf-8'><title>Top 10 attractions</title></head>"
+ "<body>Please select a city: <br />"
// 此处为相对url, borwer 会在当前url后面加上href的内容 http://localhost:8080/app02a/top10?city=london
+ "<a href='?city=london'>London</a> <br />"
+ "<a href='?city=paris'>Paris</a></body></html>");
}
private void showAttractions(HttpServletRequest request, HttpServletResponse response, String city)
throws ServletException, IOException {
int page = 1;
// 得到page的值
String pageParameter = request.getParameter("page");
if(pageParameter != null) {
try {
page = Integer.parseInt(pageParameter);
}catch(NumberFormatException e) {
//do nothing and retain default value for page
}
if(page > 2) {
page = 1;
}
}
List<String> attractions = null;
if(city.equals("london"))
attractions = londonAttractions;
else if(city.equals("paris"))
attractions = parisAttractions;
response.setContentType("text/html");
PrintWriter writer = response.getWriter();
writer.print("<html><head>"
+ "<title> Top 10 Attractions </title>"
+ "</head><body>");
writer.print("<a href='top10'>Seletct City</a>");
writer.print("<hr/>page " + page + "<hr />");
int start = page*5-5;
for( int i = start; i < start + 5; i++) {
writer.print(attractions.get(i) + "<br />");
}
writer.print("<hr style='color:blue;' />"
+ "<a href='?city="+ city
+ "&page=1'>page 1</a>");
writer.print(" <a href='?city=" + city +
"&page=2'>page 2</a>");
}
}
二.隐藏域
使用隐藏域来保持状态类似于URL重写技术, 但不是将值附加到URL上,而是放到HTML的表单的隐藏域中.当表单提交时,隐藏域的值也它是条件到服务器端,隐藏域技术仅当网页有表单时有效,相对于URL的优势在于,没有字符限制,同时无须额外编码.但是不适合跨越多个页面
例: 通过隐藏域来更新客户信息
package app02a.hiddenfields; import java.io.IOException;
import java.io.PrintWriter;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.Vector;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.sql.*;
//URL分别映射三个URL 前两个会调用doGet, 而 update会调用dopost方法
@WebServlet(name = "CustomerServlet", urlPatterns= {
"/customer", "/editCustomer", "/updateCustomer"
})
public class CustomerServlet extends HttpServlet{
private static final long serialVersionUID = -20L;
//存储customers 数据
private Vector<Customer> customers = new Vector<Customer>();
@Override
public void init() throws ServletException{
Customer customer1 = new Customer();
ResultSet rs = null;
// 读取数据库的customer数据
try (Statement stmt = new Mysql_JDBC().getStatement()){
rs = stmt.executeQuery("SELECT cust_id,cust_name,cust_city FROM mysql_test.customer where cust_id <100 ");
while(rs.next())
{
Customer cust = new Customer();
cust.setId(rs.getInt("cust_id"));
cust.setName(rs.getString("cust_name"));
cust.setCity(rs.getString("cust_city"));
customers.add(cust);
}
}catch(Exception e) {
e.printStackTrace();
}finally{
}
} private void sendCusomer(HttpServletResponse response) throws ServletException, IOException{
response.setContentType("text/html");
response.setCharacterEncoding("utf-8");
PrintWriter writer = response.getWriter();
writer.print("<!DOCTYPE html><html lang='en'><head><meta charset='utf-8' ><title>Customers</title></head>"
+ "<body><h2>Customerss </h2>");
for(Customer customer : customers) {
writer.println("<li>" + customer.getName() +
"(" + customer.getCity() + ") (" +
"<a href='editCustomer?id="+ customer.getId() //当用户点击<a>标签 URL 会调用doGet()
+ " '>edit )</a> </li>");
} writer.println("<ul>");
writer.println("</body></html>");
} private Customer getCustomer(int cust_id) {
for (Customer cust : customers) {
if (cust.getId() == cust_id)
return cust;
}
return null;
} private void sendEditCustomerForm(HttpServletRequest request,HttpServletResponse response)
throws ServletException, IOException{
response.setContentType("text/html");
response.setCharacterEncoding("utf-8");
PrintWriter writer = response.getWriter();
int cust_id = 0;
try {
cust_id = Integer.parseInt(request.getParameter("id"));
}catch(NumberFormatException e) { }
Customer customer = getCustomer(cust_id);
if ( customer != null) {
writer.println("<!DOCTYPE html> <html lang='en' ><head>"
+ "<meta charset='UTF-8' >"
+ "<title>Edit Customer</title></head>"
+ "<body><h2>Edit Customer</h2>"
+ "<form method = 'post' "
+ "action = 'updateCustomer'>");
/* hidden 定义隐藏字段 */
writer.println("<input type='hidden' name='id' value='"
+ cust_id + "' />" );
writer.println("<table>");
writer.println("<tr><td>name: </td><td>"
+ "<input name='name' value= '"
+ customer.getName()
+ "'</td></tr>");
writer.println("<tr><td>city: </td><td>"
+ "<input name='city' value= '"
+ customer.getCity()
+ "'/></td></tr>");
writer.println("<tr>"
+ "<td colspan='2 ' style='text-algin:right'>"
// 当点击提交submit 会将隐藏(hddien) 的键对值发送给doPost
+ "<input type='submit' value='Update' /></td>"
+ "</tr>"); writer.println("<tr>"
+ "<td colspan='2 '>"
+ "<a href='customer'>Customer List</a></td>"
+ "</tr>");
writer.println("</table></form></body></html>");
}else
writer.println("No customer found");
} @Override
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String uri = request.getRequestURI();
if(uri.endsWith("/customer")) {
sendCusomer(response);
}else if (uri.endsWith("/editCustomer"))
sendEditCustomerForm(request,response);
}
@Override
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//update customer
request.setCharacterEncoding("UTF-8");
int cust_id = 0;
try {
cust_id=Integer.parseInt(request.getParameter("id"));
}catch(NumberFormatException e) { }
Customer cust = getCustomer(cust_id);
if (cust != null) {
cust.setName( request.getParameter("name"));
cust.setCity(request.getParameter("city"));
}
sendCusomer(response);
} }
三.Cookies
cookies 是一个很少的信息片段,可以自动的在浏览器和Web服务器间交互,因此cookies可存储在多个页面间传递的信息,Cookies 作为HTTP协议的一部分,其传输协议是有HTTP协议控制.浏览器通常支持每个网站高达20个Cookies
Cookies的问题在于,用户可以通过改变浏览器的设置拒绝接受Cookies
Cookies的构造方法:
javax.servlet.http.Cookie cookie = new javax.servlet.http.Cookie(name, value);//通过给定键值对构造
要将cookie发送到浏览器需要HttpServletResponse的addcookie方法
httpServeltResonse.addCookie(cookie)
浏览器在访问同一Web服务器时,会将之前收到的cookie以便发送
服务器若要提取浏览器提交的cookie,可以通过HttpServletRequest接口的getCookies的方法,该方法返回一个Cookie数组,如果没有Cookie则返回null
如下为查询名为maxRecords的cookie的示例
Cookie[] cookies = request.getCookies();
Cookie maxRecordesCookie = null;
if(cookies != null)
{
for(Cookie cookie : cookies)
{
if(cookie.getName().contentEquals(" maxRecordesCookie"))
{
maxRecordesCookie = cookie;
break;
}
}
}
要删除Cookie 只能创建一个同名的Cookie,并将maxAge属性设置为0,并添加到HttpServletRepsonse 接口中
public void test() {
Cookie cookie = new Cookie("userName","");
cookie.setMaxAge();
response.addCookie(cookie);
}
Servlet Cookie 方法
以下是在 Servlet 中操作 Cookie 时可使用的有用的方法列表。
序号 | 方法 & 描述 |
---|---|
1 |
public void setDomain(String pattern) 该方法设置 cookie 适用的域,例如 runoob.com。 |
2 |
public String getDomain() 该方法获取 cookie 适用的域,例如 runoob.com。 |
3 |
public void setMaxAge(int expiry) 该方法设置 cookie 过期的时间(以秒为单位)。如果不这样设置,cookie 只会在当前 session 会话中持续有效。 |
4 |
public int getMaxAge() 该方法返回 cookie 的最大生存周期(以秒为单位),默认情况下,-1 表示 cookie 将持续下去,直到浏览器关闭。 |
5 |
public String getName() 该方法返回 cookie 的名称。名称在创建后不能改变。 |
6 |
public void setValue(String newValue) 该方法设置与 cookie 关联的值。 |
7 |
public String getValue() 该方法获取与 cookie 关联的值。 |
8 |
public void setPath(String uri) 该方法设置 cookie 适用的路径。如果您不指定路径,与当前页面相同目录下的(包括子目录下的)所有 URL 都会返回 cookie。 |
9 |
public String getPath() 该方法获取 cookie 适用的路径。 |
10 |
public void setSecure(boolean flag) 该方法设置布尔值,表示 cookie 是否应该只在加密的(即 SSL)连接上发送。 |
11 |
public void setComment(String purpose) 设置cookie的注释。该注释在浏览器向用户呈现 cookie 时非常有用。 |
12 |
public String getComment() 获取 cookie 的注释,如果 cookie 没有注释则返回 null。 |
http头信息中包含如下内容
HTTP/1.1 200 OK
Date: Fri, 04 Feb 2000 21:03:38 GMT
Server: Apache/1.3.9 (UNIX) PHP/4.0b3
Set-Cookie: name=xyz; expires=Friday, 04-Feb-07 22:03:38 GMT;
path=/; domain=runoob.com
Connection: close
Content-Type: text/html
例: PreferenceServlet 展示了如何通过cookies来进行会话管理,改Servlet允许用户通过修改四个cookie值设定显示配置
package cookie; import java.io.IOException;
import java.io.PrintWriter;
import java.net.URLDecoder;
import java.net.URLEncoder;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.sql.*; @WebServlet(name ="PreferenceServlet", urlPatterns = {"/preference"})
public class PreferenceServlet extends HttpServlet{
private static final long serialVersionUID = 888L;
public static final String MENU =
"<div style = 'background:#e8e8e8;"
+ "padding:15px'>"
+ "<a href='cookieClss'>Cookie class </a> "
+ "<a href='cookieinfo'>Cookie info </a> "
+ "<a href='preference'>preference</a>" + "</div>";
@Override
public void doGet(HttpServletRequest request,HttpServletResponse response) throws IOException{
response.setContentType("text/html");
response.setCharacterEncoding("UTF-8");
PrintWriter writer = response.getWriter();
writer.print("<html lang='en'>\r\n" +
"<head>\r\n" +
"<meta charset='UTF-8' />\r\n" +
"<title>Preference</title>\r\n" +
"<style>\r\n" +
"table{\r\n" +
"font-size:samll;\r\n" +
"background:WHILE;\r\n" +
"}\r\n" +
"</style>\r\n" +
"</head><body>"
+ MENU
+ "Please select the value below:\r\n" +
"<form method='post' action=\"\">\r\n" +
" <table>\r\n" +
" <tr>\r\n" +
" <td>Title Font Size:</td>\r\n" +
" <td><select name='titleFontSize' >\r\n" +
" <option >large</option>\r\n" +
" <option >x-large</option>\r\n" +
" <option >xx-large</option>\r\n" +
" </select>\r\n" +
" </td>\r\n" +
" </tr>\r\n" +
" <tr>\r\n" +
" <td>Title Style %26 Weight: </td>\r\n" +
" <td><select name='titleStyleAndWeight' multiple>\r\n" +
" <option >italic</option>\r\n" +
" <option >bold</option>\r\n" +
" </select>\r\n" +
" </td>\r\n" +
" </tr>\r\n" +
" <tr>\r\n" +
" <td>Max, Records in Table: </td>\r\n" +
" <td><select name='maxRecords'>\r\n" +
" <option >5</option>\r\n" +
" <option >10</option>\r\n" +
" </select></td>\r\n" +
" </tr>\r\n" +
" <tr>\r\n" +
" <td rowspan=\"2\">\r\n" +
" <input type=\"submit\" value=\"set\" />\r\n" +
" </td>\r\n" +
" </tr>\r\n" +
" </table>\r\n" +
"</form>\r\n" +
"</body>\r\n" +
"</html>");
}
@Override
public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {
request.setCharacterEncoding("UTF-8");
// 得到浏览器发送的值
String maxRecords = request.getParameter("maxRecords");
// 得到多选select的数组值
String[] titleStyleAndWeight = request.getParameterValues("titleStyleAndWeight"); String titleFontSize =
request.getParameter("titleFontSize");
// 创建Cookie 并发送
response.addCookie(new Cookie("maxRecords",maxRecords));
response.addCookie(new Cookie("titleFontSize",titleFontSize));
//delete titleFontWeight and titleFontStyle cookies first
// delete cookie by adding a cookie with the maxAage = 0;
Cookie cookie = new Cookie("titleFontWeight","");
cookie.setMaxAge();
response.addCookie(cookie); cookie = new Cookie("titleFontStyle","");
cookie.setMaxAge();
response.addCookie(cookie); if(titleStyleAndWeight != null) {
for( String style : titleStyleAndWeight)
{
if(style.contentEquals("bold"))
response.addCookie(new Cookie("TitleFontWeight","bold"));
else if (style.contentEquals("italic"))
{
response.addCookie(new Cookie("titleFontStyle","italic"));
}
}
} response.setContentType("text/html");
response.setCharacterEncoding("UTF-8");
PrintWriter writer = response.getWriter();
writer.println("<html lang='en'>\r\n" +
"<head>\r\n" +
"<meta charset='UTF-8' />\r\n" +
"<title>Preference</title>\r\n" +
"</head><body>"
+ MENU
+ "Please select the value below:\r\n" +
"<br/><br/> Max. Records in Table: " + maxRecords
+ "<br/>Title Font Size: " + titleFontSize
+ "<br/>TitleFOnt Style & Weight: "
);
//titleStyleAnd Weight will be null if none of the options
//was selected
if(titleStyleAndWeight != null) {
writer.println("<ul>");
for (String style : titleStyleAndWeight)
writer.print("<li>" + style + "</li>");
writer.println("</ul>");
}
writer.println("</body></html>");
} }
package cookie;
/*
*
*/
import java.io.IOException;
import java.io.PrintWriter;
import java.net.URLDecoder;
import java.net.URLEncoder;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.sql.*; @WebServlet(name = "CookieClassServlet", urlPatterns = { "/cookieClass" })
public class CookieClassServlet extends HttpServlet{
private static final long serialVersionUID = 837369L; private String[] methods = {
"cone1","cone2","cone3","cone4","cone5","cone6","cone7","cone8","cone9",
"cone10","cone11","cone12","cone13","cone14","cone15","cone16","cone17","cone18",
}; @Override
public void doGet(HttpServletRequest request,HttpServletResponse response) throws IOException{
Cookie[] cookies = request.getCookies();
Cookie maxRecordsCookie = null;
if(cookies != null)
{
for(Cookie cookie: cookies)
{
if(cookie.getName().contentEquals("maxRecords")) {
maxRecordsCookie = cookie;
break;
}
}
} int maxRecords = ;
if (maxRecordsCookie !=null)
{
try {
// 得到cookie的值
maxRecords = Integer.parseInt(maxRecordsCookie.getValue());
}catch(NumberFormatException e) { }
} response.setContentType("text/html");
response.setCharacterEncoding("UTF-8");
PrintWriter writer = response.getWriter();
writer.print("<!DOCTYPE html>\r\n" +
"<html lang=\"en\">\r\n" +
"<head>\r\n" +
" <meta charset=\"UTF-8\">\r\n" +
" <title>Cookie class</title>\r\n" +
"</head>\r\n" +
"<body>"
+ PreferenceServlet.MENU +
"<div>Here are some of the methods in javax.servlet.http.Cookie\r\n" +
" <ul>");
for( int i =; i<maxRecords; i++)
writer.print("<li>" + methods[i] + "</li>"); writer.print("</ul>\r\n" +
" </div>\r\n" +
"</body>\r\n" +
"</html>"); } }
package cookie; import java.io.IOException;
import java.io.PrintWriter;
import java.net.URLDecoder;
import java.net.URLEncoder;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.sql.*; @WebServlet(name = "CookieInfoServlet", urlPatterns = { "/cookieinfo" })
public class CookieInfoServlet extends HttpServlet{ private static final long serialVersionUID = 3829L; public void doGet(HttpServletRequest request,HttpServletResponse response) throws IOException{
// 得到cookies的数组
Cookie[] cookies = request.getCookies();
StringBuilder styles = new StringBuilder();
if( cookies != null) {
for(Cookie cookie : cookies)
{
String name = cookie.getName();
String value =cookie.getValue();
if ( name.equals("titleFontSize"))
styles.append("font-size: " + value + ":");
else if ( name.equals("titleFontWeight"))
styles.append("titleFontWeight: " + value + ":");
else if ( name.equals("font-weight"))
styles.append("font-weight: " + value + ":");
}
}
styles.append("}");
response.setContentType("text/html");
response.setCharacterEncoding("UTF-8");
PrintWriter writer = response.getWriter();
writer.print("<!DOCTYPE html>\r\n" +
"<html lang=\"en\">\r\n" +
"<head>\r\n" +
" <meta charset=\"UTF-8\">\r\n" +
" <title>Styles.toString()</title>\r\n" +
"</head>\r\n" +
"<body>" + PreferenceServlet.MENU +
"<div class=\"title\">Session management with cookies:\r\n" +
" </div>"); //cookies will be null if there's no cookie
if ( cookies ==null) {
writer.print("NO cookie in this http response" );
}
else {
writer.println("<br/> Cookies in this http response: ");
for(Cookie cookie : cookies) {
writer.println("<br /> " + cookie.getName() + ": "
+ cookie.getValue());
}
}
writer.println("</body>\r\n" +
"</html>");
} }
4. HttpSession 对象
所有会话跟踪技术中HttpSession 最强大, 一个用户有且只能由一个HttpSession对象,并且不会被用户访问到
HttpSession对象在用户第一次访问网站时自动创建,你可以通过调用HttpServletRequest的getSession()获取该对象,getSession() 有两个重载方法
HttpSession getSession()/// 返回当前的HttpSession,若没有则创建HttpSession
HttpSession getSession(Boolean create)// 返回当前的HttpSession,create值false时若没有则返回null,create值true时若没有则创建HttpSession,
可以通过HttpSession的setAttribute方法将值放入HttpSession
void setAttribute(java.lang.String name, java.lang.Object value)
放入HttpSession的值时存储在内存中的,因此不要放入太多对象
通过调用HttpSession的getAttribute方法可以取回之前放入的对象
java.lang.Object getAttribute(java.lang.String name)
HttpSession 还有一个非常有用的方法,会返回一个Enumeration对象来迭代访问保存在HttpSession中的值
java.util.Enumeration<java.lang.String> getAttributeName();
HttpSession 会生成唯一标识,并将该标识发送给浏览器,在后续的请求中浏览器会将标识提交给服务器
可以用HttpSession 的geId方法获取该标识
java.lang.String getId()
HttpSession的ivalidate()方法会强制会话过期,并清空保存的对象,
void getMaxInactiveInterval( ) //查看会话多久会过期,单位为秒
void setMaxInactiveInterval( int seconds) //设置其超时时间,若为0 则永不过期
例: ShoppingCartServet 为一个小的有4个商品的在线商城,用户可以将商品添加到购物车中,并可以查看购物车内容,Produc类定义了4个属性(id,name,description 和price),Shopping 有两个属性 即 quantity 和Product
package app02a.httpSession;
import java.io.IOException;
import java.io.PrintWriter;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
@WebServlet(name = "ShoppingCartServlet", urlPatterns = {
"/products", "/viewProductDetails",
"/addToCart", "/viewCart" })
public class ShoppingCartServlet extends HttpServlet {
private static final long serialVersionUID = -20L;
private static final String CART_ATTRIBUTE = "cart";
private List<Product> products = new ArrayList<Product>();
private NumberFormat currencyFormat = NumberFormat
.getCurrencyInstance(Locale.US);
@Override
public void init() throws ServletException {
products.add(new Product(, "Bravo 32' HDTV",
"Low-cost HDTV from renowned TV manufacturer",
159.95F));
products.add(new Product(, "Bravo BluRay Player",
"High quality stylish BluRay player", 99.95F));
products.add(new Product(, "Bravo Stereo System",
"5 speaker hifi system with iPod player",
129.95F));
products.add(new Product(, "Bravo iPod player",
"An iPod plug-in that can play multiple formats",
39.95F));
}
@Override
public void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException,
IOException {
String uri = request.getRequestURI();
if (uri.endsWith("/products")) {
sendProductList(response);
} else if (uri.endsWith("/viewProductDetails")) {
sendProductDetails(request, response);
} else if (uri.endsWith("viewCart")) {
showCart(request, response);
}
}
@Override
public void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException,
IOException {
// add to cart
int productId = ;
int quantity = ;
try {
productId = Integer.parseInt(
request.getParameter("id"));
quantity = Integer.parseInt(request
.getParameter("quantity"));
} catch (NumberFormatException e) {
}
Product product = getProduct(productId);
if (product != null && quantity >= ) {
ShoppingItem shoppingItem = new ShoppingItem(product,
quantity);
// 得到当前浏览器的HttpSession对象
HttpSession session = request.getSession();
@SuppressWarnings("unchecked")
List<ShoppingItem> cart = (List<ShoppingItem>) session
.getAttribute(CART_ATTRIBUTE);
if (cart == null) {
//如果当前的HttpSession里没有cart 则添加cart
cart = new ArrayList<ShoppingItem>();
session.setAttribute(CART_ATTRIBUTE, cart);
}
cart.add(shoppingItem);
}
sendProductList(response);
}
private void sendProductList(HttpServletResponse response)
throws IOException {
response.setContentType("text/html");
PrintWriter writer = response.getWriter();
writer.println("<html><head><title>Products</title>" +
"</head><body><h2>Products</h2>");
writer.println("<ul>");
for (Product product : products) {writer.println("<li>" + product.getName() + "("+ currencyFormat.format(product.getPrice())
+ ") (" + "<a href='viewProductDetails?id="+ product.getId() + "'>Details</a>)");
}
writer.println("</ul>");
writer.println("<a href='viewCart'>View Cart</a>");
writer.println("</body></html>");
}
private Product getProduct(int productId) {
for (Product product : products) {
if (product.getId() == productId) {
return product;
}
}
return null;
}
private void sendProductDetails(HttpServletRequest request,
HttpServletResponse response) throws IOException {
response.setContentType("text/html");
PrintWriter writer = response.getWriter();
int productId = ;
try {
productId = Integer.parseInt(
request.getParameter("id"));
} catch (NumberFormatException e) {
}
Product product = getProduct(productId);
if (product != null) {
writer.println("<html><head>"
+ "<title>Product Details</title></head>"
+ "<body><h2>Product Details</h2>"
+ "<form method='post' action='addToCart'>"
);
writer.println("<input type='hidden' name='id' "
+ "value='" + productId + "'/>");
writer.println("<table>");
writer.println("<tr><td>Name:</td><td>"
+ product.getName() + "</td></tr>");
writer.println("<tr><td>Description:</td><td>"
+ product.getDescription() + "</td></tr>");
writer.println("<tr>" + "<tr>"
+ "<td><input name='quantity'/></td>"
+ "<td><input type='submit' value='Buy'/>"
+ "</td>"
+ "</tr>");
writer.println("<tr><td colspan='2'>"
+ "<a href='products'>Product List</a>"
+ "</td></tr>");
writer.println("</table>");
writer.println("</form></body>");
} else {
writer.println("No product found");
}
}
private void showCart(HttpServletRequest request,
HttpServletResponse response) throws IOException {
response.setContentType("text/html");
PrintWriter writer = response.getWriter();
writer.println("<html><head><title>Shopping Cart</title>"
+ "</head>");
writer.println("<body><a href='products'>" +
"Product List</a>");
HttpSession session = request.getSession();
@SuppressWarnings("unchecked")
List<ShoppingItem> cart = (List<ShoppingItem>) session
.getAttribute(CART_ATTRIBUTE);
if (cart != null) {
writer.println("<table>");
writer.println("<tr><td style='width:150px'>Quantity"
+ "</td>"
+ "<td style='width:150px'>Product</td>"
+ "<td style='width:150px'>Price</td>"
+ "<td>Amount</td></tr>");
double total = 0.0;
for (ShoppingItem shoppingItem : cart) {
Product product = shoppingItem.getProduct();
int quantity = shoppingItem.getQuantity();
if (quantity != ) {
float price = product.getPrice();
writer.println("<tr>");
writer.println("<td>" + quantity + "</td>")
;
writer.println("<td>" + product.getName()
+ "</td>");
writer.println("<td>"
+ currencyFormat.format(price)
+ "</td>");
double subtotal = price * quantity;
writer.println("<td>"
+ currencyFormat.format(subtotal)
+ "</td>");
total += subtotal;
writer.println("</tr>");
}
}
writer.println("<tr><td colspan='4' "
+ "style='text-align:right'>"
+ "Total:"
+ currencyFormat.format(total)
+ "</td></tr>");
writer.println("</table>");
}
writer.println("</table></body></html>");
}
}
package app02a.httpSession; public class Product {
private int id;
private String name;
private String description;
private float price;
public Product(int id, String name, String description, float price) {
this.id = id;
this.name = name;
this.description = description;
this.price = price;
}
public int getId() {
return this.id;
}
public String getName() {
return this.name;
}
public String getDescription() {
return this.description;
} public float getPrice() {
return this.price;
}
// get and set methods not shown to save space
}
package app02a.httpSession; public class ShoppingItem {
private Product product;
private int quantity;
public ShoppingItem(Product product, int quantity) {
this.product = product;
this.quantity = quantity;
} public Product getProduct() {
return this.product;
}
public int getQuantity() {
return this.quantity;
}
// get and set methods not shown to save space
}