学习心得--会话技术、过滤器、监听器、JavaWeb综合案例

本周学习了会话技术cookie、session的基本使用;过滤器的基本概念、基本使用以及过滤器的一些基本案例;监听器的基本使用、基本案例;最后编写了JavaWeb综合案例,包括用户列表、删除用户、添加用户、批量删除以及修改用户。

会话技术

Cookie

概念

  • 打开浏览器,访问服务器中资源,关闭浏览器;这个过程就是会话。
  • 解决ServletContext域对象、Request域对象存储数据所存在的问题

cookie基本使用

设置Cookie

  • 方式一(设置Cookie响应头)
  • response.addHeader(“set-cookie”,“msg=hellocoolie”);
  • 方式二
  • Cookie cookie = new Cookie(“msg”,“hellocookie”);
  • response.addCookie(cookie);

获取Cookie

  • request.getCookies();

开发步骤

  • 通过request对象获取所有的Cookie对象,存储到一个数组中
  • 遍历该数组,匹配Cookie名称
  • 如果匹配上,就知道了指定的Cookie对象
  • 如果匹配不上,就没有指定的Cookie对象
Cookie[] cookies = request.getCookies();
Cookie cookie = null;
for(Cookie sonCookie : cookies){
    if("msg".equals(sonCookie.getName())){
        cookie = sonCookie;
    }
}
if(null != cookie){
    System.out.println("name : "+msgCookie.getName() + " , value : "+ msgCookie.getValue());
}

Cookie的相关设置

持久化设置

  • cookie的生命周期:默认是随着浏览器的关闭而销毁
  • setMaxAge(单位为秒)
  • 设置cookie的存活时长,cookie就可以不随着会话的关闭而销毁

路径设置

  • 默认情况下,Cookie对象会随着任何一个请求携带到服务器
  • setPath
  • 设置Cookie的访问路径
Cookie cookie = new Cookie("msg","helloworld");
cookie.setPath("/Day56/demo04");
response.addCookie(cookie);

Cookie案例之记录上次访问时间

  • 获取对应的Cookie对象
  • 判断是否是第一次访问
  • 如果是第一次访问
  • 打印当前时间,将当前时间存储到Cookie中
  • 如果不是第一次访问
  • 打印上一次访问时间,将当前时间存储到Cookie中
//判断是否是一次请求
Cookie[] cookies = request.getCookies();
Cookie cookie = null;//记录上一次的访问时间
if (cookies != null && cookies.length != 0 ) {
    for (Cookie sonCookie : cookies) {
        if ("lastTime".equals(sonCookie.getName())) {
            cookie = sonCookie;
        }
    }
}
SimpleDateFormat format = new SimpleDateFormat("yyyy年MM月dd日 hh:mm:ss");
if (null == cookie) {
    //第一次访问 ,打印当前时间,并将创建Cookie对象,存储当前时间

    Date currentDate = new Date();
    System.out.println("第一次访问,时间为" + format.format(currentDate));
    cookie = new Cookie("lastTime",currentDate.getTime()+"");
} else {
    //不是第一次访问,从cookie取出上一次的访问时间,并打印。获取当前时间,并存储cookie对象中
    long lastDateMills = Long.parseLong(cookie.getValue());
    Date lastDate = new Date(lastDateMills);
    //获取到了上一次的访问时间
    String lastTimeStr = format.format(lastDate);
    System.out.println("上一次访问,时间为" + lastTimeStr);
    //获取当前时间,并存储cookie对象中
    Date currentDate = new Date();
    //            cookie.setValue(currentDate.getTime()+"");
    cookie = new Cookie("lastTime",currentDate.getTime()+"");
}

response.addCookie(cookie);

Cookie案例之商品浏览记录

  • 获取history的Cookie对象
  • 判断商品浏览记录是否为空
  • 如果浏览记录没有,创建Cookie,并将当前的商品记录到Cookie中
  • 如果浏览记录有,有当前的商品,不做任何处理;没有当前商品,就需要将当前的商品拼接到已有记录中

Session

session执行流程

  • 第一次请求Demo01Servlet时,根据request.getSession方法, 新建一个session对象
  • 当第一次响应时,会将该session对象的id作为cookie头响应给浏览器保存
  • 第二次请求Demo01Servlet时,根据request.getSession方法,请求中会有cookie头
  • 会根据该JSESSIONID去服务器中找有没有对应的session对象,如果有就直接用,没有就新建

Session相关配置

  • session默认是有30分钟的存活时间
  • session和cookie是相关联的,cookie中存储了jsessionid,request.getSession方法会根据jsessionid去选择,到底是新建session对象,还是引用原来的session对象;如果,将浏览器关闭了,就意味着cookie中存储的jsessionid就会销毁,对应request.getSession就会新建一个session对象,但是原来的session对象还存在
  • session.invalidate方法,立马将对应的session对象销毁!后续就会新建session
  • session只有两种情况会销毁:调用了invalidate方法;过了30分钟

