Servlet——Session(2)之简单应用

Session技术的应用

1.防止用户非法登录到某个页面

比如我们的用户管理系统,必须要登录成功后才能跳转到主页面,而不能直接绕过登录页面直接到主页面,这个应用是一个非常常见的应用。

这时候,我们需要使用到Session技术,如下,当在验证用户的控制器LoginClServlet.java验证用户成功后,将当前的用户信息保存在Session对象中:

// 把user对象保存在session
HttpSession session = request.getSession();
session.setAttribute("login-user", user);

然后在主页面MainFrame.java最开始的地方,取出Session中的登录用户信息,如果信息为空,则为非法访问,直接跳转到登录页面,并提示相关信息:

// 取出login-user这个session
User login_user = (User)request.getSession().getAttribute("login-user");
if(login_user == null){
    // 说明用户没有登录,让他跳转到登录页面
    request.setAttribute("error", "请登录!");
    request.getRequestDispatcher("/LoginServlet").forward(request,response);
    // 这个return很重要!
    return;
}

那么这里就存在一个问题,一个网站会有很多个需要防止非法访问的页面,如果都是用这种方法岂不是很麻烦?

这里有两种解决办法:

第一种是将这段验证用户的代码封装成函数,每次调用

第二种是使用过滤器(后面会介绍)

2.用户登录时验证输入的验证码是否正确

原理:使用到java的绘图技术

假设我们编写登录页面Login,验证用户的LoginClServlet,以及生成验证码的CreateCode,如下所示:

用户在访问登录页面Login的时候,Login页面会去请求CreateCode这个Servlet生成验证码,然后显示在自己的页面上,然后再提交到LoginClServlet进行验证。很显然,访问Login和请求CreateCode这是从浏览器发出的两次不同的请求,所以,CreateCode产生的验证码字符串必须放入Session中,才能让LoginClServlet拿到,然后进行验证。

那么怎么让登录页面Login显示验证码呢?其实很简单,直接将img的src指向CreateCode这个Servlet即可,如下所示:

out.println("<font color=white>验证码:<input type=‘text‘ name=‘checkcode‘/><img src=‘/mycheckcode/CreateCode‘>");

可以看到运行结果:

这个登录表单提交到LoginClServlet进行验证,它需要从参数中获取用户输入的验证码,再从Session中取出CreateCode这个Servlet放入Session中的正确的验证码,然后对比两者,它的doGet方法的关键代码如下:

//获取用户的id/password/输入的验证码
String id = request.getParameter("id");
String passwd = request.getParameter("passwd");
// 用户输入的验证码
String input_checkcode = request.getParameter("checkcode");
// 正确的验证码
String checkcode = (String)request.getSession().getAttribute("checkcode");
// 先看验证码对不对
if(input_checkcode.toLowerCase().equals(checkcode)){
    // 验证码OK,再到数据库验证id和passwd
}else{
    request.setAttribute("error", "验证码有误");
    request.getRequestDispatcher("/Login").forward(request, response);
}

这里最重要的其实是生成验证码的Servlet,Servlet代码如下

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;

import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class CreateCode extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        // 7.禁止浏览器缓存随机图片
        response.setDateHeader("Expires", -1);
        response.setHeader("Cache-Control", "no-cache");
        response.setHeader("Pragma", "no-cache");

        // 6.通知客户机以图片方式打开发送过去的数据
        response.setHeader("Content-Type", "image/jpeg");

        // 1.在内存中创建一幅图片
        BufferedImage image = new BufferedImage(110, 30,
                BufferedImage.TYPE_INT_BGR);

        // 2.向图片上写数据
        Graphics g = image.getGraphics();

        // 设背景色
        g.setColor(Color.white);
        g.fillRect(0, 0, 110, 30);

        String checkcode = "";
        // 画5个验证码字符
        for(int i=0;i<5;i++){
            g.setColor(generateColor());
            g.setFont(generateFont());
            String str = generateStr();
            checkcode += str;
            g.drawString(str,20*i,25);
        }

        // 画干扰点
        for(int i=0;i<100;i++){
            Random random = new Random();
            int x = random.nextInt(110);
            int y = random.nextInt(30);
            g.setColor(generateColor());
            g.fillOval(x, y, 2, 2);
        }
        // 画干扰线
        for(int i=0;i<5;i++){
            Random random = new Random();
            int x1 = random.nextInt(110);
            int y1 = random.nextInt(30);
            int x2 = random.nextInt(110);
            int y2 = random.nextInt(30);
            g.setColor(generateColor());
            g.drawLine(x1, y1, x2, y2);
        }

        // 这句话就是把随机生成的验证码,保存到session
        // 验证码不区分大小写,所以这里转为小写
        request.getSession().setAttribute("checkcode", checkcode.toLowerCase());

        // 5.把写好数据的图片输出给浏览器
        ImageIO.write(image, "jpg", response.getOutputStream());

    }

    /**
     * 生成随机字体
     * @return
     */
    public Font generateFont() {
        String[] font_names = new String[] { "Broadway", "方正姚体",
                "Footlight MT Light", "Sitka Text", "方正舒体", "幼圆" ,"Colonna MT"};
        int[] font_styles = new int[]{Font.BOLD, Font.ITALIC, Font.BOLD|Font.ITALIC};

        Random random = new Random();
        int name_index = random.nextInt(font_names.length);
        int style_index = random.nextInt(font_styles.length);

        return new Font(font_names[name_index],font_styles[style_index],28);
    }

    /**
     * 生成随机颜色
     *
     * @return
     */
    public Color generateColor() {
        Random random = new Random();
        return new Color(random.nextInt(256), random.nextInt(256),
                random.nextInt(256));
    }

    /**
     * 生成随机数[0-9a-zA-Z]
     *
     * @return
     */
    public String generateStr() {
        String[] nums = new String[62];
        // 添加0-9这10个数字
        for (int i = 0; i < 10; i++) {
            nums[i] = String.valueOf(i);
        }
        // 添加A-Z这26个大写字母
        for (int i = 65; i < 91; i++) {
            nums[i - 55] = Character.toString((char) i);
        }
        // 添加a-z这26个小写字母
        for (int i = 97; i < 123; i++) {
            nums[i - 61] = Character.toString((char) i);
        }
        // 产生一个随机数
        Random random = new Random();
        int index = random.nextInt(62);
        return nums[index];
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        this.doGet(request, response);
    }

}

