• JAVAEE第三次作业-servlet应用


    JAVAEE第三次作业-servlet应用

    一、任务

    1. 编写一个servlet进行用户名和密码校验,获取登录页面的用户名密码,并显示出来

    2. 使用cookie,如果用户在登录时选择保存登录信息,30天内,用户无需登录

    3. 使用session,显示计科院网站当前在线人数

    4. 使用过滤器解决乱码问题,登录时用户名为中文可能不能正常识别,解决该问题

    二、任务1实验过程

    编写一个servlet进行用户名和密码校验,获取登录页面的用户名密码,并显示出来

    2.1 创建maven项目

    利用IDEA编译器来完成此次实验,为了方便对所用jar包的管理,新建maven项目。

    1591075242628

    2.2 添加框架支持

    右键项目文件,点击Add FrameWork Support

    1591067913639

    选择Web Application

    1591067931343

    添加以后的项目文件结构,其中src目录放入servelet等JAVA类,web目录放html、css、js、imaage等资源

    1591068075039

    2.3 将实验1中的静态资源导入web目录

    1591075608387

    2.4 maven导入相应的jar包

    <!--        servlet-->
            <dependency>
                <groupId>javax.servlet</groupId>
                <artifactId>servlet-api</artifactId>
                <version>2.5</version>
            </dependency>
    
    <!--        jsp-->
            <dependency>
                <groupId>javax.servlet.jsp</groupId>
                <artifactId>javax.servlet.jsp-api</artifactId>
                <version>2.3.3</version>
            </dependency>
    
    <!--        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>
    
    <!-- jdbc mysql -->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>8.0.20</version>
            </dependency>
        </dependencies>
    

    2.5 配置Tomcat服务器

    1591076202322

    2.6 配置web.xml

        <servlet>
            <servlet-name>LoginServlet</servlet-name>
            <servlet-class>servlets.LoginServlet</servlet-class>
        </servlet>
        
        <servlet-mapping>
            <servlet-name>LoginServlet</servlet-name>
            <url-pattern>/login</url-pattern>
        </servlet-mapping>
    

    2.7 创建并连接数据库

    1. Mysql创建数据库
    CREATE DATABASE USERS;
    USE USERS;
    
    CREATE TABLE USERS_INFO (
    	UID VARCHAR(20) NOT NULL,
    	UNAME VARCHAR(20) NOT NULL,
    	UPWD VARCHAR(20) NOT NULL,
    	PRIMARY KEY(UID)
    );
    
    INSERT INTO USERS_INFO VALUES (
    	'111','Sonny','123'
    );
    INSERT INTO USERS_INFO VALUES (
    	'222','Jason','123'
    );
    INSERT INTO USERS_INFO VALUES (
    	'333','Spider','123'
    );
    
    SELECT * FROM USERS_INFO;
    

    1591077268229

    1. JDBC链接数据库并返回查询结果

      此处用到了PreparedStatement,这样写的优点

      • 代码进行批处理,效率更高、
      • 方便阅读,更易于维护
      • 更安全,防止SQL注入
      //使用select语句 返回查询结果
          public static List<User> sqlBySelectMode(String uid, String upwd) throws SQLException, ClassNotFoundException, IOException {
              String url = "jdbc:mysql://localhost:3306/users?useUnicode=true&characterEncoding=utf-8&" +
                      "useSSL=false&serverTimezone=Hongkong";
      
              String username = "root";
              String password = "123";
      
              //1.加载驱动
              Class.forName("com.mysql.cj.jdbc.Driver");
              //2.连接数据库,代表数据库
              Connection connection = DriverManager.getConnection(url, username, password);
      
              //3。编写SQL
              String sql = "SELECT * FROM users_info WHERE uid = ? AND upwd = ?;";
      
              //4.预编译
              PreparedStatement preparedStatement = connection.prepareStatement(sql);
      
              preparedStatement.setString(1, uid);
              preparedStatement.setString(2, upwd);
      
              //5.执行查询SQL,返回一个 ResultSet  : 结果集
              ResultSet rs = preparedStatement.executeQuery();
      
              List<User> userList = new ArrayList<User>();
      
              while (rs.next()) {
                  User user = new User();
                  user.setUid(rs.getObject("uid").toString());
                  user.setUname(rs.getObject("uname").toString());
                  user.setUname(rs.getObject("upwd").toString());
      
                  userList.add(user);
              }
      
              //6.关闭连接,释放资源(一定要做) 先开后关
              rs.close();
              preparedStatement.close();
              connection.close();
      
              return userList;
          }
      

    2.8 创建Servlet并实现用户名密码验证

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html;charset=utf-8");
    
        String username = request.getParameter("username");
        String password = request.getParameter("password");
    
        List<User> userList = null;
    
        try {
            userList = sqlBySelectMode(username, password);
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    
        PrintWriter writer = response.getWriter();
    
        if (userList.size() != 0) {
            writer.println("<h2>登陆成功</h2>");
            writer.println("<h2>账号:" + username + "</h2>");
            writer.println("<h2>密码:" + password + "</h2>");
        } else {
            writer.println("<h2>用户名/密码输入错误,请重新输入!</h2>");
        }
    }
    

    成功/失败登录效果如下:

    1591091662854

    1591091673985

    三、任务2实验过程

    使用cookie,如果用户在登录时选择保存登录信息,30天内,用户无需登录

    3.1 账号登录成功生成Cookie,设置有效时长为30天

        //账号密码输入正确后,保持cookies
        private void setCookies(HttpServletResponse response, String username, String password) {
    
            Cookie usernameCookie = new Cookie("username", username);
            usernameCookie.setMaxAge(30 * 24 * 60 * 60);    //设置cookie有效期为30天
    
            Cookie passwordCookie = new Cookie("password", password);
            passwordCookie.setMaxAge(30 * 24 * 60 * 60);    //设置cookie有效期为30天
    
            //添加cookie到response
            response.addCookie(usernameCookie);
            response.addCookie(passwordCookie);
        }
    

    效果如下:

    1591096050903

    1591096094321

    3.2 下次登陆时,自动获取Cookie

    String username = "";   //用户名
    String password = "";   //用密码
    
    boolean isUsernameCookieOK = false;
    boolean isPasswordCookieOK = false;
    Cookie usernameCookie = null;
    Cookie passwordCookie = null;
    
    Cookie[] cookies = request.getCookies();
    for (Cookie cookie : cookies) {
        if ("username".equals(cookie.getName())) {
            isUsernameCookieOK = true;
            usernameCookie = cookie;
        }
        if ("password".equals(cookie.getName())) {
            isPasswordCookieOK = true;
            passwordCookie = cookie;
        }
        System.out.println(cookie.getName() + ":" + cookie.getValue());
    }
    
    //如果cookies不为空
    if (isUsernameCookieOK && isPasswordCookieOK) {
        username = usernameCookie.getValue();
        password = passwordCookie.getValue();
    } else {
        //否则从form表单中获得
        username = request.getParameter("username");
        password = request.getParameter("password");
    }
    

    这样就实现了免登录的功能。

    四、任务3实验过程

    使用session,显示计科院网站当前在线人数

    4.1 添加Session监听器

    //创建session
    public void sessionCreated(HttpSessionEvent se) {
        ServletContext servletContext = se.getSession().getServletContext();
    
        Object onlineNums = servletContext.getAttribute("onlineNums");
        int onlineNumsInt = 0;
        if (onlineNums == null) {
            onlineNumsInt = 1;
        } else {
            onlineNumsInt = Integer.parseInt(String.valueOf(onlineNums)) + 1;
        }
    
        //设置在线人数
        servletContext.setAttribute("onlineNums", onlineNumsInt);
    }
    
    //销毁session
    public void sessionDestroyed(HttpSessionEvent se) {
        HttpSession session = se.getSession();
        ServletContext servletContext = session.getServletContext();
    
        Object onlineNums = servletContext.getAttribute("onlineNums");
        int onlineNumsInt = 0;
        if (onlineNums == null) {
            onlineNumsInt = 0;
        } else {
            onlineNumsInt = Integer.parseInt(String.valueOf(onlineNums)) - 1;
        }
    
        //设置在线人数
        servletContext.setAttribute("onlineNums", onlineNumsInt);
    }
    

    4.2 web.xml注册监听

        <listener>
            <listener-class>listener.OnlineNumsListener</listener-class>
        </listener>
    

    4.3 获得当前在线人数

    PrintWriter writer = response.getWriter();
    ServletContext servletContext = this.getServletContext(); 
    int onlineNums =Integer.valueOf(servletContext.getAttribute("onlineNums").toString());
    writer.println("<h2>当前网页在线人数:" + onlineNums + "</h2>");
    

    效果如下:

    此处分别用Edge 和 Chorme浏览器打开

    1591104749153

    1591104789178

    • Cookie是把用户的数据写给用户的浏览器,浏览器保存 (可以保存多个)

    • Session把用户的数据写到用户独占Session中,服务器端保存 (保存重要的信息,减少服务器资源的浪费)

    • Session对象由服务创建;

    五、任务4实验过程

    使用过滤器解决乱码问题,登录时用户名为中文可能不能正常识别,解决该问题

    5.1 添加Filter,解决乱码问题

    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
        //设置编码
        req.setCharacterEncoding("utf-8");
        resp.setCharacterEncoding("utf-8");
        resp.setContentType("text/html;charset=utf-8");
    
        chain.doFilter(req, resp);
    }
    

    效果如下:

    1591093460167

    1591093502758

    5.2 web.xml中添加Filter配置,对所有页面都添加过滤

    <filter>
        <filter-name>CharacterEncodingFilter</filter-name>
        <filter-class>filter.CharacterEncodingFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>CharacterEncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    

    六、结语

    6.1 遇到的问题

    启用Session监听时,第一次启动,Session的个数为3,查找很多资料都不能解决,只能重新发布项目才可以。

    1591105133778

    码云地址: https://gitee.com/Jason98/JavaEE-Course

    1591105872425

  • 相关阅读:
    Raspberry pi raspbain source mirror
    Raspberry pi 定时天气播报
    Raspberry pi 2 wireless settings.
    MATLAB 图像处理-线性变换和直方图均衡
    求向量组的等价正交单位向量组-施密特正交化 C 语言 算法
    矩阵的逆 C 语言 算法二
    矩阵的逆 C 语言 算法一
    线性方程组 解的判别 与解的结构
    How to install .bundle packages in Ubuntu?
    C 语言期中考试 程序分析
  • 原文地址:https://www.cnblogs.com/jason5689/p/13034142.html
Copyright © 2020-2023  润新知