JavaWeb学习

1.Javaweb

1.1 静态web

html,css,提供给所有人看的数据始终不会发生变化
缺点:

  • web界面无法动态更新,所有用户看到都是同一个界面
  • 它无法和数据库交互(数据无法持久化,用户无法交互)

1.2 动态web

几乎是所有的网站,提供给所有人看的数据始终会发生变化,每个人在不同的时间不同的地点看到的信息各不相同
技术栈:Servlet/JSP,ASP,PHP
优点:

  • web界面可以动态更新,所有用户看到的都不是同一个界面
  • 它可以和数据库交互(JDBC)

1.3 web服务器

服务器是一种被动的操作,用来处理用户的一些请求和给用户一些响应信息

  • Tomcat
    在其中conf文件夹下中server为核心配置文件,在其中:
    可以配置主机的端口号
    Tomcat的默认端口号为8080
    mysql:3306
    http:80
    https:443
    可以配置主机的名称
    默认的主机名为:localhost -> 127.0.0.1
    默认网站存放的位置为webapps文件夹中(ROOT下的Index.jsp)(该文件夹下的每一个文件夹都是一个程序(网站))
    面试题1:谈谈网站是如何进行访问的
  • 输入一个域名;回车。
    检查本机的 C:\Windows\System32\drivers\etc\hosts配置文件下有没有这个域名的映射
    如果有的话则直接返回对应的ip地址(因此可自己手动修改)
    如果没有的话则去DNS服务器寻找,找到的话就返回,找不到的话就返回找不到

1.4 Http

  • Http(超文本传输协议)是一个简单的请求-相应协议,它通常运行在TCP之上。

    • 文本:html,字符串
    • 超文本:图片,音乐,视频,定位,地图…
    • 端口号为80
  • Https:安全的,端口号为443

  • Http的两个时代:

    • Http1.0:客户端与web服务器连接后,只能获得一个web资源,断开连接
    • Http2.0:客户端与web服务器连接后,可以获得多个web资源。
  • Http请求

    • 请求方式:get,post,head,put,delete
      • get:请求能够携带的参数比较少,大小有限制,会在浏览器的URL地址栏显示数据内容,不安全,但高效
      • post:请求能够携带的参数没有限制,大小没有限制,不会在浏览器的URL地址栏显示数据内容,安全,但不高效
  • Http响应

    • 响应状态码
      • 200:请求响应成功
      • 3xx:请求重定向
        • 重定向:你重新到我给你的新位置去
      • 4xx:找不到资源(404)
      • 5xx:服务器代码错误 (500) 502:网关错误

1.5 Maven

  • 我为什么要学习这个技术?
    在javaweb开发中,需要使用大量的jar包,为了能够让一个东西自动帮我导入和配置这个jar包,由此诞生了Maven
  • 下载maven并安装
  • 配置环境变量
  • 配置阿里云镜像(加速下载速度) (在conf中settings中的mirrors中贴一段代码)
  • 配置本地仓库(在conf中新建一个文件夹并命名maven-repo,然后在settings中贴一行代码,代码中包含上述文件夹的地址)
  • 在IDEA中使用Maven
    • 打开IDEA
    • 创建Maven项目(创建时可以选用Maven的一些模板,若是创建一个Maven Web项目则勾选一个类似 …maven-wepapp的)(也可不采用模板,直接创建,创建完成之后右击项目—>添加框架的支持)
    • 填写G(GroupId,组的名称,通常是公司域名)A(ArtifactId,组内构建的名称,通常是项目名)V(Version 版本号)以及项目所存放位置
    • 如果是选用的Maven模板进行创建,则还需选择Maven文件的位置,核心配置文件的位置,本地仓库的位置(自己放置的地方,直接选取即可)若想避免每次创建时都需要设置这三项,则可以修改全局设置,在初始创建界面的Configue中的设置,设置一下Maven中的那三项位置即可。
  • 在IDEA中配置Tomcat
    • 点击右上角Configuration -> 点击加号 -> 选取Tomcat,进行配置即可
    • 配置时必须要创建一个Artifact,因为访问一个网站必须指定一个文件夹名字,这个需要创建,并可指定网站名称(这个过程叫虚拟地址映射)
    • 配置完成后点击右上角就可启动了,会展示HelloWorld,默认的index.jsp中的内容
  • pom.xml是Maven的核心配置文件
    • 在此文件中可以添加很多依赖,来导入jar包

