WEB后端_Day06(Cookie练习、Session会话、登录-显示用户名、验证码、EasyCaptcha、Servlet3.0新增功能、购物车)

WEB后端_Day06(Cookie练习、Session会话、登录-显示用户名、验证码、EasyCaptcha、Servlet3.0新增功能、购物车)

Cookie

由服务端产生,保存在客户端的这样一种会话保持技术

创建cookie Cookie cookie = new Cookie(key ,value);

设置cookie的生命周期 cookie.setMaxAge(N秒);

设置cookie的路径:cookie.setPath(req.getContextPath()+"/");//工程路径名

将cookie传递个客户端:resp.addCookie(cookie对象);

设置路径:

public class CookieServlet  extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req,resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
         //创建Cookie
        Cookie cookie = new Cookie("key", "Cookie_value");
        cookie.setMaxAge( 60 * 60);
        cookie.setPath(req.getContextPath()+"/abc");
        //将cookie添加到相应头中
        resp.addCookie(cookie);
    }
}

public class GetCookieServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req,resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        Cookie newCookie = new Cookie("key1", "lanqiao");
        newCookie.setPath(req.getContextPath()+"/def");
        resp.addCookie(newCookie);

    }
}

<servlet>
        <servlet-name>cook</servlet-name>
        <servlet-class>cn.lanqiao.CookieServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>cook</servlet-name>
        <url-pattern>/abc/cook</url-pattern>
    </servlet-mapping>
    <servlet>
        <servlet-name>get</servlet-name>
        <servlet-class>cn.lanqiao.GetCookieServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>get</servlet-name>
        <url-pattern>/def/get</url-pattern>
    </servlet-mapping>

Cookie 练习—免输入用户名登录

当用户第一次登陆的时候 是需要输入用户名和密码

当用户第一次登录成功之后 则后续将不再需要输入用户名 用户实现一个自动填充。

    <form action="/login">
        用户名:<input type="text" placeholder="请输入用户名" name="username" value="${cookie.username.value}"/><br/><br/>
        密码:<input type="text" placeholder="请输入密码" name="password" value=""/><br/><br/>
        <input type="submit" value="登陆">
      </form>
 protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String username = req.getParameter("username");
        String password= req.getParameter("password");
        if("admin".equals(username)&&"123456".equals(password)){
            //此时就登陆成功
            resp.getWriter().write("登陆成功");
            //登陆成功之后 将用户名存入到cookie  并回传给客户端
            Cookie  cookie = new Cookie("username", username);
            cookie.setMaxAge(24*60*60);
            resp.addCookie(cookie);
        }else{
            resp.sendRedirect("/index.jsp");
        }
    }

Cookie的失效

1 设置的maxAge到期

2 手动清除浏览器的cookie

Session 会话

什么是Session 会话

  1. Session 就一个接口(HttpSession)。

  2. Session 就是会话。它是用来维护一个客户端和服务器之间关联的一种技术。

  3. 每个客户端都有自己的一个Session 会话。

  4. Session 会话中,我们经常用来保存用户登录之后的信息。

如何创建Session 和获取(id 号,是否为新

如何创建和获取Session。它们的API 是一样的。

  • request.getSession()

    • 第一次调用是:创建Session 会话
      • 之后调用都是:获取前面创建好的Session 会话对象。
  • isNew(); 判断到底是不是刚创建出来的(新的)

  • true 表示刚创建

  • false 表示获取之前创建

每个会话都有一个身份证号。也就是ID 值。而且这个ID 是唯一的。getId() 得到Session 的会话id 值。

HttpSession session =  req.getSession();
//判断session是否是新建的
System.out.println(session.isNew());
//获取session的id
System.out.println(session.getId());

当我们在请求一个应用的使用,如果第一访问应用请求的是一个jsp页面 那么此时就会立即创建一个session对象
在这里插入图片描述

什么时候新建session?

  1. 当第一次请求的是jsp的时候 且页面没有设置session指令或者设置为true 则在访问jsp的时候 就会创建session

  2. 如果第一次直接请求一个servlet 则servlet新建

  3. 如果第一一次请求的jsp的页面的session设置为false 在会在第一个请求的servelt中创建一个新的session

使用session来存取数据

 @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html");
        resp.setCharacterEncoding("utf-8");
        String username = req.getParameter("username");
        String password= req.getParameter("password");
        if("admin".equals(username)&&"123456".equals(password)){
            //此时就登陆成功
            resp.getWriter().write("登陆成功");
            //登陆成功之后 将用户名存入到cookie  并回传给客户端
            Cookie  cookie = new Cookie("username", username);
            cookie.setMaxAge(24*60*60);
            resp.addCookie(cookie);
            //将用户信息保存到session中
           HttpSession session = req.getSession();
           session.setAttribute("username",username);
           req.getRequestDispatcher("/success.jsp").forward(req,resp);
        }else{
            resp.sendRedirect("/index.jsp");
        }
    }

