标签:
Web语言HTTP是无状态的,默认情况下,Web服务器不知道一个HTTP请求是来自初次用户,还是来自之前已经访问过的用户。但正常应用程序需要记住用户身份的,换句说,它必须能够管理用户session。
用于保持状态的常用方法有4种:网址重写、隐藏域、cookie已经HttpSession。
(一)网址重写
网址重写是一种Session追踪技术,需要将一个或多个token作为一个查询字符串添加到一个URL钟。注意URL和token之间要用一个问号(?)隔开,两个token之间则是用一个&符号隔开。
访问http://localhost:8080/test/top10
查看页面源码
<html><head><title>Top 10 Tourist Attractions</title></head><body>Please select a city: </br><a href = ‘?city=london‘>London</a></br><a href = ‘?city=paris‘>Paris</a></body></html>
这里注意London的a标签的href。
插一个概念,任何相对的URL(没有协议部分的URL)都会被当做是相对于当前页面的URL。对于上面的London的链接就是http://localhost:8080/test/top10?city=london
例子:
package test.com.servlet.session.URLrewriting; 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"}) public class Top10Servlet extends HttpServlet{ /** * */ private static final long serialVersionUID = 1L; private List<String> londonAttractions; private List<String> parisAttactions; @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("Natural History Museum"); londonAttractions.add("Canary Wharf"); londonAttractions.add("2012 Olymoic Park"); londonAttractions.add("St Paul‘s Cathedral"); parisAttactions = new ArrayList<String>(); parisAttactions.add("Eiffel Tower"); parisAttactions.add("Notre Dame"); parisAttactions.add("The Louvre"); parisAttactions.add("Champs Elysees"); parisAttactions.add("Arc de Triomphe"); parisAttactions.add("Sainte Chapelle Church"); parisAttactions.add("Les Inva"); parisAttactions.add("Musee d‘Orsay"); parisAttactions.add("Montmarte"); parisAttactions.add("Sacre Couer Basilica"); } @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String city = request.getParameter("city"); if(city != null && ("london".equals(city) || "paris".equals(city))){ showAttractions(request, response, city); }else{ showMainPage(request, response); } } private void showMainPage(HttpServletRequest request,HttpServletResponse response) throws IOException{ response.setContentType("text/html"); PrintWriter writer = response.getWriter(); writer.print("<html><head>"); writer.print("<title>Top 10 Tourist Attractions</title>" + "</head><body>" + "Please select a city: " + "</br><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 IOException{ int page = 1; String pageParameter = request.getParameter("page"); if(pageParameter != null){ page = Integer.parseInt(pageParameter); if(page >2){ page = 1; } } List<String> attractions = null; if("london".equals(city)){ attractions = londonAttractions; }else if("paris".equals(city)){ attractions = parisAttactions; } response.setContentType("text/html"); PrintWriter writer = response.getWriter(); writer.print("<html><head>" + "<title>Top 10 Tourist Attractions</title> "+ "</head><body>"); writer.print("<a href=‘top10‘>Select City</a> "); writer.print("<hr>Page " + page + "</hr>"); int start = page * 5 - 5 ; for(int i = start;i < start +5; i++ ){ writer.println(attractions.get(i) + "</br>"); } writer.println("<hr style=‘color:blue‘/>" + "<a href=‘?city=" + city + "&page=1‘>Page 1</a>"); writer.println(" <a href=‘?city=" + city + "&page=2‘>Page 2</a>"); writer.println("</body></html>"); } }
(二)隐藏域
利用隐藏域来保持状态,与采用网址重写技术类似。但他不是将值添加到URL后面,而是将它们放在HTML表单的隐藏域中。当用户提交表单时,隐藏域中的值也传到服务器。
(三)cookie
网址重写和隐藏域都只适用于保持那些不需要跨越许多页面的信息。cookie能够解决这一问题。
cookie的不足之处在于,用户可以通过修改他的浏览器设置来拒绝接受cookie。
要创建一个cookie,传递一个名称和一个值给Cookie类的构造器:
Cookie cookie = new Cookie(name,value);
为了将一个cookie发送到浏览器,需在HttpServletResponse上调用add方法:
response.addCookie(cookie);
要访问浏览器发出的cookie,可以在HttpServletRequest中使用getCookies方法。该方法返回一个cookie数组,如果请求中没有cookie,将返回null。为了找到某个名称的cookie,需要迭代数组。
Cookie[] cookies = request.getCookies(); Cookie maxRecordsCookie = null; if(cookies != null){ for(Cookie cookie : cookies){ if("maxRecords".equals(cookie.getName())){ maxRecordsCookie = cookie; break; } } }
举个例子
package test.com.servlet.session.cookie; import java.io.IOException; import java.io.PrintWriter; 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; @WebServlet(urlPatterns={"/cookieClass"}) public class CookieClassServlet extends HttpServlet{ private static final long serialVersionUID = 1924196159884108L; private String[] methods = { "clone","getComment","getDomain", "getMaxAge","getName","getPath", "getSecure","getValue","getVersion", "isHttpOnly","setMaxAge","setPath", "setSecure","setValue","setVersion" }; @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { Cookie[] cookies = request.getCookies(); Cookie maxRecordsCookie = null; if(cookies != null){ for(Cookie cookie : cookies){ if("maxRecords".equals(cookie.getName())){ maxRecordsCookie = cookie; break; } } } int maxRecords = 5; if(maxRecordsCookie != null){ try { maxRecords = Integer.parseInt(maxRecordsCookie.getValue()); } catch (Exception e) { } } response.setContentType("text/html"); PrintWriter writer = response.getWriter(); writer.print("<html><head>" + "<title>Cookie Class</title>" +"</head><body>" + PreferenceServlet.MENU + "<div>Here are some of the methods in " + "javax.servlet.http.Cookie" ); writer.print("<ul>"); for(int i = 0;i<maxRecords;i++){ writer.print("<li>" + methods[i] + "</li>"); } writer.print("</ul>"); writer.print("</div></body></html>"); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { } }
package test.com.servlet.session.cookie; import java.io.IOException; import java.io.PrintWriter; 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; @WebServlet(urlPatterns={"/cookieInfo"}) public class CookieInfoServlet extends HttpServlet{ private static final long serialVersionUID = 4238895631504566961L; @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { Cookie[] cookies = request.getCookies(); StringBuilder styles = new StringBuilder(); styles.append(".title {"); 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("font-weight:" + value + ";"); }else if(name.equals("titleFontStyle")){ styles.append("font-style:" + value + ";"); } } } styles.append("}"); response.setContentType("text/html"); PrintWriter writer = response.getWriter(); writer.print("<html><head>" + "<title>Cookie Info</title>" + "<style>" + styles.toString() + "</style>" + "</head><body>" + PreferenceServlet.MENU + "<div class=‘title‘>" + "Session Management with Cookies:</div>"); writer.print("<div>"); // cookies will be null if there‘s no cookie if(cookies == null){ writer.print("No cookies 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.print("</div>"); writer.print("</body></html>"); } }
package test.com.servlet.session.cookie; import java.io.IOException; import java.io.PrintWriter; 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; @WebServlet(urlPatterns={"/preference"}) public class PreferenceServlet extends HttpServlet{ private static final long serialVersionUID = 1929342809231005275L; public static final String MENU = "<div style=‘background:#e8e8e8;" + "padding:15px‘>" + "<a href=‘cookieClass‘>Cookie Class</a> " + "<a href=‘cookieInfo‘>Cookie Info</a> " + "<a href=‘preference‘>Preference</a>" + "</div>"; @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html"); PrintWriter writer = response.getWriter(); writer.print("<html><head>" + "<title>Preference</title>" + "<style>table {" + "font-size:small;" + "background:NavajoWhite }</style>" + "</head><body>" + MENU + "Please select the values below:" + "<form method=‘post‘>" + "<table>" + "<tr><td>Title Font Size: </td>" + "<td><select name=‘titleFontSize‘>" + "<option>large</option>" + "<option>x-large</option>" + "<option>xx-large</option>" + "</select></td>" + "</tr>" + "<tr><td>Title Style & Weight: </td>" + "<td><select name=‘titleStyleAndWeight‘ multiple>" + "<option>italic</option>" + "<option>bold</option>" + "</select></td>" + "</tr>" + "<td>Max. Records in Table: </td>" + "<td><select name=‘maxRecords‘>" + "<option>5</option>" + "<option>10</option>" + "</select></td>" + "</tr>" + "<tr><td rowspan=‘2‘>" + "<input type=‘submit‘ value=‘Set‘/></td>" + "</tr>" + "</table>" + "</form>" + "</body></html>" ); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String maxRecords = request.getParameter("maxRecords"); String[] titleStyleAndWeight = request.getParameterValues("titleStyleAndWeight"); String titleFontSize = request.getParameter("titleFontSize"); response.addCookie(new Cookie("maxRecords", maxRecords)); response.addCookie(new Cookie("titleFontSize", titleFontSize)); Cookie cookie = new Cookie("titleFontWeight", ""); cookie.setMaxAge(1000);//设置cookie的存在时间 response.addCookie(cookie); if(titleStyleAndWeight != null){ for(String style : titleStyleAndWeight){ if(style.equals("bold")){ response.addCookie(new Cookie("titleFontWeight", "bold")); }else if(style.equals("italic")){ response.addCookie(new Cookie("titleFontStyle", "italic")); } } } response.setContentType("text/html"); PrintWriter writer = response.getWriter(); writer.println("<html><head>" + "<title>Preference</title>" + "</head><body>" + MENU + "Your preference has been set." + "<br/><br/>Max. Records in Table: " + maxRecords + "<br/>Title Font Size: " + titleFontSize + "<br/>Title Font Style & Weight:") ; if(titleStyleAndWeight != null){ writer.println("<ul>"); for(String style : titleStyleAndWeight){ writer.print("<li>" + style + "</li>"); } writer.println("</ul>"); } writer.println("</body></html>"); } }
浏览器中解析存储的cookie是这样子的。
(四)HttpSession对象
HttpSession是当一个用户第一次访问某个网站时自动创建的。
HttpSession和上面的几种的最大的区别在于,保存在HttpSession中的值是在内存中的。HttpSession不仅可以存储String的,还可以是任意对象,不对这个对象要实现Serializable接口
HttpSession中保存的值不发送到客户端,而是Servlet容器为他所创建的每一个HttpSession生成一个唯一标识符,并将这个标识符作为一个token发送给浏览器,一般作为一个名为JSESSIONID的cookie,或者作为一个jsessionid参数添加到URL后面。
下面这个图是名为JSESSIONID的cookie
例子:
package test.com.servlet.session.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 id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } public float getPrice() { return price; } public void setPrice(float price) { this.price = price; } }
package test.com.servlet.session.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 = 1L; private static final String CART_ATTRIBUTE = "cart"; private List<Product> products = new ArrayList<Product>(); private NumberFormat currenceFormat = NumberFormat .getCurrencyInstance(Locale.US); @Override public void init() throws ServletException { products.add(new Product(1, "Bravo 32‘ HDTV", "Low-cost HDTV from renowed TV manufacturer", 159.95F)); products.add(new Product(2, "Bravo BluRay Player", "High qunlity 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 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String uri = request.getRequestURI(); if(uri.endsWith("/products")){ sendProductList(response); }else if(uri.endsWith("/viewProductDetails")){ sendProductDetailes(request, response); }else if(uri.endsWith("/viewCart")){ showCart(request, response); } } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { int productId = 0; int quantity = 0; try { productId = Integer.parseInt(request.getParameter("id")); quantity = Integer.parseInt(request.getParameter("quantity")); } catch (Exception e) { } Product product = getProduct(productId); if(product != null && quantity >= 0){ ShoppingItem shoppingItem = new ShoppingItem(product, quantity); HttpSession session = request.getSession(); List<ShoppingItem> cart = (List<ShoppingItem>) session.getAttribute(CART_ATTRIBUTE); if(cart == null){ 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() + "(" + currenceFormat.format(product.getPrice()) + ") (" + "<a href=‘viewProductDetails?id=" + product.getId() + "‘>Detailes</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 sendProductDetailes(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 (Exception e) { } Product product = getProduct(productId); if(product != null){ writer.println("<html><head>" + "<title>Product Details</title></head>" + "<body><h2>Product Detailes</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(); 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>" + currenceFormat.format(price) + "</td>"); double subtotal = price * quantity; writer.println("<td>" + currenceFormat.format(subtotal) + "</td>" ); total += subtotal; writer.println("</tr>"); } } writer.println("<tr><td colspan=‘4‘ " + "style=‘text-align:right‘>" + "Total:" + currenceFormat.format(total) + "</td><tr>" ); writer.println("</table>"); } writer.println("</table></body></html>"); } }
package test.com.servlet.session.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 product; } public void setProduct(Product product) { this.product = product; } public int getQuantity() { return quantity; } public void setQuantity(int quantity) { this.quantity = quantity; } }
标签:
原文地址:http://www.cnblogs.com/vincentren/p/5797667.html