session_jsp应用原理

Session应用:

            禁用Cookie后Session共享数据问题:

                      解决方案:URL重写
                           String url = response. encodeRedirectURL(java.lang.String url)
                           response. sendRedirect(url)
                           用于对sendRedirect方法后的url地址进行重写。
                          String url = response.encodeURL(url);
                          pw.write("<a href='"+url+"'>继续购物</a>");
                          用于对表单action和超链接的url地址进行重写

           防止表单重复提交:

                 可以在表单提交时候通过设置一个id,在一个servlet中把它存在session中,然后提交的时候在url后面携带一个id参数,在

           处理的另一个servlet中取出session中保存的id,判断两个id是否相同,如果相同就把session中的id删除,这样处理的时候,在

           提交后后的第二个servlet中刷新的话,session中的id值已经不存在,这时候就提交失败。看下面例子:

        

第一个servlet:

/**
 *  用Servlet动态产生表单,且客户端与服务端都有token值
 */
public class Demo01A extends HttpServlet {
	public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
		//获取随机值
		String token = WebUtil.getToken();
		//将随机值绑定到HttpSession域对象中
		request.getSession().setAttribute("TOKEN",token);
		//以下代码是向浏览器输出一个表单
		response.setContentType("text/html;charset=UTF-8");
		PrintWriter pw = response.getWriter();
		pw.write("<form action='"+request.getContextPath()+"/Demo01B' method='POST'>");
			//将随机值绑定在表单隐藏域中
			pw.write("<input type='hidden' name='token' value='"+token+"'/>");
			pw.write("姓名:<input type='text' name='username'/><br/>");
			pw.write("密码:<input type='password' name='password'/><br/>");
			pw.write("<input type='submit' value='提交'/>");
		pw.write("</form>");
	}
}

/**
 * 工具类
 */
class WebUtil{
	private WebUtil(){}
	public static String getToken(){
		//用UUID对象产生唯一的字符串随机值
		return UUID.randomUUID().toString();
	}
}
第二个servlet:

/**
 * 比较客户端和服务端的token值是否相同,相同表示提交成功并删除服务器token值,否则表单重复提交 
 */
public class Demo01B extends HttpServlet {
	public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
		response.setContentType("text/html;charset=UTF-8");
		//获取客户端提交的token值
		String tokenClient = request.getParameter("token");
		//获取服务端的token值
		String tokenServer = (String) request.getSession().getAttribute("TOKEN");
		//如果客户端和服务端的token值都存在且相同的话
		if(tokenClient!=null && tokenServer!=null && tokenClient.equals(tokenServer)){
			//继续再获取姓名和密码
			//提交成功
			response.getWriter().write("<font style='color:green;font-size:111px'>表单提交成功</font>");
			//删除服务端的token值
			request.getSession().removeAttribute("TOKEN");
		}else{
			//表单重复提交
			response.getWriter().write("<font style='color:red;font-size:111px'>表单重复提交</font>");
		}
	}
}

JSP入门

            JSP(Java Server Page)
            是原SUN公司开发的一款动态web技术之一

JSP产生的背景?

          用Servlet来输出表单比较烦麻,难以后期维护,这时就需要一个新的技术来替代Servlet产生表单等UI功能,且又是一种动态

    web技术,于是原SUN制定的JSP规则,用于替代Servlet输出UI等相关功能
    注意:JSP替代Servlet,JSP和Servlet属于JavaEE规则之一

      JSP = HTML(表面) + Servlet(本质)

