JAVAEE第三次作业-servlet应用
一、任务
-
编写一个servlet进行用户名和密码校验,获取登录页面的用户名密码,并显示出来
-
使用cookie,如果用户在登录时选择保存登录信息,30天内,用户无需登录
-
使用session,显示计科院网站当前在线人数
-
使用过滤器解决乱码问题,登录时用户名为中文可能不能正常识别,解决该问题
二、任务1实验过程
编写一个servlet进行用户名和密码校验,获取登录页面的用户名密码,并显示出来
2.1 创建maven项目
利用IDEA编译器来完成此次实验,为了方便对所用jar包的管理,新建maven项目。
2.2 添加框架支持
右键项目文件,点击Add FrameWork Support
选择Web Application
添加以后的项目文件结构,其中src
目录放入servelet等JAVA类,web
目录放html、css、js、imaage等资源
2.3 将实验1中的静态资源导入web目录
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服务器
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 创建并连接数据库
- 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;
-
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>");
}
}
成功/失败登录效果如下:
三、任务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);
}
效果如下:
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浏览器打开
4.4 补充 Cookie 和 Session`的区别
-
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);
}
效果如下:
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,查找很多资料都不能解决,只能重新发布项目才可以。