Listener
监听器也是web项目三大组件之一。
作用:监听器用于监听域对象(除页面域以外的)的创建和销毁,以及域对象的属性变更。
分类:
第一类:监听域对象的创建和销毁
域对象类型 | 监听器 | 对应方法 | 描述 |
---|---|---|---|
ServletContext | ServletContextListener | contextInitialized | application初始化 |
contextDestroyed | application销毁 | ||
HttpSession | HttpSessionListener | sessionCreated | session创建 |
sessionDestroyed | session销毁 | ||
HttpServletRequest | ServletRequestListener | requestInitialized | request创建 |
requestDestroyed | request销毁 |
第二类:监听域对象的属性变更
域对象类型 | 监听器 | 对应方法 | 描述 |
---|---|---|---|
ServletContext | ServletContextAttributeListener | attributeAdded | 添加属性 |
attributeRemoved | 删除属性 | ||
attributeReplaced | 修改属性值 | ||
HttpSession | HttpSessionAttributeListener | attributeAdded | 添加属性 |
attributeRemoved | 删除属性 | ||
attributeReplaced | 修改属性值 | ||
HttpServletRequest | ServletRequestAttributeListener | attributeAdded | 添加属性 |
attributeRemoved | 删除属性 | ||
attributeReplaced | 修改属性值 |
第三类:监听HttpSession中JavaBean的状态改变
第三类监听器非常特殊,这类监听器不用配置。 监听器作用在JavaBean上,JavaBean可以自己感知在session中状态。
域对象类型 | 监听器 | 对应方法 | 描述 |
---|---|---|---|
HttpSession | HttpSessionBindingListener | valueBound | 绑定 |
valueUnbound | 解除绑定 | ||
HttpSession | HttpSessionActivationListener | sessionWillPassivate | 序列化(钝化) |
sessionDidActivate | 反序列化(活化) |
测试使用
监听域对象的创建
package com.woniuxy.listenner;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
/**
* 监听器创建的步骤
* 1、实现对应的监听器接口,复写其对应的方法
* 2、配置监听器
*/
@WebListener
public class MyListener implements ServletRequestListener, HttpSessionListener, ServletContextListener {
@Override
public void requestDestroyed(ServletRequestEvent servletRequestEvent) {
System.out.println("requestDestroyed...");
}
@Override
public void requestInitialized(ServletRequestEvent servletRequestEvent) {
System.out.println("requestInitialized...");
}
@Override
public void sessionCreated(HttpSessionEvent httpSessionEvent) {
System.out.println("sessionCreated...");
}
@Override
public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
System.out.println("sessionDestroyed...");
}
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
System.out.println("contextInitialized...");
}
@Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
System.out.println("contextDestroyed...");
}
}
监听属性变更
监听器
package com.woniuxy.listenner;
import javax.servlet.ServletRequestAttributeEvent;
import javax.servlet.ServletRequestAttributeListener;
import javax.servlet.annotation.WebListener;
@WebListener
public class YourListener implements ServletRequestAttributeListener {
/**
* 监听请求对象第一次调用setAttribute()
* @param servletRequestAttributeEvent
*/
@Override
public void attributeAdded(ServletRequestAttributeEvent servletRequestAttributeEvent) {
System.out.println("attributeAdded...");
}
/**
* 监听请求对象调用removeAttribute()
* @param servletRequestAttributeEvent
*/
@Override
public void attributeRemoved(ServletRequestAttributeEvent servletRequestAttributeEvent) {
System.out.println("attributeRemoved...");
}
/**
* 监听请求对象第二次及更多次的调用setAttribute()
* 注意:对同一个key进行多次setAttribute()
* @param servletRequestAttributeEvent
*/
@Override
public void attributeReplaced(ServletRequestAttributeEvent servletRequestAttributeEvent) {
System.out.println("attributeReplaced...");
}
}
servlet
package com.woniuxy.servlet;
import com.woniuxy.commons.BaseServlet;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/user")
public class UserServlet extends BaseServlet {
public String login(HttpServletRequest req, HttpServletResponse resp){
System.out.println("处理登录请求");
req.setAttribute("a","1");
System.out.println("===========================");
req.setAttribute("b","2");
System.out.println("===========================");
req.removeAttribute("a");
return "/index.jsp";
}
}
监听器应用
统计在线人数
统计在线登录人数
案例代码:
监听器
package com.woniuxy.listenner;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
/**
* 使用监听器统计在线人数
* 实现ServletContextListener接口的目的:在servoetContext创建时,初始一个变量,用于保存在线人数
*/
@WebListener
public class OnlineListener implements HttpSessionListener, ServletContextListener, HttpSessionAttributeListener {
@Override
public void sessionCreated(HttpSessionEvent httpSessionEvent) {
ServletContext context = httpSessionEvent.getSession().getServletContext();
Integer onlineCount = (Integer) context.getAttribute("onlineCount");
context.setAttribute("onlineCount",++onlineCount);
}
@Override
public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
ServletContext context = httpSessionEvent.getSession().getServletContext();
Integer onlineCount = (Integer) context.getAttribute("onlineCount");
context.setAttribute("onlineCount",--onlineCount);
}
/**
* ServletContext初始化时,保存一个存储在线人数的变量
* @param servletContextEvent
*/
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
ServletContext context = servletContextEvent.getServletContext();
//在servletContext对象完成初始化时,向该对象中保存了一个数据,用于记录在线人数
context.setAttribute("onlineCount",0);
//在servletContext对象完成初始化时,向该对象中保存了一个数据,用于记录在线登录人数
context.setAttribute("onlineLoginCount",0);
}
@Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
}
@Override
public void attributeAdded(HttpSessionBindingEvent httpSessionBindingEvent) {
ServletContext context = httpSessionBindingEvent.getSession().getServletContext();
Integer onlineLoginCount = (Integer) context.getAttribute("onlineLoginCount");
String name = httpSessionBindingEvent.getName();
if ("loginUser".equals(name)) {
context.setAttribute("onlineLoginCount",++onlineLoginCount);
}
}
@Override
public void attributeRemoved(HttpSessionBindingEvent httpSessionBindingEvent) {
ServletContext context = httpSessionBindingEvent.getSession().getServletContext();
Integer onlineLoginCount = (Integer) context.getAttribute("onlineLoginCount");
String name = httpSessionBindingEvent.getName();
if ("loginUser".equals(name)) {
context.setAttribute("onlineLoginCount",--onlineLoginCount);
}
}
@Override
public void attributeReplaced(HttpSessionBindingEvent httpSessionBindingEvent) {
}
}
servlet
package com.woniuxy.servlet;
import com.woniuxy.commons.BaseServlet;
import com.woniuxy.model.User;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/user")
public class UserServlet extends BaseServlet {
public String login(HttpServletRequest req, HttpServletResponse resp){
boolean flag=true;//true 表示登录成功 false 表示登录失败。
if (flag) {
req.getSession().setAttribute("loginUser",new User());
}
return "/index.jsp";
}
public void logout1(HttpServletRequest req, HttpServletResponse resp){
req.getSession().invalidate();
// return "/index.jsp";
}
public String logout2(HttpServletRequest req, HttpServletResponse resp){
req.getSession().removeAttribute("loginUser");
return "/index.jsp";
}
}
index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>$Title$</title>
</head>
<body>
<a href="/user?method=logout1">注销在线状态</a>
<a href="/user?method=logout2">注销登录状态</a>
当前在线人数为:${onlineCount}<br>
当前在线登录人数为:${onlineLoginCount}
</body>
</html>
文件上传
文件域:<input type=“file”/>
通过文件域可以去系统中搜集一个文件的内容,并将之存放在表单中。
前端
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<!--
文件上传不能使用BaseServlet
表单提交: post
enctype: multipart/form-data
文件域也必须有name属性
-->
<form action="/upload" method="post" enctype="multipart/form-data">
用户名:<input type="text" name="username"/><br>
密码:<input type="password" name="password"><br>
上传头像:<input type="file" name="upload"><br>
<input type="submit" value="立即注册">
</form>
</body>
</html>
servlet
package com.woniuxy.servlet;
import com.woniuxy.commons.RandomString;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.util.List;
@WebServlet("/upload")
public class UploadServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//isMultipartContent(req)用于判断请求中是否存在文件上传操作,如果是,返回true
boolean multipartContent = ServletFileUpload.isMultipartContent(req);
try {
if (multipartContent) {//是文件上传
//创建ServletFileUpload对象
ServletFileUpload fileUpload = new ServletFileUpload(new DiskFileItemFactory());
//准备解析请求
List<FileItem> fileItems = fileUpload.parseRequest(req);
//遍历fileItems集合,判断fileItem是否是文件域的内容
for (FileItem fileItem : fileItems) {
if (fileItem.isFormField()) {//普通表单字段
//fileItem.getFieldName()用于获取表单控件的name属性值
//fileItem.getString("utf-8")用于获取表单控件的value值
System.out.println(fileItem.getFieldName()+":"+fileItem.getString("utf-8"));
}else{//文件域字段,应该进行上传操作。
//上传的文件应该存放在哪里? 本地文件系统 tomcat 专门的文件服务器中
String path = this.getServletContext().getRealPath("/files");
File file = new File(path);
if (!file.exists()) {
file.mkdirs();
}
//上传的文件保存的文件名要不要做到唯一?
String originFileName = fileItem.getName();
String fileType = originFileName.substring(originFileName.lastIndexOf("."));
String saveFileName = RandomString.getRandomString(128)+fileType;
//创建要保存的文件对象
File saveFile = new File(file, saveFileName);
//将上传文件的名字保存到session中,便于后面引用
req.getSession().setAttribute("imagePath",saveFile.getName());
//将fileItem中的文件内容写入到文件中。
fileItem.write(saveFile);
//删除由于文件过大,在上传过程中产生的临时文件
fileItem.delete();
}
}
}else{//不是文件上传
}
} catch (FileUploadException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
resp.sendRedirect("/show.jsp");
}
}
javamail
javamail是sun公司为方便开发人员在开发过程中对邮件发送和接收操作而开发出来的一套标准开发包。
邮件协议:
邮件协议是TCP/IP协议簇下的一部分。
SMTP:既可接,也可发
POP3:发
IMAP:接
开发过程中只关心邮件的发送,不关心邮件的接收。
javamail包中重点关心的类:
Message类:就表示一封邮件,推荐使用其子类MimeMessage。
Session类:用于设置发送邮件的基本环境。
Transport类:send():静态方法,用于发送邮件。
准备邮件发送的基本环境
1、注册一个163邮箱,并登录进去。
2、在设置中开启pop3/smtp服务,注意保存授权码。
3、写代码,发邮件。先导入javax.mail.jar
package com.woniuxy.test;
import javax.mail.*;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import java.util.Properties;
public class Test {
public static void main(String[] args) throws MessagingException {
//创建properties:用于设置发送邮件的基本环境
Properties properties = new Properties();
properties.setProperty("mail.transport.protocol","SMTP");
properties.setProperty("mail.host","smtp.163.com");
properties.setProperty("mail.smtp.auth","true");
//创建Session
Session session = Session.getInstance(properties, new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication("hjy1***656@163.com","K***ZBYNPYF");
}
});
//1、创建邮件
Message message = new MimeMessage(session);
//设置邮件的发送者
message.setFrom(new InternetAddress("hjy1***656@163.com"));
//设置邮件的接收者
message.setRecipient(Message.RecipientType.TO,new InternetAddress("935***90@qq.com"));
//设置邮件标题
message.setSubject("20210915-测试邮件的发送");
//设置邮件内容
//参数1:邮件内容
//参数2:邮件的内容类型
message.setContent("测***邮件发送","text/html;charset=utf-8");
//发送邮件
Transport.send(message);
}
}
MD5加密
md5加密是一种散列算法,
特点:
1、对同个值进行再多次的加密运算,返回的值永远都是同一个。
2、md5加密是一个不可逆的过程,无法通过加密后的结果,反推出来原始值。
王小云!!
代码实现
package com.woniuxy.test;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
public class Test1 {
public static void main(String[] args) {
try {
String password="111111";
//生成加密对象
MessageDigest md5 = MessageDigest.getInstance("MD5");
//调用digest()方法对字符串进行加密操作
byte[] bytes = md5.digest(password.getBytes("utf-8"));
//使用Base64对加密结果进行处理,生成对应的字符串
String s = Base64.getEncoder().encodeToString(bytes);
System.out.println(s);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
}
try {
String password=“111111”;
//生成加密对象
MessageDigest md5 = MessageDigest.getInstance(“MD5”);
//调用digest()方法对字符串进行加密操作
byte[] bytes = md5.digest(password.getBytes(“utf-8”));
//使用Base64对加密结果进行处理,生成对应的字符串
String s = Base64.getEncoder().encodeToString(bytes);
System.out.println(s);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
}