获取session中的数据

   欢迎:${sessionScope.username}

Session 生命周期控制

public void setMaxInactiveInterval(int interval) 设置Session 的超时时间(以秒为单位),超过指定的时长,Session就会被销毁。

  • 值为正数的时候,设定Session 的超时时长。
  • 负数表示永不超时(极少使用)

public int getMaxInactiveInterval()获取Session 的超时时间

public void invalidate() 让当前Session 会话马上超时无效。

Session 默认的超时时长是多少! Session 默认的超时时间长为30 分钟。

tomcat的conf/web.xml中 单位为分钟

  <session-config>
        <session-timeout>30</session-timeout>
    </session-config>

我们也可以在自己的web.xml中来配置session的默认时间

安全退出

 @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        HttpSession session = req.getSession();
        //无论session是否到达失效时间 都会立即失效
        session.invalidate();
        resp.sendRedirect("/index.jsp");
    }

session失效的方式:

  1. 关闭浏览器

  2. session的超时时限到达

  3. 调用了session.invalidate();
    在这里插入图片描述

Session和Cookie的区别:

  1. Session他是由服务端自动创建,并保存在服务器端

  2. Cookie 他是由服务端创建 而且是由我们自己手动创建 ,并保存在客户端的

  3. 对同一个session的判断 是通过客户端携带的sessionID来判定的

JSESSIONID=F147FA96640D80F4A9F33F54549F0254

cookie中保存的key是固定的 JSESSIONID

登陆—显示用户名

在这里插入图片描述

注销

public void logout(HttpServletRequest req, HttpServletResponse resp){
        HttpSession session = req.getSession();
        session.invalidate();
        resp.sendRedirect("/pages/user/login.jsp");
    }

表单重复提交之-----验证码

表单重复提交有三种常见的情况:

一:提交完表单。服务器使用请求转发进行页面跳转。这个时候,用户按下功能键F5,就会发起最后一次的请求。造成表单重复提交问题。解决方法:使用重定向来进行跳转

二:用户正常提交服务器,但是由于网络延迟等原因,迟迟未收到服务器的响应,这个时候,用户以为提交失败,就会着急,然后多点了几次提交操作,也会造成表单重复提交–可以在前端,当用户点击了提交按钮之后 ,就将提交按钮置为不可用。

三:用户正常提交服务器。服务器也没有延迟,但是提交完成后,用户回退浏览器。重新提交。也会造成表单重复提交。

服务器端避免重复提交的思路:

  1. 在进入每一个jsp页面的时候 都是需要经过servelt

  2. 在进入表单页时,此时可以在servlet中产生一个token 将token保存在session中,然后在页面从session中获取token

  3. 当提交表单的时候 连同token一起提交到处理表达的servlet中

  4. 此时用提交的token和session中保存的token进行比较 如果一致,则不是重复提交 正常处理表单数据 ,同时将session中token重新生成或者直接将token给移除

  5. 如果重复提交 页面存在token 而此时的session中的token 已经发生了变化

  6. 如果此时客户重复提交 那么当我们接受到之后 通过token的判断 因为token不一致 则可以认定为重复提交

EasyCaptcha

简介

Java图形验证码,支持gif、中文、算术等类型,可用于Java Web、JavaSE等项目

使用

下载并添加jar

