servlet 会话管理
一.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(0); 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(0); response.addCookie(cookie); cookie = new Cookie("titleFontStyle",""); cookie.setMaxAge(0); 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 = 5; 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 =0; 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(1, "Bravo 32' HDTV", "Low-cost HDTV from renowned TV manufacturer", 159.95F)); products.add(new Product(2, "Bravo BluRay Player", "High quality stylish BluRay player", 99.95F)); products.add(new Product(3, "Bravo Stereo System", "5 speaker hifi system with iPod player", 129.95F)); products.add(new Product(4, "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 = 0; int quantity = 0; try { productId = Integer.parseInt( request.getParameter("id")); quantity = Integer.parseInt(request .getParameter("quantity")); } catch (NumberFormatException e) { } Product product = getProduct(productId); if (product != null && quantity >= 0) { 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 = 0; 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 != 0) { 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 }