JSP运行原理

          tomcat/work目录是为jsp定制的,在jsp首次访问时,work目录下会有jsp翻译过来的servlet源码和servlet字节码,从这一点

    讲,jsp本质上就是servlet,只是表现形式不一样

          jsp翻译成servlet后,依然有与servlet相类似的方法,例如:_jspInit(),_jspService(),_jspDestory()每次访问jsp都执行

    _jspService()方法,访问几次,就执行几次。

        public void _jspService(HttpServletRequest request, HttpServletResponse response)

                   throws java.io.IOException, ServletException {

Web服务器是如何调用并执行一个jsp页面的?

          

Jsp页面中的html排版标签是如何被发送到客户端的?

        通过JspWriter.write()方法输出到客户端的

Jsp页面中的java代码服务器是如何执行的?

          通过JspWriter.print()方法输出到客户端的

Web服务器在调用jsp时,会给jsp提供一些什么java对象?

           当jsp翻译成servlet源码时,Web服务器会向_jspService()方法传入若干对象给jsp使用,那么这些对象不需要程序员创建,直

     接用即可,我们叫其内置对象或隐式对象,JSP难点在于,它所对应的Servlet源码中的对象,可以在JSP页面直接使用,

     这一点容易让初学者头痛

MVC模式

          M:普通的Java类,完成业务的业务逻辑,例如:获取用户姓名
          V:视图,用JSP技术完成,从域对象中获取数据,并显示在浏览器中
          C:控制,用于接收客户端请求,调用业务模型,如果有结果的话,将其绑定到域对象中,转发或重定向于视图进行显示
          MVC不限于JavaWeb,其它Web都适用。
           MVC也能适用于非Web

JSP基础语法

         1_模版元素,即就是可以在JSP中书写HTML,CSS,JS
         2_脚本表达式,即向浏览器输出变量或表达式的值,不能用分号结束,例如:<%= str %>
         3_脚本片段,可以书写多行java代码,以分号结束,例如:<%int x = 10;%>
         4_JSP声明,如果是变量的话,会翻译成Servlet的实例变量如果是方法的话,会翻译成Servlet的成员方法
         5_JSP注释,<%----%>是JSP专用的,JSP引擎在翻译成Servlet时,不会将其 翻译到源码中;但如果你用<!---->的话,会被

          翻译到Servlet对应的源码中

在Servlet中写多个私有的业务方法

           你可以将多个类似的业务方法,都写在同一个Servlet中,在doPost或doGet中判断,如果是属于find功能,立刻将请求分发到

     处理find功能的业务方法中去这样一来,Servlet数量减少了,代理维护起方便


下面提供一个用session jsp servlet写出来的购物车系统:


   首先是

package shop.domain;
/**
 * 书本对象类
 * @author Jam
 */
public class Book {
	private Integer id;    //书本id
	private String title; //书本标题
	private String url;//书本图片url
	private Float price; //书本价格
	public Book(Integer id, String title, String url, Float price) {
		this.id = id;
		this.title = title;
		this.url = url;
		this.price = price;
	}
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public String getTitle() {
		return title;
	}
	public void setTitle(String title) {
		this.title = title;
	}
	public String getUrl() {
		return url;
	}
	public void setUrl(String url) {
		this.url = url;
	}
	public Float getPrice() {
		return price;
	}
	public void setPrice(Float price) {
		this.price = price;
	}
	
	
	
}

package shop.domain;

import java.util.ArrayList;
import java.util.List;

/**
 * 购物车类,自带添加,删除商品条目功能 
 * @author Jam
 */

public class ShopCar {
	private List<ShopCarItem> list = new ArrayList<ShopCarItem>();
	private Float totalPrice ;
	public ShopCar() {
	}	
	public List<ShopCarItem> getList() {
		return list;
	}
	public void setList(List<ShopCarItem> list) {
		this.list = list;
	}
	public Float getTotalPirce() {
		Float sum = 0.0f;
		for(ShopCarItem item : list){
			sum += item.getTotalPrice();
		}
		totalPrice = sum;
		return totalPrice;
	}
	public void setTotalPirce(Float totalPirce) {
		this.totalPrice = totalPirce;
	}
	public void addBook(Book b,String count){
		Integer c = Integer.parseInt(count); 
		for(ShopCarItem item : list){
			if(item.getBook().getId() == b.getId()){  //表示购物车已经有该书本,把书本数量+1
				item.setNum(item.getNum()+c);
				return ;
			}
		}
		//如果购物车中没有该书,添加进去
		ShopCarItem item = new ShopCarItem(b.getId(),b,c);
		list.add(item);
	}
	public void clearCar(){
		list.clear();
	}
	/*
	 * 移除一类图书
	 */
	public void clearItem(String id){
		Integer i = Integer.parseInt(id);
		for(int j=0;j<list.size();j++){
			ShopCarItem item = list.get(j);
			if(item.getBook().getId() == i)
			{
				list.remove(j);
				return ;
			}
		}
	}
}


/** 
 * 购物车条目
 */

public class ShopCarItem {
	private Integer id;    //图书id
	private Book book; //图书
	private Integer num;  //购买数目
	private Float totalPrice;  //图书项总价
	
	public ShopCarItem(Integer id, Book book, Integer num) {
		this.id = id;
		this.book = book;
		this.num = num;
	}
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public Book getBook() {
		return book;
	}
	public void setBook(Book book) {
		this.book = book;
	}
	public Integer getNum() {
		return num;
	}
	public void setNum(Integer num) {
		this.num = num;
	}
	public Float getTotalPrice() {
		totalPrice = book.getPrice() * num;
		return totalPrice;
	}
}
下面是业务逻辑处理对象:
package shop.service;

import java.util.List;
import shop.domain.Book;
import shop.domain.ShopCar;
/**
 * 处理购物车的业务逻辑类
 * @author Jam
 *
 */
public class BookService {
	DBService dbService = new DBService();
	public BookService(){
		
	}
	public List<Book> getBookList(){
		return dbService.getBookList();
	}
	public void addBook(String id ,ShopCar car,String count){
		int id1 = Integer.parseInt(id);
		//查找出数据库中对应这个id的书
		for(Book b: getBookList()){
			if(id1 == b.getId()){
				car.addBook(b,count);
				return ;
			}
		}
	}
	public void clearShopCar(ShopCar car){
		car.clearCar();
	}
	public void clearItem(String id,ShopCar car){
		car.clearItem(id);
	}
}

下面是servlet:


package shop.service;

import java.util.List;
import shop.domain.Book;
import shop.domain.ShopCar;
/**
 * 处理购物车的业务逻辑类
 * @author Jam
 *
 */
public class BookService {
	DBService dbService = new DBService();
	public BookService(){
		
	}
	public List<Book> getBookList(){
		return dbService.getBookList();
	}
	public void addBook(String id ,ShopCar car,String count){
		int id1 = Integer.parseInt(id);
		//查找出数据库中对应这个id的书
		for(Book b: getBookList()){
			if(id1 == b.getId()){
				car.addBook(b,count);
				return ;
			}
		}
	}
	public void clearShopCar(ShopCar car){
		car.clearCar();
	}
	public void clearItem(String id,ShopCar car){
		car.clearItem(id);
	}
}

list.jsp


<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ page import="shop.domain.*" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>书本商品列表信息</title>
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="cache-control" content="no-cache">
	<meta http-equiv="expires" content="0">    
	<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
	<meta http-equiv="description" content="This is my page">
	<link type="text/css" rel="stylesheet" href="css/style.css" />
  </head>
  <body>
  <h1>欢迎购买</h1>
  <div class="contain-list">
	  	<% List<Book> list = (List<Book>)request.getAttribute("BOOKLIST"); %>
	  	<%for(Book b : list){ %>
	  	<div class="list">
	  		<ul>
	  			<li><img src="<%=b.getUrl()%>"/></li>
	  			<li><%=b.getTitle()%></li>
	  			<li><span>数量:</span><input class="count" maxlength="3" type="text" value="1" id="<%=b.getId()+"input"%>"/><span>单价:<%=b.getPrice()%></span></li>
	 				<%
  						String url = request.getContextPath()+"/BookServlet?action=addBook&id="+b.getId();
  						url = response.encodeURL(url);
  					%>
	  			<li class="buy"><a id="<%=b.getId()%>" href="<%=url%>">立即购买</a></li>
	  			</ul>
	  	</div>
	  	<%}%>
  	</div>
  	<script type="text/javascript">
  		<%for(Book b : list){%>
  			document.getElementById("<%=b.getId()%>").onclick = function(){
  				var inputElement = document.getElementById("<%=b.getId()+"input"%>");
  				if(inputElement.value.length>0){
						if(/[0-9]+/.test(inputElement.value)){
							this.href = this.href+"&count="+inputElement.value;
						}
						else{
							alert("请填入数字");
							return false;
						}
					}else{
						alert("数量不能为空");
						return false;
					}
				}
  		<%}%>
  	</script>
  </body>
</html>

shopcar.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8" %>
<%@ page import="shop.domain.ShopCar" %>
<%@ page import="shop.domain.ShopCarItem" %>
<%@ page import="java.util.*" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>购物车</title>
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="cache-control" content="no-cache">
	<meta http-equiv="expires" content="0">    
	<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
	<meta http-equiv="description" content="This is my page">
	<link type="text/css" rel="stylesheet" href="css/style.css" />
  </head>
  
  <body>
  <% ShopCar car = (ShopCar) request.getSession().getAttribute("SHOPCAR"); %>
    <h1>购物车列表</h1>
    <div class="head">
    	<%
    		String url = request.getContextPath()+"/BookServlet?action=list";
    		String urlClear = request.getContextPath()+"/BookServlet?action=clear";
    	 %>
    	<a class="car" href="<%=urlClear%>">清空购物车</a><a class="car" href="<%=url%>">继续购物</a><span>总价:<%=car.getTotalPirce() %></span>
    </div>
    <div class="contain-list">
    	
    	<%
    		for(ShopCarItem item : car.getList()){ 
    	%>
	  	<div class="list">
	  		<ul>
	  			<li><img src="<%=item.getBook().getUrl()%>"/></li>
	  			<li><%=item.getBook().getTitle()%></li>
	  			<li><span>数量:<%=item.getNum() %></span></li>
	  			<li><span>总价:<%=item.getTotalPrice().intValue()%></span></li>
	  			<%
	  				int bookId = item.getBook().getId();
	  				String removeItemUrl = request.getContextPath()+"/BookServlet?action=clearItem&id="+bookId;
	  			 %>
	  			<li><li class="buy"><a href="<%=removeItemUrl%>">移出购物车</a></li></li>
	  			</ul>
	  	</div>
	  	<%}%>
    </div>
    
  </body>
</html>




上面的工程实现了使用session和servlet和jsp结合展示购物列表和购物车页面。



你可能感兴趣的:(session_jsp应用原理)