在web.xml中进行配置

   <!-- 图形验证码servlet -->
    <servlet>
        <servlet-name>CaptchaServlet</servlet-name>
        <servlet-class>com.wf.captcha.servlet.CaptchaServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>CaptchaServlet</servlet-name>
        <url-pattern>/captcha</url-pattern>
    </servlet-mapping>

前端

<label>验证码:</label>
									<input class="itxt" type="text" style="width: 150px;"  name = "code" id="code"/>
									<img src="captcha" width="130px" height="48px" />

后端
在这里插入图片描述

看不清 换一张

<label>验证码:</label>
	<input class="itxt" type="text" style="width: 150px;"  name = "code" id="code"/>
	<a href="javascript:void(0)"  id="captcha">
		<img src="captcha" id="captchaImg"  width="130px" height="48px" />
	</a>
$("#captcha").click(function (){
    //请求后边的参数 必须要有   如果没有  因为每一次的请求路径都是一样的  此时浏览器会认为是重复请求   所以就不会发送这个请求到服务器 
    $("#captchaImg").attr("src","${basePath}captcha?d="+new Date())
})

Servlet3.0新增的注解功能

@WebServlet注解

1. 说明:该注解用来配置Servlet,其将会在服务器启动时被tomcat容器处理,容器将根据具体的属性配置将相应的类部署为 Servlet。

  1. 参数的说明:
    在这里插入图片描述
@WebServlet(name = "user",urlPatterns = {"/user","/bookUser"},
        initParams = {@WebInitParam(name = "username",value = "admin"),@WebInitParam(name = "password",value = "123456")},
       loadOnStartup = 100)

监听器@WebListener 不需要参数

购物车模型分析

在这里插入图片描述

购物车模型的实现

public class CartItem {
    private Integer id;
    private String name;
    private Integer number;
    private BigDecimal price;
    private BigDecimal totalPrice;

    public CartItem() {
    }

    public CartItem(String name, Integer number, BigDecimal price, BigDecimal totalPrice) {
        this.name = name;
        this.number = number;
        this.price = price;
        this.totalPrice = totalPrice;
    }

    public CartItem(Integer id, String name, Integer number, BigDecimal price, BigDecimal totalPrice) {
        this.id = id;
        this.name = name;
        this.number = number;
        this.price = price;
        this.totalPrice = totalPrice;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getNumber() {
        return number;
    }

    public void setNumber(Integer number) {
        this.number = number;
    }

    public BigDecimal getPrice() {
        return price;
    }

    public void setPrice(BigDecimal price) {
        this.price = price;
    }

    public BigDecimal getTotalPrice() {
        return totalPrice;
    }

    public void setTotalPrice(BigDecimal totalPrice) {
        this.totalPrice = totalPrice;
    }
}
public class Cart {
    private Integer totalNumber;
    private BigDecimal priceAll;
    //表示购物车
    private Map<Integer,CartItem> cart = new HashMap<>();
	
    public Map<Integer, CartItem> getCart() {
        return cart;
    }
    
    //添加商品到购物车
    public  void  addItem(CartItem item){
        Integer id = item.getId();
        //购物车中已经有了该商品
        if(cart.containsKey(id)){
            Integer number = cart.get(id).getNumber()+1;
            item.setNumber(number);
            BigDecimal totalPrice = item.getPrice().multiply(BigDecimal.valueOf(number));
            item.setTotalPrice(totalPrice);
        }
        cart.put(id,item);
    }
    //删除商品
    public  void deleteItem(Integer id){
        cart.remove(id);
    }
    //清空购物城
    public  void emptyCar(){
        cart.clear();
    }
    //修改商品的数量
    public void updateItem(Integer id,Integer number){
       CartItem item =  cart.get(id);
       item.setNumber(number);
       item.setTotalPrice(item.getPrice().multiply(BigDecimal.valueOf(number)));
        cart.put(id,item);
    }

    public Integer getTotalNumber() {
        int  totalNumber = 0 ;
        for(Map.Entry<Integer,CartItem> entry :cart.entrySet()){
            CartItem item =  entry.getValue();
            totalNumber += item.getNumber();
        }
        return  totalNumber;
    }