session的基本使用

  • setAttribute:往session域对象中存储数据
  • getAttribute:从session域对象中获取数据
  • removeAttribute:把session域对象中的数据移除

session案例之登录

@WebServlet(name = "LoginServlet",urlPatterns = "/login")
public class LoginServlet extends HttpServlet {

    private UserDao userDao = new UserDaoImpl();

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        User inputUser = new User();
        inputUser.setUsername(username);
        inputUser.setPassword(password);
        try {
            User existUser = userDao.login(inputUser);
            System.out.println(existUser);
            //判断登录成功
            if (null == existUser) {
                //登录失败,请求转发,跳转到登录页面
                request.getRequestDispatcher("/login.html").forward(request,response);
            } else {
                //登录成功,重定向,跳转到显示用户信息
                //存储existUser
                //request : 跳转到首页,使用了重定向,会有一个新的请求
                //servletContext : 如果存储到ServletContext,就意味着所有人都可以拿到你的用户信息!
                //cookie : 如果存储到cookie中,就是存储到浏览器 , 不安全! cookie中是无法存储中文及一些特殊符号!!
                //session : 数据存储到服务器!!
                request.getSession().setAttribute("existUser",existUser);
                response.sendRedirect("/day57/showIndex");

            }

        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request,response);
    }
}

session案例之随机验证码

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        int width = 60;//定义图片宽度
        int height = 32;//定义图片高度
        //创建图片对象
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        //创建画笔对象
        Graphics g = image.getGraphics();
        //设置背景颜色
        g.setColor(new Color(0xDCDCDC));
        g.fillRect(0, 0, width, height);//实心矩形
        //设置边框
        g.setColor(Color.black);
        g.drawRect(0, 0, width - 1, height - 1);//空心矩形

        Random rdm = new Random();
        //画干扰椭圆
        for (int i = 0; i < 50; i++) {
            int x = rdm.nextInt(width);
            int y = rdm.nextInt(height);
            g.drawOval(x, y, 0, 0);
        }
        //产生随机字符串
        String hash1 = Integer.toHexString(rdm.nextInt());
        //生成四位随机验证码
        String capstr = hash1.substring(0, 4);
        //将产生的验证码存储到session域中,方便以后进行验证码校验!
        request.getSession().setAttribute("existCode", capstr);
        System.out.println(capstr);
        g.setColor(new Color(0, 100, 0));
        g.setFont(new Font("Candara", Font.BOLD, 24));
        g.drawString(capstr, 8, 24);
        g.dispose();
        //将图片响应到浏览器
        response.setContentType("image/jpeg");
        OutputStream strm = response.getOutputStream();
        ImageIO.write(image, "jpeg", strm);
        strm.close();
    }

过滤器

过滤器的概念

  • 过滤器就是一个用于在请求之前处理资源的组件

生命周期

  • 随着服务器启动而初始化
  • 随着请求的发出而过滤
  • 随着服务器关闭而销毁

执行流程

  • 浏览器发起请求
  • 服务器会根据这个请求,创建request对象及response对象
  • 过滤器会持有request对象及response对象
  • 只有当过滤器放行之后,request对象及response对象才会传给Serlvet
  • 过滤器链:根据配置顺序,遵从"先过滤,后放行"的原则

过滤器的基本使用

  • 自定义类实现Filter接口
  • 重写init、doFilter、destroy方法
  • 在web.xml中配置过滤器
<!--声明Demo01Filter过滤器-->
<filter>
    <filter-name>Demo01Filter</filter-name>
    <filter-class>com.qfedu.filter.Demo01Filter</filter-class>
</filter>