1.6 Servlet

  • Servlet就是sun公司开发动态web的一门技术

  • Sun在这些API中提供一个接口叫做Servlet,如果要想开发一个Servlet程序,只需完成两个小步骤:

    • 编写一个类,实现Servlet接口
    • 把开发好的Java类部署到web服务器中
  • 实现简单的 HelloServlet

    • Servlet接口sun公司有两个默认的实现类:HttpServlet,

    • 构建一个普通的Maven项目,删掉里面的src目录,在其pom文件中添加servlet依赖。一般都是在项目中建立Module;这个空的工程就是Maven主工程,这样的好处在于,在父工程添加的依赖会继承给所有的子工程。每次创建模块不用重复增添依赖

    • 建立Module后,在父项目核心文件中中会生成代码

          <modules>
              <module>servlet-01</module>
          </modules>
      

      在子项目核心文件中会生成代码

          <parent>
              <artifactId>javaweb-01-servlet</artifactId>
              <groupId>org.example</groupId>
              <version>1.0-SNAPSHOT</version>
          </parent>
      

      子可继承父中的各种依赖

    • Maven环境搭建

      • 修改web.xml为最新
      • 将Maven的结构搭建完整
        • 在main下添加java目录,并标记为“源码 根”
        • 在main下添加resources目录,并标记为“resources 根”
    • 编写一个Servlet程序

      • 编写一个普通类
      • 实现Servlet接口,直接继承HttpServlet
      public class HelloServlet extends HttpServlet {
      
          // 由于get或者post只是请求实现的不同的方式,可以相互调用,业务逻辑都一样;
          @Override
          protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
              System.out.println("进入doGet方法");
              PrintWriter writer = resp.getWriter();
              writer.print("Hello,Servlet");
          }
          @Override
          protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
              doGet(req,resp);
          }
      }
      
      
    • 编写Servlet的映射

      • 为什么需要映射?
        • 我们写的是Java程序,但是需要通过浏览器访问,而浏览器需要连接web服务器,所以我们需要在web服务器中注册我们写的Servlet,并给他一个浏览器能够访问的路径,即映射。
        • 如下面代码,由 /hello 映射到 com.liu.servlet.HelloServlet
        <!-- 注册Servlet -->
        <servlet>
          <servlet-name>hello</servlet-name>
          <servlet-class>com.liu.servlet.HelloServlet</servlet-class>
        </servlet>
        <!-- Servlet的请求路径 -->
        <servlet-mapping>
          <servlet-name>hello</servlet-name>
          <url-pattern>/hello</url-pattern>
        </servlet-mapping>
      
    • 配置Tomcat

      • 右上角进行配置(注意artifact的选取,不同的子web项目选取的artifact不同。每当创建了一个新的web后运行时记得修改!!)
    • 启动

      • 会先通过设置好的名称进入index.jsp页面,再通过/hello进入HelloServlet
  • Servelet的Mapping问题

    • 一个Servlet可以指定一个映射路径

        <servlet-mapping>
          <servlet-name>hello</servlet-name>
          <url-pattern>/hello</url-pattern>
        </servlet-mapping>
      
    • 一个Servlet可以指定多个映射路径

        <servlet-mapping>
          <servlet-name>hello</servlet-name>
          <url-pattern>/hello</url-pattern>
        </servlet-mapping>
        <servlet-mapping>
          <servlet-name>hello</servlet-name>
          <url-pattern>/hello1</url-pattern>
        </servlet-mapping>
        <servlet-mapping>
          <servlet-name>hello</servlet-name>
          <url-pattern>/hello2</url-pattern>
        </servlet-mapping>
        <servlet-mapping>
          <servlet-name>hello</servlet-name>
          <url-pattern>/hello3</url-pattern>
        </servlet-mapping>
      
    • 一个Servlet可以指定通用映射路径( *代表可以输入任意)

        <servlet-mapping>
          <servlet-name>hello</servlet-name>
          <url-pattern>/hello/*</url-pattern>
        </servlet-mapping>
      
    • 默认请求路径 (启动Tomcat会覆盖首页,直接到达此处)

        <servlet-mapping>
          <servlet-name>hello</servlet-name>
          <url-pattern>/*</url-pattern>
        </servlet-mapping>
      
    • 指定一些后缀或者前缀等 (如下为只要以“.liu”结尾就跳转,注意 * 前面不加 “/”)

        <servlet-mapping>
          <servlet-name>hello</servlet-name>
          <url-pattern>*.liu</url-pattern>
        </servlet-mapping>
      
    • 优先级问题

      • 指定了固有的映射路径优先级最高,如果找不到就会走默认的处理请求。(如下,除了输入/hello外,其余均会进入ErrorServlet)
        <servlet>
          <servlet-name>hello</servlet-name>
          <servlet-class>com.liu.servlet.HelloServlet</servlet-class>
        </servlet>
        <servlet>
          <servlet-name>error</servlet-name>
          <servlet-class>com.liu.servlet.ErrorServlet</servlet-class>
        </servlet>
      
        <servlet-mapping>
          <servlet-name>hello</servlet-name>
          <url-pattern>/hello</url-pattern>
        </servlet-mapping>
        <servlet-mapping>
          <servlet-name>error</servlet-name>
          <url-pattern>/*</url-pattern>
        </servlet-mapping>
      
  • ServletContext
    web容器在启动的时候,他会为每个web程序都创建一个对应的ServletContext对象,它代表了当前的web应用

    • 共享数据

      • 所有的Servlet共享ServletContext中保存的数据,在一个Servlet中保存的数据可以在另外一个Servlet中拿到。
      • 如下,在HelloServlet中存数据,在GetServlet中取出,先进入/hello中存数据后,再进入/getc获取数据。
      public class HelloServlet extends HttpServlet {
          @Override
          protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
              ServletContext context = this.getServletContext();   // ctrl + alt + v 自动补全方法返回值
              String username = "刘梦豪";
              context.setAttribute("username",username); // 将一个数据保存在了ServletContext中
          }
      
          @Override
          protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
              doGet(req, resp);
          }
      }
      
      public class GetServlet extends HttpServlet {
          @Override
          protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
              ServletContext context = this.getServletContext();
              String username = (String) context.getAttribute("username");
      
      		// 下面两行代表设置中文显示,防止乱码
              resp.setContentType("text/html"); 
              resp.setCharacterEncoding("utf-8"); 
              resp.getWriter().print("名字:"+username);
          }
      
          @Override
          protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
              doGet(req, resp);
          }
      }
      
      <web-app>
        <display-name>Archetype Created Web Application</display-name>
        <servlet>
          <servlet-name>hello</servlet-name>
          <servlet-class>com.liu.servlet.HelloServlet</servlet-class>
        </servlet>
        <servlet>
          <servlet-name>getc</servlet-name>
          <servlet-class>com.liu.servlet.GetServlet</servlet-class>
        </servlet>
      
        <servlet-mapping>
          <servlet-name>hello</servlet-name>
          <url-pattern>/hello</url-pattern>
        </servlet-mapping>
        <servlet-mapping>
          <servlet-name>getc</servlet-name>
          <url-pattern>/getc</url-pattern>
        </servlet-mapping>
      </web-app>
      
    • 获取初始化参数

      • 在web.xml中配置
       <!-- 配置一些web应用初始化参数 -->
        <context-param>
          <param-name>url</param-name>
          <param-value>jdbc:mysql://localhost:3306/mybatis</param-value>
        </context-param>
      
      public class ServletDemo03 extends HttpServlet {
          @Override
          protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
              ServletContext context = this.getServletContext();
              String url = context.getInitParameter("url"); // 获取初始化参数
              resp.getWriter().print(url);  //输出
          }
      
          @Override
          protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
              doGet(req, resp);
          }
      }
      
    • 请求转发

      public class ServletDemo04 extends HttpServlet {
          @Override
          protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
              ServletContext context = this.getServletContext();
              System.out.println("进入了ServletDemo04");
      //      RequestDispatcher requestDispatcher = context.getRequestDispatcher("/gp"); // 转发的请求路径
      //      requestDispatcher.forward(req,resp); // 调用forward实现请求转发
              // 下面的  "/" 代表当前的web应用
              context.getRequestDispatcher("/gp").forward(req,resp); 
          }
      
          @Override
          protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
              doGet(req, resp);
          }
      }
      
    • 读取资源文件

      • 在resources目录下新建properties文件

      • 在java目录下新建properties文件(通过在pom文件中添加一段build代码,才能被打包到classes路径下,这个路径为classpath)

      • 运行之后,这properties文件会被打包到target下面的classes中

      • 通过文件流可以获取properties文件中的内容

        username=root
        password=123456
        
        public class ServletDemo05 extends HttpServlet {
            @Override
            protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
                InputStream is = this.getServletContext().getResourceAsStream("/WEB-INF/classes/dp.properties");   // 注意路径位置,第一个 / 代表当前web,即servlet-02
        
                Properties prop = new Properties();
                prop.load(is);
                String user = prop.getProperty("username");
                String pwd = prop.getProperty("password");
        
                resp.getWriter().print(user+":"+pwd);
            }
        
            @Override
            protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
                doGet(req, resp);
            }
        }
        
  • HttpServletResponse
    web服务器接收到客户端的http请求,针对这个请求,分别创建一个代表请求的HttpServletRequest对象、代表响应的一个HttpServletResponse对象

    • 如果要获取客户端请求过来的参数:找HttpServletRequest
    • 如果要给客户端响应一些信息:找HttpServletResponse
    • 常见应用
      • 向浏览器输出消息(getwriter)

      • 下载文件

        public class FileServlet extends HttpServlet {
            @Override
            protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
                // 1. 要获取下载文件的路径
                String realPath = "D:\\all_Java_Project_Code\\javaweb-01-servlet\\response\\src\\main\\resources\\刘梦豪.jpg";
                System.out.println("下载文件的路径:"+realPath);
                // 2. 获取下载的文件名
                String fileName = realPath.substring(realPath.lastIndexOf("\\") + 1 );
                // 3. 设置想办法让浏览器能够支持(Content-Dispositon)下载我们需要的东西,中文文件名URLEncoder.encode编码,否则有可能乱码
                resp.setHeader("Content-Disposition", "attachment;filename="+ URLEncoder.encode(fileName,"UTF-8"));
                // 4. 获取下载文件的输入流
                FileInputStream in = new FileInputStream(realPath);
                // 5. 创建缓冲区
                int len = 0;
                byte[] buffer = new byte[1024];
                // 6. 获取OutputStream对象
                ServletOutputStream out = resp.getOutputStream();
                // 7. 将FileOutputStream流写入到buffer缓冲区,使用OutputStream将缓冲区中的数据输出到客户端
                while((len=in.read(buffer)) > 0)
                {
                    out.write(buffer, 0, len);
                }
                in.close();
                out.close();
            }
            @Override
            protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
                doGet(req, resp);
            }
        }
        
      • 验证码功能

        public class ImageServlet extends HttpServlet {
            @Override
            protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
                // 如何让浏览器3秒自动刷新一次
                resp.setHeader("refresh","3");
                // 在内存中创建一个图片
                BufferedImage image = new BufferedImage(80,20,BufferedImage.TYPE_INT_RGB);
                // 得到图片
                Graphics2D g = (Graphics2D) image.getGraphics(); // 得到画笔
                // 设置图片的背景颜色
                g.setColor(Color.white);
                g.fillRect(0,0,80,20);  //背景为长方形
                // 给图片写数据
                g.setColor(Color.BLUE);
                g.setFont(new Font(null,Font.BOLD,20));
                g.drawString(makeNum(), 0, 20);
                // 告诉浏览器,这个请求用图片的方式打开
                resp.setContentType("image/jpeg");
                // 网站存在缓存,不让浏览器缓存
                resp.setDateHeader("expires",-1);
                resp.setHeader("Cache-Control","no-cache");
                resp.setHeader("Progma","no-cache");
                // 把图片写给浏览器
                ImageIO.write(image,"jpg",resp.getOutputStream());
            }
        
            private String makeNum(){
                Random random = new Random();
                String num = random.nextInt(9999999)+"";
                StringBuffer sb = new StringBuffer();
                for(int i=0;i<7-num.length();i++){
                    sb.append("0");
                }
                return sb.toString()+num;
            }
        
            @Override
            protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
                doGet(req, resp);
            }
        }
        
      • 实现重定向

        • 一个web资源收到客户端请求后,他会通知客户端去访问另外一个web资源,这个过程叫重定向

        • 与请求转发的区别:

          • 请求转发是A向B发送请求,B代替A去找到C然后返回给A,整个过程地址栏地址输入的B,始终是B,即URL地址栏不会发生变化。
          • 重定向是A向B发送请求,B给A发送C的位置,A再去找C,整个过程地址栏地址输入的B,然后变成C,即URL地址栏会发生变化。
          public class RedirectServlet extends HttpServlet {
              @Override
              protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
                  // getContextPath() 返回当前页面所在web项目的路径
                  resp.sendRedirect(req.getContextPath()+"/image"); // 重定向到image页面
              }
              @Override
              protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
                  doGet(req, resp);
              }
          }
          
        • 由index.jsp页面 -> requestServlet,再通过重定向进入success.jsp页面

          <html>
          <body>
          <h2>Hello World!</h2>
          <%@page pageEncoding="UTF-8"%>
          <%--  ${pageContext.request.contextPath} 代表当前的项目  --%>
          <form action="${pageContext.request.contextPath}/login" method="get">
              用户名: <input type="text" name="username"> <br>
              密码: <input type="password" name="password"> <br>
              <input type="submit">
          </form>
          
          </body>
          </html>
          
          
          public class RequestServlet extends HttpServlet {
              @Override
              protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
                  //处理请求,获取传过来的参数
                  String username = req.getParameter("username");
                  String password = req.getParameter("password");
                  System.out.println(username+":"+password);
          
                  // 重定向
                  resp.sendRedirect(req.getContextPath()+"/success.jsp");
              }
          
              @Override
              protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
                  doGet(req, resp);
              }
          }
          
  • HttpServletRequest

    • HttpServletRequest代表客户端的请求,用户通过Http协议访问服务器,Http请求中的所有信息会被封装到HttpServletRequest,通过这个HttpServletRequest的方法,获得客户端的所有信息。

    • 获取前端传递的参数与请求转发(index.jsp->LoginServlet->succ)

      <%@ page contentType="text/html;charset=UTF-8" language="java" %>
      <html>
      <head>
          <title>登录</title>
      </head>
      <body>
      <h1>登录</h1>
      
      <div>
          <form action="${pageContext.request.contextPath}/login" method="post">
              用户名:<input type="text" name="username"> <br>
              密码:<input type="password" name="password"> <br>
              爱好:
              <input type="checkbox" name="hobbys" value="女孩">女孩
              <input type="checkbox" name="hobbys" value="代码">代码
              <input type="checkbox" name="hobbys" value="唱歌">唱歌
              <input type="checkbox" name="hobbys" value="电影">电影
              <br>
              <input type="submit">
          </form>
      </div>
      </body>
      </html>
      
      public class LoginServlet extends HttpServlet {
          @Override
          protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
      
              //后台接收到的数据中文乱码问题
              req.setCharacterEncoding("utf-8");
              resp.setCharacterEncoding("utf-8");
      
              String username = req.getParameter("username");
              String password = req.getParameter("password");
              String[] hobbys = req.getParameterValues("hobbys");
              System.out.println("=============================");
              System.out.println(username);
              System.out.println(password);
              System.out.println(Arrays.toString(hobbys));
              System.out.println("=============================");
      
              System.out.println(req.getContextPath());
              // 通过请求转发
              // 这里的 / 代表当前的web应用,不用再加 req.getContextPath(),这也是与重定向的一点区别。
              req.getRequestDispatcher("/success.jsp").forward(req,resp);
          }
      
          @Override
          protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
              doGet(req, resp);
          }
      }
      

1.7 Cookie Session

  • Cookie、Session
    • 会话:用户打开一个浏览器,点击了很多超链接,访问多个web资源,然后关闭浏览器,这个过程称之为会话
    • 有状态会话:一个同学来过教室,下次再来教室,我们会知道这个同学曾经来过,这就称之为有状态会话
    • 问:一个网站如何证明你来过?
      • 服务端给客户端一个信件,客户端下次访问服务端时带上信件就可以了。(cookie)
      • 服务器端有记录,下次来的时候再次匹配。(session)
    • 保存会话的两种技术
      • cookie
        • 客户端技术,服务器通过响应把cookie发给客户端,客户端通过请求把cookie发给服务器
      • session
        • 服务器技术,利用这个技术,可以保存用户的会话信息。我们可以把数据或信息放在session中
      • 常见:网站登陆过后,下次不用再登录,第二次访问直接就上去了。
    • Cookie
      • 1.从请求中拿到cookie信息

      • 2.服务器响应给客户端cookie

        public class CookieDemo01 extends HttpServlet {
            @Override
            protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
                // 服务器,告诉你,你来的时间,把这个时间封装成一个信件,你下次带来,我就知道你来了
        
                //解决中文乱码
                req.setCharacterEncoding("utf-8");
                resp.setCharacterEncoding("utf-8");
                resp.setContentType("text/html; charset=utf-8"); 
        
                PrintWriter out = resp.getWriter();
                // Cookie,服务器端从客户端获取,因此是req
                Cookie[] cookies = req.getCookies();
                // 判断Cookie是否存在
                if(cookies!=null)
                {
                    // 如果存在
                    out.write("你上一次访问的时间是: ");
                    for (int i=0;i<cookies.length;i++)
                    {
                        Cookie cookie = cookies[i];
                        // 获取cookie的名字
                        if(cookie.getName().equals("lastLoginTime"))
                        {
                            // 获取cookie中的值
                            long lastLoginTime = Long.parseLong(cookie.getValue());
                            Date date = new Date(lastLoginTime);
                            out.write(date.toLocaleString());
                        }
                    }
                }
                else
                {
                    out.write("这是您第一次访问本站");
                }
                //服务器给客户端响应一个Cookie
                Cookie cookie = new Cookie("lastLoginTime",System.currentTimeMillis()+"");
                cookie.setMaxAge(60); // 设置cookie有效期,以秒为单位
                resp.addCookie(cookie);
            }
        
            @Override
            protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
                doGet(req, resp);
            }
        }
        
    • Session(重点)
      • 什么是Session:

        • 服务器会给每一个用户(每一个浏览器)创建一个Session对象
        • 一个Session独占一个浏览器,只要浏览器未关闭,这个Session就存在,用户可访问Session中的信息
      • Session与Cookie的区别

        • Cookie是把用户的数据写给用户的浏览器,浏览器(用户)保存
        • Session是把用户的数据写到用户独占的Session中,服务器端保存,一般用来保存重要的信息
        • Session对象由服务器创建
      • 创建Session

        public class SessionDemo01 extends HttpServlet {
            @Override
            protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
                // 解决乱码问题
                req.setCharacterEncoding("utf-8");
                resp.setCharacterEncoding("utf-8");
                resp.setContentType("text/html;charset=utf-8");
        
                // 得到Session
                HttpSession session = req.getSession();
                // 给Session中存东西
                session.setAttribute("name", new Person("刘梦豪", 1));
                // 获取Session中的ID
                String sessionId = session.getId();
                // 判断Session是不是新创建
                if(session.isNew()){
                    resp.getWriter().write("session创建成功,ID"+sessionId);
                }else{
                    resp.getWriter().write("session已经存在,ID"+sessionId);
                }
            }
        
            @Override
            protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
                doGet(req, resp);
            }
        }
        
      • 获取Session

        public class SessionDemo02 extends HttpServlet {
            @Override
            protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
                // 解决乱码问题
                req.setCharacterEncoding("utf-8");
                resp.setCharacterEncoding("utf-8");
                resp.setContentType("text/html;charset=utf-8");
        
                // 得到Session
                HttpSession session = req.getSession();
                Person person = (Person) session.getAttribute("name");
                System.out.println(person.toString());
            }
        
            @Override
            protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
                doGet(req, resp);
            }
        }
        
      • 手动注销Session

        public class SessionDemo03 extends HttpServlet {
            @Override
            protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        
                HttpSession session = req.getSession();
                session.removeAttribute("name");
                //手动注销Session
                session.invalidate();
            }
        
            @Override
            protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
                doGet(req, resp);
            }
        }
        
      • 在web.xml中设置自动注销Session

            <!-- 设置Session默认的失效时间 -->
            <session-config>
                <!-- 60分钟后Session自动失效,以分钟为单位 -->
                <session-timeout>60</session-timeout>
            </session-config>
        

1.8 JSP

  • JSP
    • 什么是JSP
      • Java Server Pages:Java服务器端页面,也和Servlet一样,用于动态Web技术!
    • 最大的特点:
      • 写JSP就像在写HTML
      • 区别:
        • HTML只给用户提供静态的数据
        • JSP页面中可以嵌入Java代码,为用户提供动态数据
    • JSP本质上就是Servlet,只是简化了很多东西,进行了一定的封装
    • 9大内置对象
      • PageContext (存东西)

      • Request (存东西)

      • Response

      • Session(存东西)

      • Application 【ServletContext】 存东西

      • Config 【ServletConfig】

      • Out

      • Page

      • Exception

        <%-- 内置对象 --%>
        <%
            pageContext.setAttribute("name1","刘1号"); // 保存的数据只在一个页面中有效
            request.setAttribute("name2","刘2号"); // 保存的数据只在一次请求中有效,请求转发会携带这个数据
            session.setAttribute("name3","刘3号"); // 保存的数据只在一次会话中有效,从打开浏览器到关闭浏览器
            application.setAttribute("name4","刘4号"); // 保存的数据只在服务器中有效,从打开服务器到关闭服务器
        %>
        
      • 应用场景

        • request:客户端向服务器发送请求,产生的数据,用户看完就没用了,比如:新闻
        • session:客户端向服务器发送请求,产生的数据,用户用完一会还有用,比如:购物车
        • application:客户端向服务器发送请求,产生的数据,一个用户用完了,其他用户还可能使用,比如:聊天数据
      • pageContextDemo01 -> pageContextDemo02

        <%@ page contentType="text/html;charset=UTF-8" language="java" %>
        <html>
        <head>
            <title>Title</title>
        </head>
        <body>
        <%-- 内置对象 --%>
        <%
            pageContext.setAttribute("name1","刘1号"); // 保存的数据只在一个页面中有效
            request.setAttribute("name2","刘2号"); // 保存的数据只在一次请求中有效,请求转发会携带这个数据
            session.setAttribute("name3","刘3号"); // 保存的数据只在一次会话中有效,从打开浏览器到关闭浏览器
            application.setAttribute("name4","刘4号"); // 保存的数据只在服务器中有效,从打开服务器到关闭服务器
        %>
        <%-- 脚本片段中的代码,会被原封不动生成到java文件
        要求: 这里面的代码,必须保证Java语法的正确性
        --%>
        <%
            //从pageContext取出,通过寻找的方式来
            //从底层到高层(作用域) pageContext->request->session->application
            String name1 = (String) pageContext.findAttribute("name1");
            String name2 = (String) pageContext.findAttribute("name2");
            String name3 = (String) pageContext.findAttribute("name3");
            String name4 = (String) pageContext.findAttribute("name4");
            String name5 = (String) pageContext.findAttribute("name5");
            pageContext.forward("/pageContextDemo02.jsp"); // 请求转发,会发现原来在pageContextDemo02中展示不出来的 "刘2号" 可以展示出来了,因为request转发过程不会丢失数据
        %>
        <%-- 使用EL表达式输出 --%>
        <h1>取出的值为:</h1>
        <h3>${name1}</h3>
        <h3>${name2}</h3>
        <h3>${name3}</h3>
        <h3>${name4}</h3>
        <h3>${name5}</h3>
        </body>
        </html>
        
        
        <%@ page contentType="text/html;charset=UTF-8" language="java" %>
        <html>
        <head>
            <title>Title</title>
        </head>
        <body>
            <%-- 使用EL表达式输出  name1和name2不会展示,只会展示出name3和name4  --%>
            <h1>取出的值为:</h1>
            <h3>${name1}</h3>
            <h3>${name2}</h3>
            <h3>${name3}</h3>
            <h3>${name4}</h3>
            <h3>${name5}</h3>
        </body>
        </html>
        
    • JSP标签、JSTL标签、EL表达式
          <!-- jstl表达式的依赖 -->
          <dependency>
            <groupId>javax.servlet.jsp.jstl</groupId>
            <artifactId>jstl-api</artifactId>
            <version>1.2</version>
          </dependency>
          <!-- standard标签库 -->
          <dependency>
            <groupId>taglibs</groupId>
            <artifactId>standard</artifactId>
            <version>1.1.2</version>
          </dependency>
      
      • EL表达式 : ${}
        • 获取数据
        • 执行运算
        • 获取web开发的常用对象
      • JSP标签
        //请求转发,并携带参数
        <jsp:forward page="/jsptag2.jsp">
            <jsp:param name="name" value="liumenghao"/>
            <jsp:param name="age" value="21"/>
        </jsp:forward>
        
      • JSTL表达式
        • JSTL标签库的使用就是为了弥补HTML标签的不足;它自定义许多标签,可以供我们使用,标签的功能和Java代码一样!

        • JSTL标签库的使用步骤

          • 引入对应的taglib
          • 使用其中的方法
          <body>
              <h4>if测试</h4>
              <hr>
              <form action="coreif.jsp" method="get">
                  <%--
                  EL表达式获取表单中的数据!!!
                  ${param.参数名}
                  --%>
                  <input type="text" name="username" value="${param.username}">
                  <input type="submit" value="登录">
              </form>
          <%-- 判断如果提交的用户名是admin,则登陆成功 --%>
          <%-- java代码形式
          <%
              if(request.getParameter("username").equals("admin")){
                  out.print("登陆成功");
              }
          %>
          --%>
          <%-- test用来进行判断,var用来接收test的返回值 --%>
          <c:if test="${param.username=='admin'}" var="isAdmin">
              <c:out value="登陆成功"></c:out>
          </c:if>
          <c:out value="${isAdmin}"></c:out>
          </body>
          
          <body>
          <%-- 定义一个变量score,值为85 --%>
          <c:set var="score" value="55"></c:set>
          <%-- 类似switch语句,按顺序逐个判断 --%>
          <c:choose>
              <c:when test="${score>=90}">你的成绩优秀</c:when>
              <c:when test="${score>=80}">你的成绩良好</c:when>
              <c:when test="${score>=70}">你的成绩一般</c:when>
              <c:when test="${score>=60}">你的成绩及格</c:when>
              <c:when test="${score<60}">你的成绩不及格</c:when>
          </c:choose>
          </body>
          
          <body>
          <%
              ArrayList<Object> people = new ArrayList<>();
              people.add(0,"张三");
              people.add(1,"李四");
              people.add(2,"王五");
              people.add(3,"赵六");
              people.add(4,"田七");
              request.setAttribute("list",people);
          %>
          
          <%--
          var: 每一次遍历出来的变量
          items: 要遍历的对象
          begin: 开始的下标
          end: 结束的下标
          step: 步长
          --%>
          <c:forEach var="people" items="${list}">
              <c:out value="${people}"></c:out>
          </c:forEach>
          <hr>
          <c:forEach var="people" items="${list}" begin="1" end="3" step="2">
              <c:out value="${people}"></c:out>
          </c:forEach>
          </body>
          

1.9 JavaBean

  • JavaBean
    实体类
    • JavaBean有特定的写法

      • 必须有一个无参构造
      • 属性必须私有化
      • 必须有对应的get/set方法
    • 一般用来和数据库的字段做映射 ORM(对象关系映射)

      • 一个表 --> 一个类
      • 一个字段 --> 一个属性
      • 一行记录 --> 一个对象
      package com.liu.pojo;
      
      public class People {
          private int id;
          private String name;
          private int age;
          private String address;
          public People(){
          }
          public People(int id, String name, int age, String address) {
              this.id = id;
              this.name = name;
              this.age = age;
              this.address = address;
          }
          public void setId(int id) {
              this.id = id;
          }
          public void setName(String name) {
              this.name = name;
          }
          public void setAge(int age) {
              this.age = age;
          }
          public void setAddress(String address) {
              this.address = address;
          }
          public int getId() {
              return id;
          }
          public String getName() {
              return name;
          }
          public int getAge() {
              return age;
          }
          public String getAddress() {
              return address;
          }
          @Override
          public String toString() {
              return "People{" +
                      "id=" + id +
                      ", name='" + name + '\'' +
                      ", age=" + age +
                      ", address='" + address + '\'' +
                      '}';
          }
      }
      
      <%@ page import="com.liu.pojo.People" %>
      <%@ page contentType="text/html;charset=UTF-8" language="java" %>
      <html>
      <head>
          <title>Title</title>
      </head>
      <body>
      <%
      // 与下面等价
      //    People people = new People();
      //    people.setAddress();
      //    people.setId();
      //    people.setAge();
      //    people.setName();
      %>
      
      <jsp:useBean id="people" class="com.liu.pojo.People" scope="page"></jsp:useBean>
      <jsp:setProperty name="people" property="address" value="河南"></jsp:setProperty>
      <jsp:setProperty name="people" property="id" value="1"></jsp:setProperty>
      <jsp:setProperty name="people" property="age" value="21"></jsp:setProperty>
      <jsp:setProperty name="people" property="name" value="刘梦豪"></jsp:setProperty>
      
      <%--
       与下面等价
       <%= people.getAddress()%>
      --%>
      姓名:<jsp:getProperty name="people" property="name"/>
      id:<jsp:getProperty name="people" property="id"/>
      年龄:<jsp:getProperty name="people" property="age"/>
      地址:<jsp:getProperty name="people" property="address"/>
      </body>
      </html>
      

1.10 MVC

  • MVC三层架构
    • Model、View、Controller 模型、视图、控制器

    • 最初时
      在这里插入图片描述

      • 用户直接访问控制层,控制层就可以直接操作数据库
      • Servlet->增删改查->数据库
      • 程序十分臃肿,不利于维护
    • MVC三层架构
      在这里插入图片描述

      • Model
        • 业务处理:业务逻辑(Service层)
        • 数据持久层:增删改查CRUD(Dao层)
      • View
        • 展示数据
        • 提供链接发起Servlet请求(a,form,img…)
      • Controller(Servlet)
        • 接收用户的请求(req:请求参数,Session信息…)
        • 交给业务层处理对应的代码
        • 控制视图的跳转
      • 例:登录—>接受用户的登录请求—>处理用户的请求(获取用户登录的参数,username,password)—>交给业务层处理登录业务(判断用户名密码是否正确)—>Dao层查询用户名和密码是否正确—>数据库

1.11 Filter

  • Filter(重点)
    • 过滤器,用来过滤网站的数据
      • 处理中文乱码
      • 登录验证…
    • 编写过滤器
      • 导包不要错 (implements Filter)(import javax.servlet.*)

      • 实现Filter接口,重写对应的方法即可

        public class CharacterEncodingFilter implements Filter {
            // 初始化:web服务器启动,就已经初始化了,随时等待过滤对象的出现
            public void init(FilterConfig filterConfig) throws ServletException {
                System.out.println("CharacterEncodingFilter初始化");
            }
            // chain: 链
            /*
            1. 过滤中的所有代码,在过滤特定请求的时候都会执行
            2. 必须要让过滤器继续通行
                chain.doFilter(request,response)
             */
            public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
                request.setCharacterEncoding("utf-8");
                response.setCharacterEncoding("utf-8");
                response.setContentType("text/html;charset=utf-8");
        
                System.out.println("CharacterEncodingFilter执行前....");
                chain.doFilter(request,response); //让我们的请求继续走,如果不写,程序到这里就会被拦截停止
                System.out.println("CharacterEncodingFilter执行后....");
            }
            // 销毁:web服务器关闭的时候,过滤会销毁
            public void destroy() {
                System.out.println("CharacterEncodingFilter销毁");
            }
        }
        
      • 在web.xml中进行配置(与配置Servlet基本相同)

        <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
                 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                 xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
                 version="4.0">
            <servlet>
                <servlet-name>ShowServlet</servlet-name>
                <servlet-class>com.liu.servlet.ShowServlet</servlet-class>
            </servlet>
            <servlet-mapping>
                <servlet-name>ShowServlet</servlet-name>
                <url-pattern>/servlet</url-pattern>
            </servlet-mapping>
            <servlet-mapping>
                <servlet-name>ShowServlet</servlet-name>
                <url-pattern>/show</url-pattern>
            </servlet-mapping>
        
            <filter>
                <filter-name>CharacterEncodingFilter</filter-name>
                <filter-class>com.liu.filter.CharacterEncodingFilter</filter-class>
            </filter>
            <filter-mapping>
                <filter-name>CharacterEncodingFilter</filter-name>
                <!-- 只要是 /servlet 开始的任何请求,都会经过这个过滤器 -->
                <url-pattern>/servlet/*</url-pattern>
            </filter-mapping>
        </web-app>
        
    • 例:登陆验证(用户登录之后才能进入主页,用户注销后就不能进入主页了!)
      • 用户登录之后,向Session中放入用户的数据

      • 进入主页的时候要判断用户是否已经登录;要求:在过滤器中实现!

        public class SysFilter implements Filter {
        
            public void init(FilterConfig filterConfig) throws ServletException {}
        
            public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException {
                HttpServletRequest request = (HttpServletRequest) req;
                HttpServletResponse response = (HttpServletResponse) resp;
                if(request.getSession().getAttribute(Constant.USER_SESSION)==null){
                    response.sendRedirect("/error.jsp");
                }
                chain.doFilter(req,resp); //这句话是必须的
            }
             public void destroy() {}
        }
        
            <filter>
                <filter-name>SysFilter</filter-name>
                <filter-class>com.liu.filter.SysFilter</filter-class>
            </filter>
            <filter-mapping>
                <filter-name>SysFilter</filter-name>
                <!-- 只要是 /sys 开始的任何请求,都会经过这个过滤器 -->
                <url-pattern>/sys/*</url-pattern>
            </filter-mapping>
        
        • 登陆界面
          <%@ page contentType="text/html;charset=UTF-8" language="java" %>
          <html>
          <head>
              <title>Title</title>
          </head>
          <body>
          <form action="/servlet/login" method="post">
              <input type="text" name="username">
              <input type="submit">
          </form>
          </body>
          </html>
          
        • 登陆成功后会向Session中写数据
          public class LoginServlet extends HttpServlet {
              @Override
              protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
                  String username = req.getParameter("username");
                  System.out.println("进来了");
                  if ("admin".equals(username)){ //登陆成功
                      req.getSession().setAttribute("USER_SESSION", req.getSession().getId());
                      resp.sendRedirect("/sys/success.jsp");
                  }else{ //登陆失败
                      resp.sendRedirect("/error.jsp");
                  }
              }
          
              @Override
              protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
                  doGet(req, resp);
              }
          }
          
        • 由于有过滤器的缘故,因此在未登录成功之前,不可能直接访问到/sys/success.jsp界面

1.12 监听器

  • 监听器
    • GUI编程中经常使用
    • 编写一个监听器步骤
      • 实现监听器的接口
      • 在web.xml中注册监听器

1.13 JDBC

  • JDBC
    • 导入数据库依赖

              <!-- 连接数据库 -->
              <dependency>
                  <groupId>mysql</groupId>
                  <artifactId>mysql-connector-java</artifactId>
                  <version>5.1.47</version>
              </dependency>
      
    • IDEA中连接数据库

      • 点击Database->点击加号->Data Source->MySQL->输入密码->在schemas中选择数据库->应用
    • JDBC固定步骤

      • 加载驱动

      • 连接数据库

      • 获取向数据库发送SQL的对象Statement(不安全)

      • 编写SQL(根据业务,不同的SQL)

      • 执行SQL

      • 关闭连接

        public class TestJdbc {
            public static void main(String[] args) throws ClassNotFoundException, SQLException {
                // 配置信息
                // useUnicode=true&characterEncoding=utf-8 解决中文乱码
                String url="jdbc:mysql://localhost:3306/jdbc?useUnicode=true&characterEncoding=utf-8";
                String username = "root";
                String passowrd = "root";
        
                //1.加载驱动
                Class.forName("com.mysql.jdbc.Driver");
                //2.连接数据库,代表数据库
                Connection connection = DriverManager.getConnection(url, username, passowrd);
                //3.获取向数据库发送SQL的对象Statement:
                Statement statement = connection.createStatement();
                //4.编写SQL
                String sql = "select * from users";
                //5.执行查询SQL,返回一个ResultSet:结果集;增删改的话为executeUpdate,返回更新的行数
                ResultSet rs = statement.executeQuery(sql);
        
                while(rs.next()){
                    System.out.println("id="+rs.getObject("id"));
                    System.out.println("name="+rs.getObject("name"));
                    System.out.println("password="+rs.getObject("password"));
                    System.out.println("email="+rs.getObject("email"));
                    System.out.println("birthday="+rs.getObject("birthday"));
                }
                //6.关闭连接,释放资源(一定要做) 先打开的后关
                rs.close();
                statement.close();
                connection.close();
            }
        }
        
    • 更安全的步骤(采用PreparedStatement)

      • 加载驱动

      • 连接数据库

      • 编写SQL(根据业务,不同的SQL)

      • PreparedStatement预编译

      • 执行SQL

      • 关闭连接

        public class TestJdbc2 {
            public static void main(String[] args) throws ClassNotFoundException, SQLException {
                // 配置信息
                // useUnicode=true&characterEncoding=utf-8 解决中文乱码
                String url="jdbc:mysql://localhost:3306/jdbc?useUnicode=true&characterEncoding=utf-8";
                String username = "root";
                String passowrd = "root";
        
                //1.加载驱动
                Class.forName("com.mysql.jdbc.Driver");
                //2.连接数据库,代表数据库
                Connection connection = DriverManager.getConnection(url, username, passowrd);
                //3.编写SQL
                String sql = "insert into users(id, name, password, email, birthday) values (?,?,?,?,?)";
                //4.预编译
                PreparedStatement preparedStatement = connection.prepareStatement(sql);
                preparedStatement.setInt(1,4); // 给第一个占位符? 的值赋值为4,下面以此类推
                preparedStatement.setString(2,"赵六");
                preparedStatement.setString(3,"123456");
                preparedStatement.setString(4,"5454455@qq.com");
                preparedStatement.setString(5,"2000-01-02");
                //5.执行SQL
                int i = preparedStatement.executeUpdate();
                if(i>0){
                    System.out.println("插入成功!");
                }
                //6.关闭连接,释放资源(一定要做) 先打开的后关
                preparedStatement.close();
                connection.close();
            }
        }
        
    • 事务

      • 操作要么全做,要么全部做
      • ACID原则:保证数据的安全
      • 开启事务
      • 事务提交 commit()
      • 事务回滚 rollback()
      • 关闭事务
    • Junit单元测试

      • 依赖
                <!-- 单元测试 -->
                <dependency>
                    <groupId>junit</groupId>
                    <artifactId>junit</artifactId>
                    <version>4.12</version>
                </dependency>
        
      • 简单使用
        @Test方法只有在方法上有效,只要加了这个注解的方法,就可以直接运行!
            @Test
            public void test()
            {
                System.out.println("Hello");
            }
        
    • 事务测试

      public class TestJdbc3 {
          @Test
          public void test()
          {
              // 配置信息
              // useUnicode=true&characterEncoding=utf-8 解决中文乱码
              String url="jdbc:mysql://localhost:3306/jdbc?useUnicode=true&characterEncoding=utf-8";
              String username = "root";
              String passowrd = "root";
      
              Connection connection=null;
              //1.加载驱动
              try {
                  Class.forName("com.mysql.jdbc.Driver");
                  //2.连接数据库,代表数据库
                  connection = DriverManager.getConnection(url, username, passowrd);
                  //3.通知数据库开启事务,false为开启
                  connection.setAutoCommit(false);
      
                  String sql = "update account set money=money-100 where name='A'";
                  connection.prepareStatement(sql).executeUpdate();
                  String sql2 = "update account set money=money+100 where name='B'";
                  connection.prepareStatement(sql2).executeUpdate();
                  //4.提交事务
                  connection.commit();
                  System.out.println("success");
      
              } catch (Exception e) {
                  try {
                      // 如果出现异常,就通知数据库回滚事务
                      connection.rollback();
                  } catch (SQLException ex) {
                      ex.printStackTrace();
                  }
                  e.printStackTrace();
              }finally {
                  try {
                      connection.close();
                  } catch (SQLException e) {
                      e.printStackTrace();
                  }
              }
          }
      }
      

1.14 超时订单管理系统SMBMS

  • 超时订单管理系统SMBMS
    • 项目准备工作
      • 搭建一个maven web项目

      • 配置Tomcat

      • 测试项目是否能够跑起来

      • 在pom文件中导入项目中会遇到的jar包:jsp,servlet,mysql驱动,jstl,stand…

          <dependencies>
            <!--servlet与jsp依赖-->
            <dependency>
              <groupId>javax.servlet</groupId>
              <artifactId>servlet-api</artifactId>
              <version>2.5</version>
            </dependency>
            <dependency>
              <groupId>javax.servlet.jsp</groupId>
              <artifactId>javax.servlet.jsp-api</artifactId>
              <version>2.3.3</version>
            </dependency>
            <!--mysql驱动依赖-->
            <dependency>
              <groupId>mysql</groupId>
              <artifactId>mysql-connector-java</artifactId>
              <version>5.1.27</version>
            </dependency>
            <!--jstl依赖与standard标签库-->
            <dependency>
              <groupId>javax.servlet.jsp.jstl</groupId>
              <artifactId>jstl-api</artifactId>
              <version>1.2</version>
            </dependency>
            <dependency>
              <groupId>taglibs</groupId>
              <artifactId>standard</artifactId>
              <version>1.1.2</version>
            </dependency>
            <!-- 单元测试 -->
            <dependency>
              <groupId>junit</groupId>
              <artifactId>junit</artifactId>
              <version>4.12</version>
            </dependency>
          </dependencies>
        
      • 创建项目包结构(com.liu.dao/filter/pojo/service/servlet/util)
        在这里插入图片描述

      • 在pojo中编写实体类:ORM映射:表-类映射
        在这里插入图片描述
        在这里插入图片描述
        在这里插入图片描述
        在这里插入图片描述

      • 编写基础公共类

        • 编写数据库配置文件(db.properties)

          driver=com.mysql.jdbc.Driver
          url=jdbc:mysql://localhost:3306/smbms?useSSL=true&useUnicode=true&characterEncoding=utf-8
          username=root
          password=root
          
        • 编写数据库的公共类(BaseDao)

          package com.liu.dao;
          
          import java.io.IOException;
          import java.io.InputStream;
          import java.sql.*;
          import java.util.Properties;
          
          //操作数据库的公共类
          public class BaseDao {
          
              private static String driver;
              private static String url;
              private static String username;
              private static String password;
          
              //静态代码块,类加载的时候就初始化完了
              static{
                  Properties properties = new Properties();
                  //通过类加载器读取对应的资源
                  InputStream is = BaseDao.class.getClassLoader().getResourceAsStream("db.properties");
                  try {
                      properties.load(is);
                  } catch (IOException e) {
                      e.printStackTrace();
                  }
          
                  driver=properties.getProperty("driver");
                  url=properties.getProperty("url");
                  username=properties.getProperty("username");
                  password=properties.getProperty("password");
              }
          
              //获取数据库的连接
              public static Connection getConnection(){
                  Connection connection=null;
                  try {
                      Class.forName(driver);
                      connection = DriverManager.getConnection(url, username, password);
                  } catch (Exception e) {
                      e.printStackTrace();
                  }
                  return connection;
              }
          
              //编写查询公共方法
              public static ResultSet execute(Connection connection, PreparedStatement preparedStatement, ResultSet resultSet, String sql, Object[] params) throws SQLException {
                  //预编译的sql,在后面直接执行就可以了
                  preparedStatement=connection.prepareStatement(sql);
                  for (int i = 0; i < params.length; i++) {
                      preparedStatement.setObject(i+1, params[i]);
                  }
                  resultSet=preparedStatement.executeQuery();
                  return resultSet;
              }
          
              //编写增删改公共方法
              public static int execute(Connection connection,String sql,Object[] params,PreparedStatement preparedStatement) throws SQLException {
                  preparedStatement = connection.prepareStatement(sql);
                  for (int i = 0; i < params.length; i++) {
                      preparedStatement.setObject(i+1,params[i]);
                  }
                  int updateRows = preparedStatement.executeUpdate();
                  return updateRows;
              }
          
              //释放资源
              public static boolean closeResource(Connection connection,PreparedStatement preparedStatement,ResultSet resultSet){
                  boolean flag = true;
          
                  if (resultSet!=null){
                      try {
                          resultSet.close();
                          //GC回收
                          resultSet = null;
                      } catch (SQLException e) {
                          e.printStackTrace();
                          flag = false;
                      }
                  }
          
                  if (preparedStatement!=null){
                      try {
                          preparedStatement.close();
                          //GC回收
                          preparedStatement = null;
                      } catch (SQLException e) {
                          e.printStackTrace();
                          flag = false;
                      }
                  }
          
                  if (connection!=null){
                      try {
                          connection.close();
                          //GC回收
                          connection = null;
                      } catch (SQLException e) {
                          e.printStackTrace();
                          flag = false;
                      }
                  }
                  return flag;
              }
          
          }
          
          
        • 编写字符编码过滤器(CharacterEncodingFilter)

          package com.liu.filter;
          
          import javax.servlet.*;
          import java.io.IOException;
          
          public class CharaterEncodingFilter implements Filter {
              public void init(FilterConfig filterConfig) throws ServletException {
          
              }
          
              public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException {
                  req.setCharacterEncoding("utf-8");
                  resp.setCharacterEncoding("utf-8");
                  chain.doFilter(req,resp);
              }
          
              public void destroy() {
          
              }
          }
          
          
      • 导入静态资源(css,js,html,img)

    • 登录功能的实现
      在这里插入图片描述
      • 编写登陆界面login.jsp

        <%@ page language="java" contentType="text/html; charset=UTF-8"
            pageEncoding="UTF-8"%>
        <html>
        <head lang="en">
            <meta charset="UTF-8">
            <title>系统登录 - 超市订单管理系统</title>
            <link type="text/css" rel="stylesheet" href="${pageContext.request.contextPath }/css/style.css" />
            <script type="text/javascript">
        	/* if(top.location!=self.location){
        	      top.location=self.location;
        	 } */
            </script>
        </head>
        <body class="login_bg">
            <section class="loginBox">
                <header class="loginHeader">
                    <h1>超市订单管理系统</h1>
                </header>
                <section class="loginCont">
        	        <form class="loginForm" action="${pageContext.request.contextPath }/login.do"  name="actionForm" id="actionForm"  method="post" >
        				<div class="info">${error }</div>
        				<div class="inputbox">
                            <label >用户名:</label>
        					<input type="text" class="input-text" id="userCode" name="userCode" placeholder="请输入用户名" required/>
        				</div>	
        				<div class="inputbox">
                            <label >密码:</label>
                            <input type="password" id="userPassword" name="userPassword" placeholder="请输入密码" required/>
                        </div>	
        				<div class="subBtn">
        					
                            <input type="submit" value="登录"/>
                            <input type="reset" value="重置"/>
                        </div>	
        			</form>
                </section>
            </section>
        </body>
        </html>
        
      • 将登录页面设置为首页,在web.xml中加入这段话

            <!-- 设置欢迎页面 -->
            <welcome-file-list>
                <welcome-file>login.jsp</welcome-file>
            </welcome-file-list>
        
      • 编写dao层用户登录的接口UserDao
        在dao中建立一个user包,在包中建一个UserDao接口,在接口中写

        package com.liu.dao.user;
        
        import com.liu.pojo.User;
        
        import java.sql.Connection;
        import java.sql.SQLException;
        
        public interface UserDao {
            public User getLoginUser(Connection connection, String userCode, String userPassword) throws SQLException;
        
        }
        
        
      • 编写UserDao接口的实现类UserDaoImpl

        package com.liu.dao.user;
        
        import com.liu.dao.BaseDao;
        import com.liu.pojo.User;
        
        import java.sql.Connection;
        import java.sql.PreparedStatement;
        import java.sql.ResultSet;
        import java.sql.SQLException;
        
        public class UserDaoImpl implements UserDao {
            //得到要登录的用户
            public User getLoginUser(Connection connection, String userCode, String userPassword) throws SQLException {
                PreparedStatement pstm = null;
                ResultSet rs = null;
                User user = null;
        
                if (connection!=null){
                    String sql = "select * from smbms_user where userCode=?";
                    Object[] params = {userCode};
                    //System.out.println(userPassword);
                    rs = BaseDao.execute(connection,pstm,rs,sql,params);
                    if (rs.next()){
                        user = new User();
                        user.setId(rs.getInt("id"));
                        user.setUserCode(rs.getString("userCode"));
                        user.setUserName(rs.getString("userName"));
                        user.setUserPassword(rs.getString("userPassword"));
                        user.setGender(rs.getInt("gender"));
                        user.setBirthday(rs.getDate("birthday"));
                        user.setPhone(rs.getString("phone"));
                        user.setAddress(rs.getString("address"));
                        user.setUserRole(rs.getInt("userRole"));
                        user.setCreatedBy(rs.getInt("createdBy"));
                        user.setCreationDate(rs.getTimestamp("creationDate"));
                        user.setModifyBy(rs.getInt("modifyBy"));
                        user.setModifyDate(rs.getTimestamp("modifyDate"));
                    }
              	  if(!user.getUserPassword().equals(userPassword))
            		user=null;
                    BaseDao.closeResource(null,pstm,rs);
                }
                return user;
            }
        }
        
        
      • 编写业务层接口
        在service下建立user包,建立UserService接口

        package com.liu.service.user;
        
        import com.liu.pojo.User;
        
        public interface UserService {
            //用户登录
            public User login(String userCode, String password);
        }
        
      • 编写业务层接口的实现类
        在service的user包中建立UserServiceImpl类

        package com.liu.service.user;
        
        import com.liu.dao.BaseDao;
        import com.liu.dao.user.UserDao;
        import com.liu.dao.user.UserDaoImpl;
        import com.liu.pojo.User;
        import org.junit.Test;
        
        import java.sql.Connection;
        import java.sql.SQLException;
        
        public class UserServiceImpl implements UserService {
        
            //业务层都会调用dao层,所以我们要引入Dao层;
            private UserDao userDao;
            public UserServiceImpl(){
                userDao = new UserDaoImpl();
            }
        
            public User login(String userCode, String password) {
                Connection connection = null;
                User user = null;
        
                try {
                    connection = BaseDao.getConnection();
                    //通过业务层调用对应的具体的数据库操作
                    user = userDao.getLoginUser(connection, userCode,password);
                } catch (SQLException e) {
                    e.printStackTrace();
                }finally {
                    BaseDao.closeResource(connection,null,null);
                }
                return user;
            }
        //    @Test
        //    public void test(){
        //        UserServiceImpl userService = new UserServiceImpl();
        //        User login = userService.login("test", "111");
        //        System.out.println(login.getUserPassword());
        //    }
        
        }
        
      • 编写Servlet类
        在Servlet包中创建user包,在user包中建立LoginServlet类

        package com.liu.servlet.user;
        
        import com.liu.pojo.User;
        import com.liu.service.user.UserService;
        import com.liu.service.user.UserServiceImpl;
        import com.liu.util.Constants;
        
        import javax.servlet.ServletException;
        import javax.servlet.http.HttpServlet;
        import javax.servlet.http.HttpServletRequest;
        import javax.servlet.http.HttpServletResponse;
        import java.io.IOException;
        
        public class LoginServlet extends HttpServlet {
            //Servlet:控制层,调用业务层代码
        
            @Override
            protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        
                System.out.println("LoginServlet--start....");
                //获取用户名和密码
                String userCode = req.getParameter("userCode");
                String userPassword = req.getParameter("userPassword");
                //和数据库中的密码进行对比,调用业务层;
                UserService userService = new UserServiceImpl();
                User user = userService.login(userCode, userPassword);  //这里已经把登录的人给查出来了
                System.out.println(userCode);
                System.out.println(userPassword);
                System.out.println(user.getUserCode());
                System.out.println(user.getUserPassword());
                if (user!=null){ //查有此人,可以登录
                    //将用户的信息放到Session中;
                    req.getSession().setAttribute(Constants.USER_SESSION,user);
                    //跳转到主页重定向
                    resp.sendRedirect("jsp/frame.jsp");
                }else {//查无此人,无法登录
                    //转发回登录页面,顺带提示它,用户名或者密码错误;
                    req.setAttribute("error","用户名或者密码不正确");
                    req.getRequestDispatcher("login.jsp").forward(req,resp);
                }
            }
        
            @Override
            protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
                doGet(req, resp);
            }
        }
        
      • 在web.xml中注册当前的Servlet

            <!--    注册登录页面的Servlet-->
            <servlet>
                <servlet-name>login</servlet-name>
                <servlet-class>com.liu.servlet.user.LoginServlet</servlet-class>
            </servlet>
            <servlet-mapping>
                <servlet-name>login</servlet-name>
                <url-pattern>/login.do</url-pattern>
            </servlet-mapping>
        
    • 登录功能的优化
      • 注销功能
        • 移除session,返回登录页面,servlet.user下创建LogoutServlet类

          package com.liu.servlet.user;
          
          import com.liu.util.Constants;
          
          import javax.servlet.ServletException;
          import javax.servlet.http.HttpServlet;
          import javax.servlet.http.HttpServletRequest;
          import javax.servlet.http.HttpServletResponse;
          import java.io.IOException;
          
          public class LogoutServlet  extends HttpServlet {
              @Override
              protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
                  //移除用户的session
                  req.getSession().removeAttribute(Constants.USER_SESSION);
                  //req.getContextPath() 看情况是否加,一般报404就加
                  resp.sendRedirect(req.getContextPath()+"/login.jsp"); //返回登录页面
              }
          
              @Override
              protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
                  doGet(req, resp);
              }
          }
          
        • 在web.xml中注册注销servlet

              <!-- 注册注销页面 -->
              <servlet>
                  <servlet-name>LogoutServlet</servlet-name>
                  <servlet-class>com.liu.servlet.user.LogoutServlet</servlet-class>
              </servlet>
              <servlet-mapping>
                  <servlet-name>LogoutServlet</servlet-name>
                  <url-pattern>/jsp/logout.do</url-pattern>
              </servlet-mapping>
          
      • 登录拦截器
        • 在filter下创建SysFilter类

          package com.liu.filter;
          
          import com.liu.pojo.User;
          import com.liu.util.Constants;
          
          import javax.servlet.*;
          import javax.servlet.http.HttpServletRequest;
          import javax.servlet.http.HttpServletResponse;
          import java.io.IOException;
          
          public class SysFilter implements Filter {
              public void init(FilterConfig filterConfig) throws ServletException {
              }
              public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException {
                  HttpServletRequest request = (HttpServletRequest) req;
                  HttpServletResponse response = (HttpServletResponse) resp;
          
                  //过滤器,从Session中获取用户,
                  User user = (User) request.getSession().getAttribute(Constants.USER_SESSION);
          
                  if (user==null){ //已经被移除或者注销了,或者未登录
                      response.sendRedirect("/smbms/error.jsp");
                  }else {
                      chain.doFilter(req,resp);
                  }
              }
              public void destroy() {
              }
          }
          
        • 在web.xml中注册

              <!-- 登录拦截器 -->
              <filter>
                  <filter-name>Sysfilter</filter-name>
                  <filter-class>com.liu.filter.SysFilter</filter-class>
              </filter>
              <filter-mapping>
                  <filter-name>Sysfilter</filter-name>
                  <url-pattern>/jsp/*</url-pattern>
              </filter-mapping>
          
    • 密码修改
      • 自顶向下设计,自底向上实现

      • 为了实现这个功能需要自底向上逐一实现功能,修改密码需要更新数据库的相关行,所以这就需要dao层去进行增删改查操作数据

      • Dao层需要当前的一些信息,比如用户名,当前的密码,要修改的密码,这些就要dao层去从Service层获取这些参数

      • Service需要获取从Servlet层传过来的数据进行相应的处理,验证,核算,然后将最终的信息传递给Dao层

      • 而Servlet直接与前端接触,返回当前页面上传递而来的用户输入触发的参数,转发到不同的页面,交给不同的Service来处理这些请求

      • 这就意味着先从dao层开始写,分模块,先写接口,再写接口的实现类,依次写service和servlet,最后注册这个servlet,最后测试并完善前端页面

      • 编写dao层用户修改密码的接口UserDao
        在UserDao的接口下增加updatepwd

            //修改当前用户密码
            //增删改都会影响数据库的变化,所以是返回int类型,说明有几行受到了影响
            public int updatePwd(Connection connection,int id,String userPassword)throws SQLException;
        
      • 编写dao层用户修改密码的接口实现方法
        在UserDaoImpl下增加

            //修改当前用户密码
            //增删改都会影响数据库的变化,所以是返回int类型,说明有几行受到了影响
            public int updatePwd(Connection connection, int id, String userPassword) throws SQLException {
                int updateRows=0;
                PreparedStatement pstm = null;
                if(connection!=null){
                    String sql="update smbms_user set userPassword=? where id=?";
                    Object []params={userPassword,id};
                    updateRows=BaseDao.execute(connection,pstm,sql,params);
                }
                BaseDao.closeResource(null,pstm,null);
                return updateRows;
            }
        
      • 编写业务层Service的用户修改密码的接口
        UserService下增加

            //根据用户id修改密码
            public boolean updatePwd(int id,String password);
        
      • 编写业务层Service的用户修改密码的接口实现方法
        UserServiceImpl下增加

            //根据用户id修改密码
            //通过返回的参数flag判断是否修改成功
            public boolean updatePwd(int id, String password) {
                boolean flag = false;
                Connection connection = null;
                try{
                    connection = BaseDao.getConnection();
                    if(userDao.updatePwd(connection,id,password) > 0)
                        flag = true;
                }catch (Exception e) {
                    e.printStackTrace();
                }finally{
                    BaseDao.closeResource(connection, null, null);
                }
                return flag;
            }
        
      • 编写修改密码的Servlet类UserServlet

        public class UserServlet extends HttpServlet {
            @Override
            protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
                //实现Servlet复用,实现复用需要提取出方法,然后在doGet函数中调用即可
                String method = req.getParameter("method"); // 获取前端隐藏域中的name
                if(method.equals("savepwd") && method!=null){
                    this.updatePwd(req,resp);
                }
            }
        
            @Override
            protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
                doGet(req, resp);
            }
        
            //在doGet外写复用方法
            public void updatePwd(HttpServletRequest req, HttpServletResponse resp){
                //从session中获得用户id,这里的attribute包括了用户的所用信息
                Object attribute = req.getSession().getAttribute(Constants.USER_SESSION);
                //获得新密码
                String newpassword = req.getParameter("newpassword");
                boolean flag= false;
                //判断是否有这个用户是否存在,以及新密码不为空
                if(attribute!=null && !StringUtils.isNullOrEmpty(newpassword)){
                    UserService userService = new UserServiceImpl();
                    flag = userService.updatePwd(((User) attribute).getId(), newpassword);
                    if (flag) {
                        req.setAttribute(Constants.SYS_MESSAGE,"修改密码成功,请退出后重新登录");
                        //密码修改成功后移除当前session
                        req.getSession().removeAttribute(Constants.USER_SESSION);
                    }else{
                        req.setAttribute(Constants.SYS_MESSAGE,"密码修改失败请重新输入");
                    }
                }else{
                    req.setAttribute(Constants.SYS_MESSAGE,"新密码设置错误请重新输入");
                }
                try {
                    req.getRequestDispatcher("pwdmodify.jsp").forward(req,resp);
                } catch (ServletException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        
      • 在web.xml中注册这个servlet

            <!--    注册UserServlet页面-->
            <servlet>
                <servlet-name>UserServlet</servlet-name>
                <servlet-class>com.liu.servlet.user.UserServlet</servlet-class>
            </servlet>
            <servlet-mapping>
                <servlet-name>UserServlet</servlet-name>
                <url-pattern>/jsp/user.do</url-pattern>
            </servlet-mapping>
        
      • 密码修改的前端页面pwdmodify.jsp

        <%@ page language="java" contentType="text/html; charset=UTF-8"
        	pageEncoding="UTF-8"%>
        <%@include file="/jsp/common/head.jsp"%>
        <div class="right">
                    <div class="location">
                        <strong>你现在所在的位置是:</strong>
                        <span>密码修改页面</span>
                    </div>
                    <div class="providerAdd">
                        <form id="userForm" name="userForm" method="post" action="${pageContext.request.contextPath }/jsp/user.do">
                            <input type="hidden" name="method" value="savepwd">
                            <!--div的class 为error是验证错误,ok是验证成功-->
                            <div class="info">${message}</div>
                            <div class="">
                                <label for="oldPassword">旧密码:</label>
                                <input type="password" name="oldpassword" id="oldpassword" value=""> 
        						<font color="red"></font>
                            </div>
                            <div>
                                <label for="newPassword">新密码:</label>
                                <input type="password" name="newpassword" id="newpassword" value=""> 
        						<font color="red"></font>
                            </div>
                            <div>
                                <label for="rNewPassword">确认新密码:</label>
                                <input type="password" name="rnewpassword" id="rnewpassword" value=""> 
        						<font color="red"></font>
                            </div>
                            <div class="providerAddBtn">
                                <!--<a href="#">保存</a>-->
                                <input type="button" name="save" id="save" value="保存" class="input-button">
                            </div>
                        </form>
                    </div>
                </div>
            </section>
        <%@include file="/jsp/common/foot.jsp" %>
        <script type="text/javascript" src="${pageContext.request.contextPath }/js/pwdmodify.js"></script>
        
    • 使用Ajax优化密码修改(前面的修改密码并没有管旧密码是否正确)
      • 导入阿里巴巴的json包

            <!-- 阿里巴巴的fastjson.jar包 -->
            <!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
            <dependency>
              <groupId>com.alibaba</groupId>
              <artifactId>fastjson</artifactId>
              <version>1.2.62</version>
            </dependency>
        
      • 编写验证旧密码的servlet类,还是servlet方法复用

        	else if(method.equals("pwdmodify") && method!=null){//收到前端发来的请求,根据不同的method值来启动不同的方法应对
                    this.modifyPwd(req,resp);
                        //在下面继续写
        //验证旧密码,session中可以获得旧密码,不需要重复去数据库中寻找
            public void modifyPwd(HttpServletRequest req, HttpServletResponse resp){
                //从session中获得用户的旧密码,这里的attribute包括了用户的所用信息
                Object o = req.getSession().getAttribute(Constants.USER_SESSION);
                //从前端输入的页面中获得输入的旧密码
                String oldpassword = req.getParameter("oldpassword");
                //万能的Map
                Map<String, String> resultMap = new HashMap<String,String>();
                if (o==null){//取到的session为空,意味着session过期了
                    resultMap.put("result","sessionerror");
                }else if (StringUtils.isNullOrEmpty(oldpassword)){//如果输入的旧密码为空
                    resultMap.put("result","error");
                }else{//session不为空,输入的旧密码也不为空,则取出当前旧密码与之比较
                    String userPassword = ((User) o).getUserPassword();
                    if(oldpassword.equals(userPassword)){
                        resultMap.put("result","true");
                    }else {
                        resultMap.put("result","false");
                    }
                }
                try {
                    // 将返回值的格式设置为json格式
                    resp.setContentType("application/json");
                    PrintWriter out = resp.getWriter();
                    // 将map中的值,转换到json,并传回去
                    out.write(JSONArray.toJSONString(resultMap));
                    out.flush();
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        
      • 前端js代码为pwdmodify.js

        	var oldpassword = null;
        	var newpassword = null;
        	var rnewpassword = null;
        	var saveBtn = null;
        	
        	$(function(){
        		oldpassword = $("#oldpassword");
        		newpassword = $("#newpassword");
        		rnewpassword = $("#rnewpassword");
        		saveBtn = $("#save");
        		
        		oldpassword.next().html("*");
        		newpassword.next().html("*");
        		rnewpassword.next().html("*");
        		
        		oldpassword.on("blur",function(){//JQuery失去焦点
        			$.ajax({
        				type:"GET",
        				url:path+"/jsp/user.do",
        				data:{method:"pwdmodify",oldpassword:oldpassword.val()},//data就是ajax传递的参数
        				/*
        				上面这句话等价于path+"/jsp/user.do?method="pwdmodify"&&oldpassword=oldpassword.val()
        				*/
        				dataType:"json",//主流开发都是用JSON实现前后端开发{}
        				success:function(data){
        					if(data.result == "true"){//旧密码正确
        						validateTip(oldpassword.next(),{"color":"green"},imgYes,true);
        					}else if(data.result == "false"){//旧密码输入不正确
        						validateTip(oldpassword.next(),{"color":"red"},imgNo + " 原密码输入不正确",false);
        					}else if(data.result == "sessionerror"){//当前用户session过期,请重新登录
        						validateTip(oldpassword.next(),{"color":"red"},imgNo + " 当前用户session过期,请重新登录",false);
        					}else if(data.result == "error"){//旧密码输入为空
        						validateTip(oldpassword.next(),{"color":"red"},imgNo + " 请输入旧密码",false);
        					}
        				},
        				error:function(data){
        					//请求出错
        					validateTip(oldpassword.next(),{"color":"red"},imgNo + " 请求错误",false);
        				}
        			});
        			
        			
        		}).on("focus",function(){
        			validateTip(oldpassword.next(),{"color":"#666666"},"* 请输入原密码",false);
        		});
        		
        		newpassword.on("focus",function(){
        			validateTip(newpassword.next(),{"color":"#666666"},"* 密码长度必须是大于6小于20",false);
        		}).on("blur",function(){
        			if(newpassword.val() != null && newpassword.val().length > 6
        					&& newpassword.val().length < 20 ){
        				validateTip(newpassword.next(),{"color":"green"},imgYes,true);
        			}else{
        				validateTip(newpassword.next(),{"color":"red"},imgNo + " 密码输入不符合规范,请重新输入",false);
        			}
        		});
        		
        		
        		rnewpassword.on("focus",function(){
        			validateTip(rnewpassword.next(),{"color":"#666666"},"* 请输入与上面一致的密码",false);
        		}).on("blur",function(){
        			if(rnewpassword.val() != null && rnewpassword.val().length > 6
        					&& rnewpassword.val().length < 20 && newpassword.val() == rnewpassword.val()){
        				validateTip(rnewpassword.next(),{"color":"green"},imgYes,true);
        			}else{
        				validateTip(rnewpassword.next(),{"color":"red"},imgNo + " 两次密码输入不一致,请重新输入",false);
        			}
        		});
        		
        		
        		saveBtn.on("click",function(){
        			oldpassword.blur();
        			newpassword.blur();
        			rnewpassword.blur();
        	
        			if(oldpassword.attr("validateStatus") == "true"
        				&&newpassword.attr("validateStatus") == "true"
        				&& rnewpassword.attr("validateStatus") == "true"){
        				if(confirm("确定要修改密码?")){
        					$("#userForm").submit();
        				}
        			}
        			
        		});
        	});
        	```
        
  • 用户管理模块的实现
    流程图
    在这里插入图片描述
    用户列表:根据搜索框和下拉框查询到的列表
    角色列表:下拉框展示的可以勾选的列表(系统管理员,经历,普通员工)
    分页:对查询到的用户列表分页
    • 按照自底向上的流程,编写顺序

      • Dao
      • DaoImpl
      • Service
      • ServiceImpl
      • Servlet
    • 编写分页要用到的工具类

      package com.liu.util;
      
      public class PageSupport {
      	//当前页码-来自于用户输入
      	private int currentPageNo = 1;
      	
      	//总数量(表)
      	private int totalCount = 0;
      	
      	//页面容量
      	private int pageSize = 0;
      	
      	//总页数- totalCount/pageSize(+1)
      	private int totalPageCount = 1;
      
      	public int getCurrentPageNo() {
      		return currentPageNo;
      	}
      
      	public void setCurrentPageNo(int currentPageNo) {
      		if(currentPageNo > 0){
      			this.currentPageNo = currentPageNo;
      		}
      	}
      
      	public int getTotalCount() {
      		return totalCount;
      	}
      
      	public void setTotalCount(int totalCount) {
      		if(totalCount > 0){
      			this.totalCount = totalCount;
      			//设置总页数
      			this.setTotalPageCountByRs();
      		}
      	}
      	public int getPageSize() {
      		return pageSize;
      	}
      
      	public void setPageSize(int pageSize) {
      		if(pageSize > 0){
      			this.pageSize = pageSize;
      		}
      	}
      
      	public int getTotalPageCount() {
      		return totalPageCount;
      	}
      
      	public void setTotalPageCount(int totalPageCount) {
      		this.totalPageCount = totalPageCount;
      	}
      	
      	public void setTotalPageCountByRs(){
      		if(this.totalCount % this.pageSize == 0){
      			this.totalPageCount = this.totalCount / this.pageSize;
      		}else if(this.totalCount % this.pageSize > 0){
      			this.totalPageCount = this.totalCount / this.pageSize + 1;
      		}else{
      			this.totalPageCount = 0;
      		}
      	}
      	
      }
      
    • 获取用户的数量

      • 首先是UserDao接口添加一个函数

      • 然后UserDaoImpl里实现上面接口里新增的函数

            //根据用户输入的名字或者角色id来查询计算用户数量
            public int getUserCount(Connection connection, String userName, int userRole) throws Exception {
                int count=0;
                PreparedStatement pstm = null;
                ResultSet rs=null;
                if (connection!=null) {
                    StringBuffer sql=new StringBuffer();
                    sql.append("select count(1) as count from smbms_user u,smbms_role r where u.userRole=r.id");
                    ArrayList<Object> list = new ArrayList<Object>();//存放可能会放进sql里的参数,就是用来替代?的params
                    if(!StringUtils.isNullOrEmpty(userName)){  //如果姓名搜索框中有姓名
                        sql.append(" and u.username like ?");
                        list.add("%"+userName+"%"); //模糊查询,index:0
                    }
                    if(userRole>0){  // 如果在下拉框中勾选了身份
                        sql.append(" and u.userRole = ?");
                        list.add(userRole); //index:1
                    }
                    Object[] params = list.toArray();//转换成数组
                    System.out.println("当前的sql语句为------------>"+sql); //输出最后完整的sql语句
                    rs = BaseDao.execute(connection, pstm, rs, sql.toString(), params);
                    if(rs.next()){
                        count=rs.getInt("count"); // 从结果集中获取最终的数量
                    }
                    BaseDao.closeResource(null,pstm,rs);
                }
                return count;
            }
        
      • 继续在UserService接口里面增加一个新的函数

      • 接口里新增后,在UserServiceImpl实现这个方法

            //根据条件(用户的查询输入)查询用户记录数
            public int getUserCount(String queryUserName, int queryUserRole) {
                int count=0;
                Connection connection=null;
                try {
                    connection = BaseDao.getConnection();
                    count = userDao.getUserCount(connection, queryUserName, queryUserRole);
                } catch (Exception e) {
                    e.printStackTrace();
                }finally {
                    BaseDao.closeResource(connection, null, null);
                }
                return count;
            }
        
    • 根据输入的条件获取当前的用户列表

      • 首先是UserDao接口添加一个函数

      • 然后UserDaoImpl里实现上面接口里新增的函数

            //通过用户输入的条件查询用户列表
            public List<User> getUserList(Connection connection, String userName, int userRole, int currentPageNo, int pageSize) throws Exception {
                List<User> userList = new ArrayList<User>();
                PreparedStatement pstm=null;
                ResultSet rs=null;
                if(connection!=null){
                    StringBuffer sql = new StringBuffer();
                    sql.append("select u.*,r.roleName as userRoleName from smbms_user u,smbms_role r where u.userRole = r.id");
                    List<Object> list = new ArrayList<Object>(); // 用来存取参数
                    if(!StringUtils.isNullOrEmpty(userName)){
                        sql.append(" and u.userName like ?");
                        list.add("%"+userName+"%");
                    }
                    if(userRole > 0){
                        sql.append(" and u.userRole = ?");
                        list.add(userRole);
                    }
                    //实现分页显示
                    sql.append(" order by creationDate DESC limit ?,?");
                    currentPageNo = (currentPageNo-1)*pageSize;
                    list.add(currentPageNo);
                    list.add(pageSize);
        
                    Object[] params = list.toArray();
                    System.out.println("sql ----> " + sql.toString());
                    rs = BaseDao.execute(connection, pstm, rs, sql.toString(), params);
                    while(rs.next()){
                        User _user = new User();
                        _user.setId(rs.getInt("id"));
                        _user.setUserCode(rs.getString("userCode"));
                        _user.setUserName(rs.getString("userName"));
                        _user.setGender(rs.getInt("gender"));
                        _user.setBirthday(rs.getDate("birthday"));
                        _user.setPhone(rs.getString("phone"));
                        _user.setUserRole(rs.getInt("userRole"));
                        _user.setUserRoleName(rs.getString("userRoleName"));
                        userList.add(_user);
                    }
                    BaseDao.closeResource(null, pstm, rs);
                }
                return userList;
            }
        
      • 继续在UserService接口里面增加一个新的函数

      • 接口里新增后,在UserServiceImpl实现这个方法

            //根据条件查询用户列表
            public List<User> getUserList(String queryUserName, int queryUserRole, int currentPageNo, int pageSize) {
                // TODO Auto-generated method stub
                Connection connection = null;
                List<User> userList = null;
                try {
                    connection = BaseDao.getConnection();
                    userList = userDao.getUserList(connection, queryUserName,queryUserRole,currentPageNo,pageSize);
                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }finally{
                    BaseDao.closeResource(connection, null, null);
                }
                return userList;
            }
        
    • 获取角色列表

      • 首先在dao层新建role目录,下面新建RoleDao接口

      • 然后在dao层role目录下新建RoleDaoImpl实现接口

            public List<Role> getRoleList(Connection connection) throws Exception {
                PreparedStatement pstm=null;
                ResultSet rs=null;
                List<Role> roleList = new ArrayList<Role>();
                if(connection!=null){
                    String sql="select * from smbms_role";
                    Object[] params={};
                    rs = BaseDao.execute(connection, pstm, rs, sql, params);
                    while(rs.next()){
                        Role role = new Role();
                        role.setId(rs.getInt("id"));
                        role.setRoleCode(rs.getString("roleCode"));
                        role.setRoleName(rs.getString("roleName"));
                        roleList.add(role);
                    }
                }
                BaseDao.closeResource(null,pstm,rs);
                return roleList;
            }
        
      • 在service层新建role目录,新建RoleService接口

      • 在service层role目录下,新建RoleServiceImlp接口实现

            public List<Role> getRoleList() {
                Connection connection=null;
                List<Role> roleList=null;
                try {
                    connection= BaseDao.getConnection();
                    roleList = roleDao.getRoleList(connection);
                } catch (Exception e) {
                    e.printStackTrace();
                }finally {
                    BaseDao.closeResource(connection,null,null);
                }
                return roleList;
            }
        
    • 用户管理query模块的Servlet编写

      else if (method.equals("query") && method!=null){ // 用户查询
                  this.query(req,resp);
              }
      //用户管理模块页面查询
          //怎么处理
          public void query(HttpServletRequest req,HttpServletResponse resp) throws ServletException,IOException{
              //接收前端传来的参数
              String queryUserName = req.getParameter("queryname");
              String temp = req.getParameter("queryUserRole"); //从前端传回来的用户角色码不知是否为空或者是有效角色码,所以暂存起来
              String pageIndex = req.getParameter("pageIndex");
              int queryUserRole=0;
      
              //通过UserServiceImpl得到用户列表,用户数
              UserServiceImpl userService = new UserServiceImpl();
      
              //通过RoleServiceImpl得到角色表
              RoleService roleService = new RoleServiceImpl();
      
              List<User> userList=null;//用来存储查询到的用户列表
              List<Role> roleList=null;//用来存储角色列表
              //设置每页显示的页面容量
              int pageSize=Constants.pageSize;
              //设置当前的默认页码
              int currentPageNo=1;
      
      
              //前端传来的参数若不符合查询sql语句,即如果用户不进行设置,值为空会影响sql查询,需要给它们进行一些约束
              if(queryUserName==null){ //这里为空,说明用户没有输入要查询的用户名,则sql语句传值为"",%%,会查询所有记录
                  queryUserName="";
              }
              if(temp!=null && !temp.equals("")){
                  //不为空,说明前端有传来的用户所设置的userCode,更新真正的角色码
                  queryUserRole=Integer.parseInt(temp);//强制转换,前端传递的参数都是默认字符串,要转成int类型
              }
      
              if(pageIndex!=null){//说明当前用户设置了要跳转的页码
                  currentPageNo=Integer.valueOf(pageIndex);
              }
      
              //有了用户名和用户角色后可以开始查询了,所以需要显示当前查询到的总记录条数
              int totalCount = userService.getUserCount(queryUserName, queryUserRole);
      
              //根据总记录条数以及当前每页的页面容量可以算出,一共有几页,以及最后一页的显示条数
              PageSupport pageSupport = new PageSupport();
              pageSupport.setCurrentPageNo(currentPageNo);
              pageSupport.setPageSize(pageSize); //设置一下每页的条目个数
              pageSupport.setTotalCount(totalCount); //设置一下条目总数
      
              //获取可显示的总页数
              int totalPageCount=pageSupport.getTotalPageCount();
      
              //约束首位页,即防止用户输入的页面索引小于1或者大于总页数
              if(currentPageNo<1){
                  currentPageNo=1;
              }else if(currentPageNo>totalPageCount){
                  currentPageNo=totalPageCount;
              }
              //有了,待查询条件,当前页码,以及每页的页面容量后,就可以给出每页的具体显示情况了
              userList = userService.getUserList(queryUserName, queryUserRole, currentPageNo, pageSize);
              roleList = roleService.getRoleList();
      
              //得到了用户表与角色表以及各种经过处理后的参数,都存进req中
              req.setAttribute("userList",userList);
              req.setAttribute("roleList",roleList);
              req.setAttribute("queryUserName", queryUserName);
              req.setAttribute("queryUserRole", queryUserRole);
              req.setAttribute("totalPageCount", totalPageCount);
              req.setAttribute("totalCount", totalCount);
              req.setAttribute("currentPageNo", currentPageNo);
              //将所得到的的所有req参数送回给前端
              req.getRequestDispatcher("userlist.jsp").forward(req,resp);
          }        
      
    • 用户管理模块的增删改查

      • Dao

            //增加用户信息
            public  int add(Connection connection,User user) throws Exception;
        
            //通过用户id删除用户信息
            public int deleteUserById(Connection connection, Integer delId)throws Exception;
        
            //通过userId查看当前用户信息
            public User getUserById(Connection connection, String id)throws Exception;
        
            //修改用户信息
            public int modify(Connection connection, User user)throws Exception;
        
      • DaoImpl

        //增加用户信息
            public int add(Connection connection, User user) throws Exception {
                PreparedStatement pstm=null;
                int updateNum=0;
                if(connection!=null) {
                    String sql = "insert into smbms_user (userCode,userName,userPassword," +
                            "userRole,gender,birthday,phone,address,creationDate,createdBy) " +
                            "values(?,?,?,?,?,?,?,?,?,?)";
                    Object[] params = {user.getUserCode(), user.getUserName(), user.getUserPassword(),
                            user.getUserRole(), user.getGender(), user.getBirthday(),
                            user.getPhone(), user.getAddress(), user.getCreationDate(), user.getCreatedBy()};
                    updateNum = BaseDao.execute(connection, pstm, sql, params);
                    BaseDao.closeResource(null, pstm, null);
                }
                return updateNum;
            }
        
            //根据用户id删除该用户
            public int deleteUserById(Connection connection, Integer delId) throws Exception {
                PreparedStatement pstm=null;
                int deleteNum=0;
                if(connection!=null){
                    String sql="delete from smbms_user where id=?";
                    Object[] params={delId};
                    deleteNum=BaseDao.execute(connection, pstm, sql, params);
                    BaseDao.closeResource(null, pstm,null);
                }
                return deleteNum;
            }
        
            //通过userId查看当前用户信息
            public User getUserById(Connection connection, String id) throws Exception {
                PreparedStatement pstm=null;
                ResultSet rs=null;
                User user = new User();
                if(connection!=null){
                    String sql="select u.*,r.roleName as userRoleName from smbms_user u,smbms_role r where u.id=? and u.userRole = r.id";
                    Object[] params={id};
                    rs = BaseDao.execute(connection, pstm, rs, sql, params);
                    while(rs.next()){
                        user.setId(rs.getInt("id"));
                        user.setUserCode(rs.getString("userCode"));
                        user.setUserName(rs.getString("userName"));
                        user.setUserPassword(rs.getString("userPassword"));
                        user.setGender(rs.getInt("gender"));
                        user.setBirthday(rs.getDate("birthday"));
                        user.setPhone(rs.getString("phone"));
                        user.setAddress(rs.getString("address"));
                        user.setUserRole(rs.getInt("userRole"));
                        user.setCreatedBy(rs.getInt("createdBy"));
                        user.setCreationDate(rs.getTimestamp("creationDate"));
                        user.setModifyBy(rs.getInt("modifyBy"));
                        user.setModifyDate(rs.getTimestamp("modifyDate"));
                        user.setUserRoleName(rs.getString("userRoleName"));
                    }
                    BaseDao.closeResource(null,pstm,rs);
                }
                return user;
            }
        
            //修改用户的信息
            public int modify(Connection connection, User user) throws Exception {
                int updateNum = 0;
                PreparedStatement pstm = null;
                if(null != connection){
                    String sql = "update smbms_user set userName=?,"+
                            "gender=?,birthday=?,phone=?,address=?,userRole=?,modifyBy=?,modifyDate=? where id = ? ";
                    Object[] params = {user.getUserName(),user.getGender(),user.getBirthday(),
                            user.getPhone(),user.getAddress(),user.getUserRole(),user.getModifyBy(),
                            user.getModifyDate(),user.getId()};
                    updateNum = BaseDao.execute(connection, pstm, sql, params);
                    BaseDao.closeResource(null, pstm, null);
                }
                return updateNum;
            }
        
      • Service

            //增加用户
            public boolean add(User user);
        
            //修改用户信息
            public boolean modify(User user) throws Exception;
        
        
            //根据用户id删除用户
            public boolean deleteUserById(Integer delId);
        
            //根据用户id得到当前用户
            public User getUserById(String id);
        
            //根据用户编码,判断用户是否存在
            public User selectUserCodeExist(String userCode, String userPassword);
        
      • ServiceImpl

        //增加用户
            public boolean add(User user) {
                boolean flag = false;
                Connection connection = null;
                try {
                    connection = BaseDao.getConnection();//获得连接
                    connection.setAutoCommit(false);//开启JDBC事务管理
                    int updateRows = userDao.add(connection,user);
                    connection.commit();
                    if(updateRows > 0){
                        flag = true;
                        System.out.println("add success!");
                    }else{
                        System.out.println("add failed!");
                    }
        
                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                    try {
                        System.out.println("rollback==================");
                        connection.rollback();//失败就回滚
                    } catch (SQLException e1) {
                        // TODO Auto-generated catch block
                        e1.printStackTrace();
                    }
                }finally{
                    //在service层进行connection连接的关闭
                    BaseDao.closeResource(connection, null, null);
                }
                return flag;
            }
        
            //修改用户信息
            public boolean modify(User user) {
                Boolean flag=false;
                Connection connection=null;
                try {
                    connection=BaseDao.getConnection();
                    connection.setAutoCommit(false);//开启JDBC事务
                    int updateNum = userDao.modify(connection, user);//执行修改sql
                    connection.commit();//提交事务
                    if(updateNum>0){
                        flag=true;
                        System.out.println("修改用户成功");
                    }else{
                        System.out.println("修改用户失败");
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    //若抛出异常,则说明修改失败需要回滚
                    System.out.println("修改失败,回滚事务");
                    try {
                        connection.rollback();
                    } catch (SQLException e1) {
                        e1.printStackTrace();
                    }
                }finally {
                    BaseDao.closeResource(connection,null,null);
                }
                return flag;
            }
        
        
            public boolean deleteUserById(Integer delId) {
                Boolean flag=false;
                Connection connection=null;
                connection=BaseDao.getConnection();
                try {
                    int deleteNum=userDao.deleteUserById(connection,delId);
                    if(deleteNum>0)flag=true;
                } catch (Exception e) {
                }finally {
                    BaseDao.closeResource(connection,null,null);
                }
                return flag;
            }
        
            public User getUserById(String id) {
                User user = new User();
                Connection connection=null;
                try {
                    connection=BaseDao.getConnection();
                    user = userDao.getUserById(connection,id);
                } catch (Exception e) {
                    e.printStackTrace();
                }finally {
                    BaseDao.closeResource(connection,null,null);
                }
                return  user;
            }
        
            public User selectUserCodeExist(String userCode, String userPassword) {
        
                Connection connection = null;
                User user = null;
                try {
                    connection = BaseDao.getConnection();
                    user = userDao.getLoginUser(connection, userCode, userPassword);
                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }finally{
                    BaseDao.closeResource(connection, null, null);
                }
                return user;
            }
        
      • 增删改查Servlet(放个总的)

        public class UserServlet extends HttpServlet {
            @Override
            protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
                //实现Servlet复用,实现复用需要提取出方法,然后在doGet函数中调用即可
                String method = req.getParameter("method"); // 获取前端隐藏域中的name
                if(method.equals("savepwd") && method!=null){
                    this.updatePwd(req,resp);
                }else if(method.equals("pwdmodify") && method!=null){//收到前端发来的请求,根据不同的method值来启动不同的方法应对
                    this.modifyPwd(req,resp);
                }else if (method.equals("query") && method!=null){ // 用户查询
                    this.query(req,resp);
                }else if(method != null && method.equals("add")){//增加操作
                    this.add(req, resp);
                }else if(method != null && method.equals("deluser")){//删除用户
                    this.delUser(req, resp);
                }else if(method != null && method.equals("modify")){ //通过用户id得到该用户,并跳转到用户修改界面显示该用户信息
                    this.getUserById(req, resp,"usermodify.jsp");
                }else if(method != null && method.equals("modifyexe")){ //验证用户,判断是否修改成功
                    this.modify(req, resp);
                }else if(method != null && method.equals("view")){  //通过用户id得到该用户,并跳转到用户展示界面展示该用户信息
                    this.getUserById(req, resp,"userview.jsp");
                }else if(method != null && method.equals("getrolelist")){ //查询用户角色表
                    this.getRoleList(req, resp);
                }else if(method != null && method.equals("ucexist")){ //查询当前用户编码是否已经存在,若已存在则不能add
                    this.userCodeExist(req, resp);
                }
            }
        
            @Override
            protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
                doGet(req, resp);
            }
        
            //在doGet外写复用方法
            public void updatePwd(HttpServletRequest req, HttpServletResponse resp){
                //从session中获得用户id,这里的attribute包括了用户的所用信息
                Object attribute = req.getSession().getAttribute(Constants.USER_SESSION);
                //获得新密码
                String newpassword = req.getParameter("newpassword");
                boolean flag= false;
                //判断是否有这个用户是否存在,以及新密码不为空
                if(attribute!=null && !StringUtils.isNullOrEmpty(newpassword)){
                    UserService userService = new UserServiceImpl();
                    flag = userService.updatePwd(((User) attribute).getId(), newpassword);
                    if (flag) {
                        req.setAttribute(Constants.SYS_MESSAGE,"修改密码成功,请退出后重新登录");
                        //密码修改成功后移除当前session
                        req.getSession().removeAttribute(Constants.USER_SESSION);
                    }else{
                        req.setAttribute(Constants.SYS_MESSAGE,"密码修改失败请重新输入");
                    }
                }else{
                    req.setAttribute(Constants.SYS_MESSAGE,"新密码设置错误请重新输入");
                }
                try {
                    req.getRequestDispatcher("pwdmodify.jsp").forward(req,resp);
                } catch (ServletException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        
            //在下面继续写
            //验证旧密码,session中可以获得旧密码,不需要重复去数据库中寻找
            public void modifyPwd(HttpServletRequest req, HttpServletResponse resp){
                //从session中获得用户的旧密码,这里的attribute包括了用户的所用信息
                Object o = req.getSession().getAttribute(Constants.USER_SESSION);
                //从前端输入的页面中获得输入的旧密码
                String oldpassword = req.getParameter("oldpassword");
                //万能的Map
                Map<String, String> resultMap = new HashMap<String,String>();
                if (o==null){//取到的session为空,意味着session过期了
                    resultMap.put("result","sessionerror");
                }else if (StringUtils.isNullOrEmpty(oldpassword)){//如果输入的旧密码为空
                    resultMap.put("result","error");
                }else{//session不为空,输入的旧密码也不为空,则取出当前旧密码与之比较
                    String userPassword = ((User) o).getUserPassword();
                    if(oldpassword.equals(userPassword)){
                        resultMap.put("result","true");
                    }else {
                        resultMap.put("result","false");
                    }
                }
                try {
                    // 将返回值的格式设置为json格式
                    resp.setContentType("application/json");
                    PrintWriter out = resp.getWriter();
                    // 将map中的值,转换到json,并传回去
                    out.write(JSONArray.toJSONString(resultMap));
                    out.flush();
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        
            //用户管理模块页面查询
            //怎么处理
            public void query(HttpServletRequest req,HttpServletResponse resp) throws ServletException,IOException{
                //接收前端传来的参数
                String queryUserName = req.getParameter("queryname");
                String temp = req.getParameter("queryUserRole"); //从前端传回来的用户角色码不知是否为空或者是有效角色码,所以暂存起来
                String pageIndex = req.getParameter("pageIndex");
                int queryUserRole=0;
        
                //通过UserServiceImpl得到用户列表,用户数
                UserServiceImpl userService = new UserServiceImpl();
        
                //通过RoleServiceImpl得到角色表
                RoleService roleService = new RoleServiceImpl();
        
                List<User> userList=null;//用来存储查询到的用户列表
                List<Role> roleList=null;//用来存储角色列表
                //设置每页显示的页面容量
                int pageSize=Constants.pageSize;
                //设置当前的默认页码
                int currentPageNo=1;
        
        
                //前端传来的参数若不符合查询sql语句,即如果用户不进行设置,值为空会影响sql查询,需要给它们进行一些约束
                if(queryUserName==null){ //这里为空,说明用户没有输入要查询的用户名,则sql语句传值为"",%%,会查询所有记录
                    queryUserName="";
                }
                if(temp!=null && !temp.equals("")){
                    //不为空,说明前端有传来的用户所设置的userCode,更新真正的角色码
                    queryUserRole=Integer.parseInt(temp);//强制转换,前端传递的参数都是默认字符串,要转成int类型
                }
        
                if(pageIndex!=null){//说明当前用户设置了要跳转的页码
                    currentPageNo=Integer.valueOf(pageIndex);
                }
        
                //有了用户名和用户角色后可以开始查询了,所以需要显示当前查询到的总记录条数
                int totalCount = userService.getUserCount(queryUserName, queryUserRole);
        
                //根据总记录条数以及当前每页的页面容量可以算出,一共有几页,以及最后一页的显示条数
                PageSupport pageSupport = new PageSupport();
                pageSupport.setCurrentPageNo(currentPageNo);
                pageSupport.setPageSize(pageSize); //设置一下每页的条目个数
                pageSupport.setTotalCount(totalCount); //设置一下条目总数
        
                //获取可显示的总页数
                int totalPageCount=pageSupport.getTotalPageCount();
        
                //约束首位页,即防止用户输入的页面索引小于1或者大于总页数
                if(currentPageNo<1){
                    currentPageNo=1;
                }else if(currentPageNo>totalPageCount){
                    currentPageNo=totalPageCount;
                }
                //有了,待查询条件,当前页码,以及每页的页面容量后,就可以给出每页的具体显示情况了
                userList = userService.getUserList(queryUserName, queryUserRole, currentPageNo, pageSize);
                roleList = roleService.getRoleList();
        
                //得到了用户表与角色表以及各种经过处理后的参数,都存进req中
                req.setAttribute("userList",userList);
                req.setAttribute("roleList",roleList);
                req.setAttribute("queryUserName", queryUserName);
                req.setAttribute("queryUserRole", queryUserRole);
                req.setAttribute("totalPageCount", totalPageCount);
                req.setAttribute("totalCount", totalCount);
                req.setAttribute("currentPageNo", currentPageNo);
                //将所得到的的所有req参数送回给前端
                req.getRequestDispatcher("userlist.jsp").forward(req,resp);
            }
        
            //增加用户
            private void add(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
                System.out.println("当前正在执行增加用户操作");
                //从前端得到页面的请求的参数即用户输入的值
                String userCode = req.getParameter("userCode");
                String userName = req.getParameter("userName");
                String userPassword = req.getParameter("userPassword");
                //String ruserPassword = req.getParameter("ruserPassword");
                String gender = req.getParameter("gender");
                String birthday = req.getParameter("birthday");
                String phone = req.getParameter("phone");
                String address = req.getParameter("address");
                String userRole = req.getParameter("userRole");
                //把这些值塞进一个用户属性中
                User user = new User();
                user.setUserCode(userCode);
                user.setUserName(userName);
                user.setUserPassword(userPassword);
                user.setAddress(address);
                user.setGender(Integer.valueOf(gender));
                user.setPhone(phone);
                try {
                    user.setBirthday(new SimpleDateFormat("yyyy-MM-dd").parse(birthday));
                } catch (ParseException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                user.setUserRole(Integer.valueOf(userRole));
                user.setCreationDate(new Date());
                //查找当前正在登陆的用户的id
                user.setCreatedBy(((User)req.getSession().getAttribute(Constants.USER_SESSION)).getId());
                UserServiceImpl userService = new UserServiceImpl();
                Boolean flag = userService.add(user);
                //如果添加成功,则页面转发,否则重新刷新,再次跳转到当前页面
                if(flag){
                    resp.sendRedirect(req.getContextPath()+"/jsp/user.do?method=query");
                }else{
                    req.getRequestDispatcher("useradd.jsp").forward(req,resp);
                }
            }
        
            //删除用户,需要当前的Id,来找到这个用户然后删除
            private void delUser(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{
                String id = req.getParameter("uid");
                Integer delId = 0;
                try{
                    delId = Integer.parseInt(id);
                }catch (Exception e) {
                    // TODO: handle exception
                    delId = 0;
                }
                //需要判断是否能删除成功
                HashMap<String, String> resultMap = new HashMap<String, String>();
                if(delId <= 0){
                    resultMap.put("delResult", "notexist");
                }else{
                    UserService userService = new UserServiceImpl();
                    if(userService.deleteUserById(delId)){
                        resultMap.put("delResult", "true");
                    }else{
                        resultMap.put("delResult", "false");
                    }
                }
        
                //把resultMap转换成json对象输出
                resp.setContentType("application/json");
                PrintWriter outPrintWriter = resp.getWriter();
                outPrintWriter.write(JSONArray.toJSONString(resultMap));
                outPrintWriter.flush();
                outPrintWriter.close();
            }
        
            //通过id得到用户信息
            private void getUserById(HttpServletRequest req, HttpServletResponse resp,String url) throws ServletException, IOException{
        
                String id = req.getParameter("uid");
                if(!StringUtils.isNullOrEmpty(id)){
                    //调用后台方法得到user对象
                    UserService userService = new UserServiceImpl();
                    User user = userService.getUserById(id);
                    req.setAttribute("user", user);
                    req.getRequestDispatcher(url).forward(req, resp);
                }
            }
        
            //修改用户信息
            private void modify(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{
                //需要拿到前端传递进来的参数
                String id = req.getParameter("uid");;
                String userName = req.getParameter("userName");
                String gender = req.getParameter("gender");
                String birthday = req.getParameter("birthday");
                String phone = req.getParameter("phone");
                String address = req.getParameter("address");
                String userRole = req.getParameter("userRole");
        
                //创建一个user对象接收这些参数
                User user = new User();
                user.setId(Integer.valueOf(id));
                user.setUserName(userName);
                user.setGender(Integer.valueOf(gender));
                try {
                    user.setBirthday(new SimpleDateFormat("yyyy-MM-dd").parse(birthday));
                } catch (ParseException e) {
                    e.printStackTrace();
                }
                user.setPhone(phone);
                user.setAddress(address);
                user.setUserRole(Integer.valueOf(userRole));
                user.setModifyBy(((User)req.getSession().getAttribute(Constants.USER_SESSION)).getId());
                user.setModifyDate(new Date());
        
                //调用service层
                UserServiceImpl userService = new UserServiceImpl();
                Boolean flag = userService.modify(user);
        
                //判断是否修改成功来决定跳转到哪个页面
                if(flag){
                    resp.sendRedirect(req.getContextPath()+"/jsp/user.do?method=query");
                }else{
                    req.getRequestDispatcher("usermodify.jsp").forward(req, resp);
                }
            }
        
            //得到用户角色表
            private void getRoleList(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{
                List<Role> roleList = null;
                RoleService roleService = new RoleServiceImpl();
                roleList = roleService.getRoleList();
                //把roleList转换成json对象输出
                resp.setContentType("application/json");
                PrintWriter outPrintWriter = resp.getWriter();
                outPrintWriter.write(JSONArray.toJSONString(roleList));
                outPrintWriter.flush();
                outPrintWriter.close();
            }
        
            //增加用户时,判断当前输入用户编码是否可用,即是否与已经存在的编码发生冲突
            private void userCodeExist(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{
                //先拿到用户的编码
                String userCode = req.getParameter("userCode");
                String userPassword = req.getParameter("userPassword");
                //用一个hashmap,暂存现在所有现存的用户编码
                HashMap<String, String> resultMap = new HashMap<String, String>();
                if(StringUtils.isNullOrEmpty(userCode)){
                    //userCode == null || userCode.equals("")
                    //如果输入的这个编码为空或者不存在,说明可用
                    resultMap.put("userCode", "exist");
                }else{//如果输入的编码不为空,则需要去找一下是否存在这个用户
                    UserService userService = new UserServiceImpl();
                    User user = userService.selectUserCodeExist(userCode, userPassword);
                    if(null != user){
                        resultMap.put("userCode","exist");
                    }else{
                        resultMap.put("userCode", "notexist");
                    }
                }
                //把resultMap转为json字符串以json的形式输出
                //配置上下文的输出类型
                resp.setContentType("application/json");
                //从response对象中获取往外输出的writer对象
                PrintWriter outPrintWriter = resp.getWriter();
                //把resultMap转为json字符串 输出
                outPrintWriter.write(JSONArray.toJSONString(resultMap));
                outPrintWriter.flush();//刷新
                outPrintWriter.close();//关闭流
            }
        }
        
  • 4
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

henulmh

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值