    public BigDecimal getPriceAll() {
        BigDecimal  priceAll = new BigDecimal(0);
        for(Map.Entry<Integer,CartItem> entry :cart.entrySet()){
            CartItem item =  entry.getValue();
            priceAll.add(item.getTotalPrice());
        }
        return  priceAll;
    }
}

加入购物车功能的实现

实现首页经过servlet的跳转 从数据库获取数据

在index.jsp实现转发

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<meta charset="UTF-8">
<title>零点读书</title>

</head>
<body>
	<jsp:forward page="/index?_method=list"></jsp:forward>
</body>
</html>
@WebServlet("/index")
public class IndexServlet extends BaseServlet{
    private IBookService bookService = new BookServiceImpl();
    public  void list(HttpServletRequest req , HttpServletResponse resp) throws ServletException, IOException {
        String pageNoStr = req.getParameter("pageNo");
        Integer pageNo = 1;
        if(!"".equals(pageNoStr)&&pageNoStr!=null){
            pageNo = Integer.parseInt(pageNoStr);
        }
        Page<Book> page =   bookService.pageList(pageNo,Page.PAGESIZE);
        req.setAttribute("page",page);

        req.getRequestDispatcher("/pages/home.jsp").forward(req,resp);
    }
}

添加商品到购物车

home.jsp

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <meta charset="UTF-8">
    <title>零点读书</title>
    <%@include file="public/top.jsp"%>
</head>
<body>
<div id="header">
    <img class="logo_img" alt="" src="static/img/logo.jpg" >
    <div>
        <a href="pages/user/login.jsp">登录</a> |
        <a href="pages/user/regist.jsp">注册</a> &nbsp;&nbsp;
        <a href="pages/cart/cart.jsp">购物车</a>
        <a href="pages/manager/manager.jsp">后台管理</a>
    </div>
</div>
<div id="main">
    <div id="book">
        <div class="book_cond">
            <form action="" method="get">
                价格:<input id="min" type="text" name="min" value=""> 元 -
                <input id="max" type="text" name="max" value=""><input type="submit" value="查询" />
            </form>
        </div>
        <div style="text-align: center">
            <span>您的购物车中有${cart.totalNumber}件商品</span>
            <div>
                您刚刚将<span style="color: red">${item.name}</span>加入到了购物车中
            </div>
        </div>
        <c:forEach items="${page.pageList}" var="book">
            <div class="b_list">
                <div class="img_div">
                    <img class="book_img" alt="" src="static/img/hxjs.jpg" />
                </div>

                <div class="book_info">
                    <div class="book_name">
                        <span class="sp1">书名:</span>
                        <span class="sp2">${book.name}</span>
                    </div>
                    <div class="book_author">
                        <span class="sp1">作者:</span>
                        <span class="sp2">${book.author}</span>
                    </div>
                    <div class="book_price">
                        <span class="sp1">价格:</span>
                        <span class="sp2">¥${book.price}</span>
                    </div>
                    <div class="book_sales">
                        <span class="sp1">销量:</span>
                        <span class="sp2">${book.sales}</span>
                    </div>
                    <div class="book_amount">
                        <span class="sp1">库存:</span>
                        <span class="sp2">${book.stock}</span>
                    </div>
                    <div class="book_add">
                        <form action="cart" method="post">
                            <input type="hidden" name="_method" value="addCart"/>
                            <input type="hidden" name="id" value="${book.id}">
                            <input type="submit" value="加入购物车"/>
                        </form>

                    </div>
                </div>
            </div>
        </c:forEach>

    </div>

    <div id="page_nav">
        <c:if test="${page.pageNo > 1}">
            <a href="book?_method=list&pageNo=1">首页</a>
            <a href="book?_method=list&pageNo=${page.pageNo-1}">上一页</a>
        </c:if>
        <c:forEach begin="1" end="${page.pageTotal}" step="1" var="i">
            <c:if test="${i == page.pageNo}">
                【${i}】
            </c:if>
            <c:if test="${i != page.pageNo}">
                <a href="book?_method=list&pageNo=${i}">${i}</a>
            </c:if>