3.实现简易购物车

假设我们要在网上买书,那么怎么实现添加到购物车,并可以查看购物车的功能呢?肯定要使用Session。

首先,我们先写一个Book类,该类封装Book的相关信息,这里简单起见,主要有ID号,书名,以及购买的本数。然后模拟一个数据库,如下:

import java.util.HashMap;
import java.util.LinkedHashMap;

/**
 * 模拟数据库
 */
final public class DB {
    private static HashMap<String, Book> hm = null;

    private DB(){

    }

    static{
        hm = new LinkedHashMap<String, Book>();

        Book book1 = new Book("1", "Java基础", 0);
        Book book2 = new Book("2", "Oracle数据库", 0);
        Book book3 = new Book("3", "C语言", 0);
        Book book4 = new Book("4", "Python核心教程", 0);
        Book book5 = new Book("5", "Web技术", 0);

        hm.put(book1.getId(),book1);
        hm.put(book2.getId(),book2);
        hm.put(book3.getId(),book3);
        hm.put(book4.getId(),book4);
        hm.put(book5.getId(),book5);
    }

    /**
     * 得到数据库中所有的书
     * @return
     */
    public static HashMap<String, Book> getBooks(){
        return hm;
    }

    /**
     * 根据ID得到书
     * @param id
     * @return
     */
    public static Book getBookById(String id){
        if(hm.containsKey(id)){
            return hm.get(id);
        }
        return null;
    }
}

然后在我们的showBook这个Servlet中读取数据库中所有的书的信息,显示在页面上,它的doGet方法为:

