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();
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
}
servlet 会话管理的更多相关文章
- Servlet会话管理三(HttpSession)
Session是服务器端技术,服务器在运行时可以为每一个用户的浏览器创建一个其独享的HttpSession对象.由于Session为浏览器用户所独享,所以用户在访问服务器的web资源时,可以把各自的数 ...
- Servlet会话管理一(URL重写和表单隐藏域)
会话可以简单的理解为客户端用户打开一个浏览器,点击多个超链接,访问服务器多个web资源,然后关闭浏览器的整个过程称为一个会话.即一个客户端用户和服务器端进行通讯的过程,也是客户端和服务器端之间的数据传 ...
- Java Web(三) Servlet会话管理
会话跟踪 什么是会话? 可简单理解为,用户打开一个浏览器,点击多个超链接,访问服务器多个web资源,然后关闭服务器,整个过程称为一个会话.从特定客户端到服务器的一系列请求称为会话.记录会话信息的技术称 ...
- Servlet会话管理二(Cookie)
Cookie是在HTTP协议下,将服务器传递给浏览器的的少量信息保存到浏览器客户端的一种技术,通过这种技术,即使在浏览器被关闭或链接中断的情况下,用户仍可以维护Cookie中的数据. Cookie是经 ...
- Java EE.Servlet.会话管理
一次会话是从客户打开浏览器开始到关闭浏览器结束.记录会话信息的技术称为会话跟踪.常见的会话跟踪技术有Cookie.URL重写和隐藏表单域. 1.Cookie Cookie是一小块可以嵌入到HTTP请求 ...
- java web Servlet 学习笔记 -3 会话管理技术
Cookie和HttpSession 什么是会话: 用户开一个浏览器,点击多个超链接,访问服务器多个web资源,然后关闭浏览器,整个过程称之为一个会话. 每个用户在使用浏览器与服务器进行会话的过 ...
- jsp/servlet学习三之会话管理初解
由于http的无状态性,使得会话管理或会话跟踪成为web应用开发一个无可避免的主题.默认下,一个web服务器无法区分一个http请求是否为第一次访问.例如,一个web邮件应用要求用户登陆后才能查看邮件 ...
- [Servlet&JSP] HttpSession会话管理
我们能够将会话期间必须共享的资料保存在HttpSession中,使之成为属性.假设用户关掉浏览器接受Cookie的功能.HttpSession也能够改用URL重写的方式继续其会话管理功能. HttpS ...
- 【JSP&Servlet学习笔记】4.会话管理
Http本身是无状态通信协议,要进行会话管理的基本原理,就是将需要维护的状态回应给浏览器,由浏览器在下次请求时主动发送状态信息,让Web应用程序“得知”请求之间的关联. 隐藏字段是将状态信息以窗体中看 ...
随机推荐
- java 弹出选择目录框(选择文件夹),获取选择的文件夹路径
java 弹出选择目录框(选择文件夹),获取选择的文件夹路径 java 弹出选择目录框(选择文件夹),获取选择的文件夹路径:int result = 0;File file = null;String ...
- 剑指Offer-把数组排成最小的数
题目描述 输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个.例如输入数组{3,32,321},则打印出这三个数字能排成的最小数字为321323. 思路 可以看 ...
- Fragment回退栈&commit()和commitAllowingStateLoss()
Activity切换时是通过栈的形式,不断压栈出栈,在Fragment的时候,如果你不是手动开启回退栈,它是直接销毁再重建,但如果将Fragment任务添加到回退栈,情况就会不一样了,它就有了类似Ac ...
- EasyGui的一个小例子
EasyGui的安装:首先下载easyGui安装包,地址链接:https://pan.baidu.com/s/1D8f_eXWn7l8xhcTuEsqZmA 密码:e5z5 安装步骤: 1.进入eas ...
- oracle启用异步IO(db file async I/O submit)
市局双随机awr报告中有大量db file async I/O submit等待事件 参考两篇文章: [案例]Oracle等待事件db file async I/O submit产生原因和解决办法 d ...
- 题解-bzoj4061 CERC-2012Farm and Factory
Problem Please contact lydsy2012@163.com! 题意概要:给定\(n\)点\(m\)边无向图,设定两个起点为\(1,2\),现要求在图中增加一个点,并将这个点与其他 ...
- JS中的!=、== 、!==、===的用法和区别
var num = 1; var str = '1'; var test = 1; test == num //true 相同类型 相同值 test === num //true 相同类型 相同值 t ...
- strstr()函数的使用
strstr(str1,str2) 函数用于判断字符串str2是否是str1的子串.如果是,则该函数返回str2在str1中首次出现的地址:否则,返回NULL. 实例: /** *Descriptio ...
- java 解压缩 中文名称问题
public List<String> unZip(String pathString, String zipPathString) { long startTime = System.c ...
- ThreadLocal与Synchronized区别
ThreadLocal和Synchonized都用于解决多线程并发访问他们两者的区别:synchronized是利用锁的机制,使变量或代码块在某一时该只能被一个线程访问,而ThreadLocal为每一 ...