        </c:forEach>
        <c:if test="${page.pageNo < page.pageTotal}">
            <a href="book?_method=list&pageNo=${page.pageNo+1}">下一页</a>
            <a href="book?_method=list&pageNo=${page.pageTotal}">末页</a>
        </c:if>

        共${page.pageTotal}页,共${page.totalCount}条记录 到第<input value="${page.pageNo}" name="pn" id="pn_input"/><input type="button" id="subBtn" value="确定">
    </div>
    <jsp:include page="/pages/public/foot.jsp"/>
</div>

</body>
</html>
@WebServlet("/cart")//可以不写name  直接给一个字符串就是url
public class CartServlet  extends BaseServlet{
    private IBookService bookService = new BookServiceImpl();
    public  void  addCart(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        Integer id = Integer.parseInt(req.getParameter("id"));
        Book book = bookService.queryBookById(id);
        CartItem item = new CartItem(book.getId(),book.getName(),1,book.getPrice(),book.getPrice());
        //购物车保存在session中
        HttpSession session = req.getSession();
        Cart cart = (Cart) session.getAttribute("cart");
        if(cart == null){
            Cart newCart = new Cart();
            newCart.addItem(item);
            session.setAttribute("cart",newCart);
        }else{
            cart.addItem(item);
        }
        String pageNoStr = req.getParameter("pageNo");
        Integer pageNo = 1;
        if(!"".equals(pageNoStr)&&pageNoStr!=null){
            pageNo = Integer.parseInt(pageNoStr);
        }
        Page<Book> page =   bookService.pageList(pageNo,Page.PAGESIZE);
        req.setAttribute("page",page);

        req.setAttribute("item",item);
        req.getRequestDispatcher("/pages/home.jsp").forward(req,resp);
    }
}

购物车信息的展示

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<meta charset="UTF-8">
<title>购物车</title>
<jsp:include page="/pages/public/top.jsp"/>
<link type="text/css" rel="stylesheet" href="static/css/style.css" >
	<script type="text/javascript">
		$(function (){
			$(".del").click(function (){
				return confirm("您确定要删除该商品吗?");
			})
			$(".empty").click(function (){
				return confirm("您确定要清空购物车吗?");
			})
		})
	</script>
</head>
<body>
	
	<div id="header">
			<img class="logo_img" alt="" src="static/img/logo.jpg" >
			
			<div>
				<span>欢迎<span class="um_span">${user.username}</span>光临零点读书</span>
				<a href="pages/order/order.html">我的订单</a>
				<a href="logout">注销</a>&nbsp;&nbsp;
				<a href="index.jsp">返回</a>
			</div>
	</div>
	
	<div id="main">
		<c:if test="${empty sessionScope.cart}">
			<h1 style="color: red">您当前的购物车为空,请前往商品页选购商品</h1>
		</c:if>
		<c:if test="${not empty sessionScope.cart}">
			<table>
				<tr>
					<td colspan="5" style="font-size:28px;font-weight:800">购物车</td>
				</tr>
				<tr>
					<td>商品名称</td>
					<td>数量</td>
					<td>单价</td>
					<td>金额</td>
					<td>操作</td>
				</tr>
				<c:forEach items="${sessionScope.cart.cart.values()}" var="item">
					<tr>
						<td>${item.name}</td>
						<td>${item.number}</td>
						<td>${item.price}</td>
						<td>${item.totalPrice}</td>
						<td><a href="cart?_method=deleteCartItem&id=${item.id}" class="del">删除</a></td>
					</tr>

				</c:forEach>

			</table>
		</c:if>

		<c:if test="${not empty sessionScope.cart}">
		<div class="cart_info">
			<span class="cart_span">购物车中共有<span class="b_count">${sessionScope.cart.totalNumber}</span>件商品</span>
			<span class="cart_span">总金额<span class="b_price">${sessionScope.cart.priceAll}</span></span>
			<span class="cart_span"><a href="cart?_method=emptyCart" class="empty">清空购物车</a></span>
			<span class="cart_span"><a href="pages/cart/checkout.html">去结账</a></span>
		</div>
		</c:if>
	</div>
	
	<div id="bottom">
		<span>
			零点读书.Copyright &copy;2020
		</span>
	</div>
</body>
</html>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值