public void doGet(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {
    response.setContentType("text/html;charset=utf-8");
    PrintWriter out = response.getWriter();

    out.println("<h2>欢迎光临</h2>");
    out.println("<table border=1>");
    HashMap<String, Book> books = DB.getBooks();
    Iterator it = books.keySet().iterator();
    while(it.hasNext()){
        Book book = books.get(it.next());
        out.println("<tr><td>"+book.getName()+"</td><td><a href=‘/MyCart/BuyBookCl?id="+book.getId()+"‘>点击购买</a></td></tr>");
    }
    out.println("</table>");
}

可以看到,当用户点击购买的链接时,跳到BuyBookCl这个Servlet进行处理,并且一同传递过去的参数为书的id号,我们看看BuyBookCl是怎么写的:

public void doGet(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {
    response.setContentType("text/html;charset=utf-8");
    //接收用户购买书的名字
    String id = request.getParameter("id");
    String name = DB.getBookById(id).getName();
    HttpSession session = request.getSession();
    // 用HashMap更简单
    // 从session中得到购买的 书
    HashMap<String,Book> books = (HashMap<String,Book>) session.getAttribute("books");
    if(books == null){
        books = new LinkedHashMap<String,Book>();
    }
    if(books.containsKey(id)){
        Book book = books.get(id);
        book.setNum(book.getNum()+1);
    }else{
        Book book = new Book(id, name, 1);
        books.put(id, book);
    }
    session.setAttribute("books", books);
    // 转发到ShowMyCart查看购物车
    request.getRequestDispatcher("/ShowMyCart").forward(request, response);
}

我们接收到书的id后,然后从Session中取出保存购物车信息的HashMap,如果这个HashMap为空,则新建一个HashMap;如果这个HashMap不为空,则去查找是否存在该书的ID号,如果已经存在,说明之前已经购买过该书,则将这本书的数量加1,,反之将新购买的书添加进去,并且数量设置为1。

看一下运行结果:

1.ShowBook的页面:

2.点击购买之后跳转到购物车的页面:



以上是应用Session的三个简单的例子,在实际项目中,肯定不止这么简单,比如购物车,最终肯定是要存储在数据库中的。

时间: 2024-08-09 23:28:34

Servlet——Session(2)之简单应用的相关文章

玩转web之servlet(六)---session介绍及简单使用(登录验证中保存信息)

在浏览器与服务器进行交互时,往往需要把涉及到的一些数据保存下来,这时就需要使用cookie或session进行状态管理. 这篇文章先来说说session怎么用,首先在servlet中创建一个session来保存信息,举个例子,在做登陆验证时,如果登陆成功,需要将用户的信息保存到session中,怎么保存呢?下面给出代码: public class Login_Do extends HttpServlet { String order_name = ""; String order_pa

Session小案例-----简单购物车的使用

Session小案例-----简单购物车的使用 同上篇一样,这里的处理请求和页面显示同样用的都是servlet. 功能实现如下: 1,显示网站的所有商品 2,用户点击购买后,能够记住用户选择的商品 3,实现了多个会话共享一个session 4, 实现了浏览器禁用cookie后数据共享问题的处理 首页: package cn.itcast.shopping; import java.io.IOException; import java.io.PrintWriter; import java.io

servlet session跟踪实践

一.session简介 1.session概念 Session代表服务器与浏览器的一次会话过程.因为http是无状态的协议,所以,浏览器与服务器的会话过程是断断续续的.在servlet中,session指的是HttpSession对象. 浏览器第一次发出请求时,服务器创建session并生成一个sessionID.然后返回给浏览器.此时查看浏览器的cookie,会发现会有一个: Cookie:JSESSIONID=sessionID 浏览器再次发出请求时,会携带该cookie,服务器就可以根据s

session 对象的简单实例

一个session对象的简单实例: 1.登录界面:使用简单的html表单提交界面. <%@ page language="java" contentType="text/html; charset=GB18030"    pageEncoding="GB18030"%><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "ht

Servlet 教程 各个知识点简单概括

Servlet 教程 http://www.ziqiangxuetang.com/servlet/servlet-cookies-handling.html Servlet 教程 Servlet 教程 Servlet 简介 Servlet 环境设置 Servlet 生命周期 Servlet 实例 Servlet 表单数据 Servlet 客户端HTTP 请求 Servlet 服务器 HTTP 响应 Servlet HTTP 状态码 Servlet 编写过滤器 Servlet 异常处理 Servl

一个简单的jsp+servlet实例,实现简单的登录

开发环境myeclipse+tomcat5.5 一.先创建web project 在菜单栏选File->New->Web->Dynamic Web Project Project name我命名为JavaWebTest01 (可以随便起) Target runTime 选我们之前tomcat配置的版本. 一直NEXT到Finish 二.新建jsp页面 1.在WebContent下新建一个jsp页面(如果列表里没有jsp选项,到other里去找) 这里我给jsp页面的名字命为welcome

Servlet——Session(3)之实现原理的深入讨论

Session实现原理深入讨论 1.Session实现机制 服务器是如何实现一个session为一个用户浏览器服务的? 解释: 假如浏览器A先访问Servlet1,这时候它创建了一个Session,ID号为110,然后Servlet1将这个ID号以Cookie的方式返回给浏览器A,接着,如果浏览器A继续访问Servlet2,那么这个请求会带上Cookie值: JSESSIONID=110,然后服务器根据浏览器A传递过来的ID号找到内存中的这个Session. 这时候假如浏览器B来访问Servle

java使用servlet画出最简单的验证码一

前面已经说明验证码存在的意义,接下来本片文章将讲解如何实现一个简单的验证码. 在进行表单设计时,验证码的增加可以实现是否为"人为"操作,增加验证码可以防止网站数据库信息的冗杂... 验证码作为一个图片,在页面中是"画"出来的,那么它是如何画出来的呢? 其中需要几个生成图片的类: { 1.BufferedImage图像数据缓冲区 2.Graphics绘制图片 3.color获取颜色 4.Random获取随机数 5.ImageIO输出图片 } =============

13 Servlet——session案例2:用户登录主页显示用户名和注销登录

案例说明 我们使用原本 第11节的代码进行改进,添加用户登录到主页后显示自己名字的功能和添加注销登录的功能. 思路设计 主页获取用户名设计 在LoginServlet中,我们在判断用户账号密码正确后,跳转主页之前,创建session并将用户对象添加到session中,在主页获取session中的对象即可. 同样地,在3天免登陆的情况下,在cookieServlet中跳转主页之前,创建session并将用户对象添加到session中,在主页获取session中的对象即可. 注销设计 添加一个表单,