<!--配置Demo01Filter的过滤路径-->
<filter-mapping>
    <filter-name>Demo01Filter</filter-name>
    <url-pattern>/*

过滤器的相关配置

  • 初始化参数
    <filter>
        <filter-name>Demo03Filter</filter-name>
        <filter-class>com.qfedu.filter.Demo03Filter</filter-class>
        <!--初始化参数-->
        <init-param>
            <param-name>username</param-name>
            <param-value>root</param-value>
        </init-param>
        <init-param>
            <param-name>password</param-name>
            <param-value>root123</param-value>
        </init-param>
    </filter>
  • 获取初始化参数
public class Demo03Filter implements Filter {

    public void init(FilterConfig config) throws ServletException {
        Enumeration<String> parameterNames = config.getInitParameterNames();
        while (parameterNames.hasMoreElements()) {
            //获取初始化参数名称
            String parameterName = parameterNames.nextElement();
            //获取初始化参数值
            String parameterValue = config.getInitParameter(parameterName);
            System.out.println("name : " + parameterName + " , value : " + parameterValue);
        }
    }
}

过滤器的注解开发

  • @WebFilter注解
  • WebInitParam[] initParams() default {};
  • String filterName() default “”;
  • String[] servletNames() default {};
  • String[] urlPatterns() default {};
  • 执行顺序
  • 按照过滤器的类名的字典顺序决定谁先过滤,谁先放行
  • 比如AFilter、BFilter,那么AFilter就会先过滤,BFilter会先放行

过滤器案例之自动登录

  • 判断访问的资源是否和登录相关
  • 如果是登录相关资源,直接放行
  • 如果不是登录相关资源 ,进行自动登录
  • 判断登录状态:如果已经在登录状态,直接放行;如果不在登录状态,进行自动登录
  • 获取cookie:cookie为null(清理了浏览器缓存),转发到登录页面;cookie不为null,进行自动登录
    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
        HttpServletRequest request = (HttpServletRequest) req;
        //获取请求路径
        String requestURI = request.getRequestURI();
        //1,判断访问的资源是否和登录相关
        if (requestURI.contains("login")) {
            //和登录相关的资源,直接放行
            chain.doFilter(request, resp);
        } else {
            //不是登录相关的资源
            //2,判断是否在登录状态
            User existUser = (User) request.getSession().getAttribute("existUser");
            if (null == existUser) {
                //不在登录状态 , 进行自动登录
                //获取Cookie
                Cookie cookie = CookieUtils.getCookie(request.getCookies(), "autoLogin");
                //判断cookie是否为空 , 存在浏览器清理缓存
                if (null == cookie) {
                    //浏览器清理缓存 , 相当于自动登录失败!! 跳转到登录页面,进行手动登录
                    request.getRequestDispatcher("/login.jsp").forward(request,resp);
                } else {
                    //还有缓存,进行自动登录
                    //获取用户信息 root-root
                    String infoStr = cookie.getValue();
                    String[] infos = infoStr.split("-");
                    String username = infos[0];
                    String password = infos[1];
                    if ("root".equals(username) && "root".equals(password)) {
                        //自动登录成功  ,修改登录状态, 直接放行  ,意味着,还不在登录状态!!!
                        existUser = new User();
                        existUser.setUsername(username);
                        existUser.setPassword(password);
                        request.getSession().setAttribute("existUser",existUser);
                        chain.doFilter(req,resp);
                    } else {
                        //自动登录失败 (修改了密码) ,跳转到登录页面,进行手动登录
                request.getRequestDispatcher("/login.jsp").forward(request,resp);
                    }
                }
            } else {
                //在登录状态 , 直接放行
                chain.doFilter(request,resp);
            }
        }
    }

过滤器应用之敏感词屏蔽

@WebFilter(
        filterName = "SensitiveWordsFilter" ,
        urlPatterns = "/*",
        initParams = {
                @WebInitParam(name = "word1",value = "笨蛋")
        })
public class SensitiveWordsFilter implements Filter {

    //敏感词
    List<String> sensitiveWords = new ArrayList<>();

    public void init(FilterConfig config) throws ServletException {
        Enumeration<String> parameterNames = config.getInitParameterNames();
        while (parameterNames.hasMoreElements()) {
            String sensitiveWord = config.getInitParameter(parameterNames.nextElement());
            sensitiveWords.add(sensitiveWord);
        }
    }

    public void destroy() {
    }

    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
        System.out.println("SensitiveWordsFilter doFilter");
        HttpServletRequest request = (HttpServletRequest) req;
        //增强request下的getParameter方法
        HttpServletRequest requestPrxoy = (HttpServletRequest) Proxy.newProxyInstance(
                request.getClass().getClassLoader(),
                request.getClass().getInterfaces(),
                new InvocationHandler() {
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        //增强getParameter方法
                        Object returnValue = null;
                        String methodName = method.getName();
                        if ("getParameter".equals(methodName)) {
                            //returnValue就是getParameter方法的返回值,可能会存在敏感词
                            String returnValue1 = (String)method.invoke(request, args);
                            //开始处理敏感词
                            for (String sensitiveWord : sensitiveWords) {
                                if (returnValue1.contains(sensitiveWord)) {
                                    //getParameter方法的返回值包含敏感词
                                    returnValue1 = returnValue1.replace(sensitiveWord,"***");
                                }
                            }
                            return returnValue1;
                        } else {
                            returnValue = method.invoke(request, args);
                        }
                        return returnValue;
                    }
                });
        chain.doFilter(requestPrxoy, resp);
    }
}

监听器

监听器的介绍

  • 监听器就是一个实现了特定接口的Java类,这个Java类用来监听另一个Java类的方法调用或者属性改变,当被监听的对象的发生上述的事件后,监听器某个方法就会立即执行
  • Servlet监听器
  • 事件源:request域对象、session域对象、ServletContext域对象
  • 监听器:Servlet三种监听器
  • 绑定:配置web.xml
  • 事件:域对象发生改变
  • 监听器的分类
  • 一类监听器:监听域对象的创建、销毁
  • 二类监听器:监听域对象中的属性变更(属性设置、属性替换、属性移除)
  • 三类监听器:监听域对象的java对象的绑定

一类监听器

  • ServletRequestListener:监听ServletRequest域对象的创建、销毁
  • HttpSessionListener:监听HttpSession域对象的创建、销毁
  • ServletContextListener:监听ServletContext域对象的创建、销毁

二类监听器

  • ServletRequestAttributeListener:监听ServletRequest域对象中属性变更
  • HttpSessionAttributeListener:监听HttpSession域对象中属性变更
  • ServletContextAttributeListener:监听ServletContext域对象中属性变更

三类监听器

  • HttpSessionBindingListener:监听session域中的java对象的状态(绑定和解绑)
  • 绑定:将java对象存储到session域对象
  • 解绑:将java对象从session域对象移除
  • HttpSessionBindingListener监听不需要在web.xml配置

监听器注解开发

  • @WebListener:相当于在web.xml绑定了监听器
@WebListener
public class MyServletContextLIstener implements ServletContextListener {

    @Override
    public void contextInitialized(ServletContextEvent sce) {
        System.out.println("ServletContext创建");
    }

    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        System.out.println("ServletContext销毁");
    }
}

JavaWeb综合案例

  • UserDao
public interface UserDao {

    User login(User user) throws Exception;

    List<User> selectUserList() throws Exception;

    void deleteUserById(Integer id) throws Exception;

    void deleteUsersByIds(List<Integer> list) throws Exception;

    void addUser(User user) throws Exception;

    User selectUserById(Integer id) throws Exception;

    void updateUser(User user) throws Exception;
}
  • UserDaoImpl
public class UserDaoImpl implements UserDao {

//    private QueryRunner queryRunner = new QueryRunner(JDBCUtil.getDataSource());

    @Override
    public User login(User user) throws Exception {
        return new QueryRunner(JDBCUtil.getDataSource()).query("select * from tb_user where username = ? and password = ?" , new BeanHandler<User>(User.class) , user.getUsername() , user.getPassword());
    }

    @Override
    public List<User> selectUserList() throws Exception {
        return new QueryRunner(JDBCUtil.getDataSource()).query("select * from tb_user" , new BeanListHandler<User>(User.class));
    }

    @Override
    public void deleteUserById(Integer id) throws Exception {
        new QueryRunner(JDBCUtil.getDataSource())
                .update("delete from tb_user where id = ?",
                        id);
    }

    @Override
    public void deleteUsersByIds(List<Integer> list) throws Exception {
        for (Integer id : list) {
            deleteUserById(id);
        }
    }

    @Override
    public void addUser(User user) throws Exception {
        new QueryRunner(JDBCUtil.getDataSource())
                .update("insert into tb_user(username ,password) values(?,?)",
                        user.getUsername(),
                        user.getPassword());
    }

    @Override
    public User selectUserById(Integer id) throws Exception {
        return new QueryRunner(JDBCUtil.getDataSource())
                .query("select * from tb_user where id = ?",
                        new BeanHandler<User>(User.class),
                        id);
    }

    @Override
    public void updateUser(User user) throws Exception {
        new QueryRunner(JDBCUtil.getDataSource())
                .update("update tb_user set username = ? , password = ? where id = ?",
                        user.getUsername(),
                        user.getPassword(),
                        user.getId());
    }
  • ShowIndexServlet
@WebServlet(name = "ShowIndexServlet" ,urlPatterns = "/showIndex")
public class ShowIndexServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        User existUser = (User) request.getSession().getAttribute("existUser");
        StringBuffer responseBody = new StringBuffer();
        if (null != existUser) {
            //已经在登录状态
            responseBody.append("欢迎回来~ " + existUser.getUsername());
            responseBody.append(" 注销
"
); //获取用户列表 UserDao userDao = new UserDaoImpl(); try { List<User> userList = userDao.selectUserList(); System.out.println(userList); responseBody.append(""); responseBody.append(""); responseBody.append(""); responseBody.append(""); responseBody.append(""); responseBody.append("");for(User user : userList){//遍历一个User对象,对应就应该有一个tr responseBody.append(""); responseBody.append(""); responseBody.append(""); responseBody.append(""); responseBody.append("");} responseBody.append("
ID账户密码
"+user.getId()+""+user.getUsername()+""+user.getPassword()+"
"
); } catch (Exception e) { e.printStackTrace(); } } else { //不在登录状态 responseBody.append("您还没有登录,请登录
"
); } response.setContentType("text/html;charset=utf-8"); response.getWriter().write(responseBody.toString()); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request,response); } }

你可能感兴趣的:(java,过滤器,session)