Fork me on GitHub

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

posted @ 2020-06-02 22:11  jasonlalala  阅读(308)  评论(0编辑  收藏  举报