一,servlet监听器
学习监听器,关键是,知道有什么样的应用场景.
servlet规范中定义了8个监听器
1,监听servletContext,HttpSession,ServletRequest三个对象实例的创建和销毁
ServletContextListener:监听context的创建和销毁
HttpSessionListener:监听Session的创建和销毁
ServletRequestListener:监听request的创建和销毁:应用场景:统计页面的访问次数.
2,监听servletContext,HttpSession,ServletRequest三个域对象数据变化(增,改,删)的监听器
ServletContextAttributeListener:
HttpSessionAttributeListener:罗列在线用户,踢人
ServletRequestAttributeListener:
3,感知型监听器(不需要注册)
HttpSessionBindingListener:监听自身是否驾到HttpSession中去了
HttpSessionActivationListener:监听自身何时钝化和激活.
监听器一般都是接口,谁用,谁实现
例子一,窗口事件的监听
/*
观察者设计模式
事件源:发生事件的主要对象
监听器:监听事件源上面发生的动作.一般都是接口
事件对象:封装事件源
*/
public static void main(String[] args) {
Frame f = new Frame("我的窗口");//设置窗体顶端显示的名字
f.setSize(600, 400);//设置窗体的尺寸
f.setVisible(true);//设置窗体显示
//注册监听器
f.addWindowListener(new MywindowListener());
}
}
class MywindowListener extends WindowAdapter{
//覆盖关闭窗体的方法
public void windowClosing(WindowEvent e) {
//得到事件源
Frame f = (Frame) e.getSource();
f.dispose();//关闭对象.
}
} |
例子二:自定义监听器,监听器说明
建立Student类
public class Student {
private String name;
//声明监听器,监听器一般为接口
private StudentListener listener;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void Study(){
//如果监听器不为空,则先执行监听器
if(listener!=null){
listener.preStudy(new StudentEvent(this));
}
System.out.println(name+"开始学习了");
}
public void sleep(){
//如果监听器不为空,则先执行监听器
if(listener!=null){
listener.proSleep(new StudentEvent(this));
}
System.out.println(name+"开始睡觉了");
}
//需要有注册监听器的方法
public void addStudentListener(StudentListener listener){
this.listener = listener;
}
} |
建立监听器------StudentListener接口
//监听器,必须有事件源
public interface StudentListener {
void preStudy(StudentEvent e);
void proSleep(StudentEvent e);
} |
建立事件对象,封装事件源------StudentEvent类
构造方法必须传一个对象进来 source
//事件对象:封装事件源
public class StudentEvent {
private Object source;
public StudentEvent(Object source){
this.source=source;
}
public Object getSource() {
return source;
}
} |
建立StudentDemo类,main方法,实现监听器
public class StudentDemo {
public static void main(String[] args) {
Student s = new Student();
s.setName("狗蛋");
//注册监听器
s.addStudentListener(new MySudentListener());
s.Study();
s.sleep();
}
}
//实现监听器
class MySudentListener implements StudentListener{
public void preStudy(StudentEvent e) {
Student s = (Student) e.getSource();
System.out.println(s.getName()+"喝杯牛奶吧");
}
public void proSleep(StudentEvent e) {
Student s = (Student) e.getSource();
System.out.println(s.getName()+"听歌故事吧");
}
} |
例子三:在servlet下实现监听
建立ServletContextDemoListener,实现接口
/*
注册监听器:web.xml
<listener>
<listener-class>com.itheima.web.listener.ServletContextDemoListener</listener-class>
</listener>
开发中有什么用(特点):
完成系统级别的初始化。例如Spring
*/
public class ServletContextDemoListener implements ServletContextListener {
public void contextDestroyed(ServletContextEvent arg0) {
System.out.println("ServletContext对象被摧毁了");
}
public void contextInitialized(ServletContextEvent arg0) {
System.out.println("ServletContext对象被创建了");
// <beans>
// <bean id="studentDao" class="com.itheima.dao.impl.StudentDaoImpl" type="proto"/>
// ...
// ...
// </beans>
//
// Map<String,Object> objs = ;
//
// 读取beans中的所有的bean元素
// 通过反射加载class制定的类,并创建实例对象
// 对象名称为id的值
//
// objs.put(id,Class.forName(class).newInstance());
}
} |
踢人案例:
建立User,(JavaBean)实现
Serializable接口
建立登录界面index.jsp
<body>
<a href="${pageContext.request.contextPath}/login.jsp">登录</a>
<a href="">在线用户</a>
</body> |
建立login.jsp
<body>
<form action="${pageContext.request.contextPath}/servlet/LoginServlet" method="post">
用户名:<input type="text" name="username" /><br/>
用户名:<input type="password" name="password" /><br/>
<input type="submit" value="登录" />
</form>
</body> |
建立LoginServlet类
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
String name = request.getParameter("name");
String password = request.getParameter("password");
User user = new User(name, password);
//把name和password存到session中
request.getSession().setAttribute("user", user);
response.setHeader("Refresh", "2;URL="+request.getContextPath());
out.write("登录成功,2秒后转到主页");
} |
建立LoginInfoListener监听器类
取得所有在线用户,取得所有用户
public class LoginInfoListener implements HttpSessionAttributeListener {
//key必须是user
//value必须是User类型
//把登录信息找个容器存起来:把该容器放到ServletContext域中.
public void attributeAdded(HttpSessionBindingEvent e) {
HttpSession session = e.getSession();
ServletContext sc = session.getServletContext();
Object obj = session.getAttribute("user");
//判断是否取得的是User
if(obj!=null&&obj instanceof User){
//建立一个Map,把取得的User存到Map里,方便取出.为了保证map唯一,先要进行判断
Map<String, HttpSession> users = (Map<String, HttpSession>) sc.getAttribute("users");
if(users==null){
//注意,要同步处理,否则有可能会创建多个map集合
users = Collections.synchronizedMap(new HashMap<String,HttpSession>());
sc.setAttribute("users", users);
}
User user = (User) obj;
//如果没有存相同的用户,就把这个新用户存进去
if(!users.containsKey(user.getUsername())){
users.put(user.getUsername(), session);
}
}
}
public void attributeRemoved(HttpSessionBindingEvent e) {
}
public void attributeReplaced(HttpSessionBindingEvent e) {
}
} |
建立onlineusers.jsp
<body>
<h1>当前在线用户表</h1>
<c:forEach items="${applicationScope.users}" var="me">
<c:url value="/servlet/KickServlet" var="url">
<c:param name="username" value="${me.key }"></c:param>
</c:url>
${me.key } <a href="${url }">踢出</a>
</c:forEach>
</body> |
建立SickServlet类
public class KickServlet extends HttpServlet {
//在应用域中移除用户
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
String username = request.getParameter("username");
username = new String(username.getBytes("ISO-8859-1"),"UTF-8");
//在域中取得users
Map<String, HttpSession> users = (Map<String, HttpSession>) getServletContext().getAttribute("users");
//对比Map中是否有对应的session
if(users.containsKey(username)){
//先移除session中的user
users.get(username).removeAttribute("user");
//再移除相关的元素
users.remove(username);
}
response.setHeader("Refresh", "1;URL=" + request.getContextPath());
out.write("处理成功!1秒后转向主页");
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
} |
二,JavaMail邮件开发
二、邮件开发
关键:协议
1、SMTP协议:(重点)
发送邮件的协议
Simple Message Transfer Protocal
使用的端口:25
2、POP协议:
接收邮件的协议
Post Office Protocal
使用的端口:110
3、手工发送邮件(熟悉SMTP、POP协议的组成)
准备环境:(需要翻译成Base64)
anqi@itheima.com
anqi YW5xaQ==
123 MTIz
fengjie@itheima.com
fengjie ZmVuZ2ppZQ==
123 MTIz
smtp和pop服务器地址localhost
演示:anqi@itheima.com--->fengjie@itheima.com
telnet localhost 25
--------------------------------
ehlo wzhting
auth login //请求认证:不认证不能发送邮件
YW5xaQ==
MTIz
mail from:<anqi@itheima.com>
rcpt to:<fengjie@itheima.com>
data //邮件内容开始
***********************************
邮件格式:RFC822规定的
头:
subject:主题
from:发件人邮箱
to:收件人邮箱
cc:抄送
bcc:密送
内容
***********************************
. //邮件结束
--------------------------------
quit
接收:fengjie接收
telnet localhost 110
--------------------------------
user fengjie
pass 123
--------------------------------
quit
三、利用JavaMail进行邮件开发
1、JavaMail是JavaEE技术之一。规范是由SUN制定,一般都是由抽象类或接口组成。
2、开发时需要的jar
javamail.jar
jaf.jar(Java Activition Framework):如果是JDK6及以上版本,则不需要(有了)
3、邮件开发(JavaMail的API相当的灵活)
邮件的创建:
只有文本的邮件
//创建只有文本的邮件
public class MailDemo1 {
public static void main(String[] args) throws Exception {
//创建Properties用于存放邮件信息
Properties props = new Properties();
//注意导包为javax.mail的包
Session session = Session.getInstance(props);
MimeMessage message = new MimeMessage(session);
//设置邮件主题
message.setSubject("简单的第一封邮件");
//设置邮件发送地址,创建InternetAddress存放地址
message.setFrom(new InternetAddress("888@itheima.com"));
//设置邮件发送者地址,和发送类型:to,cc,bcc
message.setRecipients(Message.RecipientType.TO, "wzt@itheima.com");
//设置邮件内容
message.setText("珽哥好,测试发邮件");
message.saveChanges();
//可以发送了,但是先保存到磁盘上
message.writeTo(new FileOutputStream("d:/1.eml"));
}
} |
既有文本且有内嵌图片的邮件
//创建有图片和文本的邮件
public class MailDemo2 {
public static void main(String[] args) throws Exception {
//头部分
Properties props = new Properties();
Session session = Session.getInstance(props);
MimeMessage message = new MimeMessage(session);
message.setSubject("简单的第二封邮件");
message.setFrom(new InternetAddress("888@itheima.com"));
message.setRecipients(Message.RecipientType.TO, "wzt@itheima.com");
//文本部分;BodyPart:代表某一部分
MimeBodyPart text = new MimeBodyPart();
text.setContent("aaa<img src='cid:mm'/>aaa", "text/html;charset=UTF-8");
//图片部分
MimeBodyPart image = new MimeBodyPart();
//JAF能自动探测你的文件的MIME类型
DataHandler dh = new DataHandler(new FileDataSource("d:/1.jpg"));
image.setDataHandler(dh);
image.setContentID("mm");
//描述2部分的关系;Multipart:描述各部分的关系
MimeMultipart mmpart = new MimeMultipart();
mmpart.addBodyPart(text);
mmpart.addBodyPart(image);
mmpart.setSubType("related");
message.setContent(mmpart);
message.saveChanges();
message.writeTo(new FileOutputStream("d:/1.eml"));
}
} |
既有文本且有内嵌图片的邮件还有附件的邮件
//创建有图片和文本,还有附件的邮件
public class MailDemo3 {
public static void main(String[] args) throws Exception {
//头部分
Properties props = new Properties();
Session session = Session.getInstance(props);
MimeMessage message = new MimeMessage(session);
message.setSubject("简单的第三封邮件");
message.setFrom(new InternetAddress("888@itheima.com"));
message.setRecipients(Message.RecipientType.TO, "wzt@itheima.com");
//文本部分;BodyPart:代表某一部分
MimeBodyPart text = new MimeBodyPart();
text.setContent("aaa<img src='cid:mm'/>aaa", "text/html;charset=UTF-8");
//图片部分
MimeBodyPart image = new MimeBodyPart();
//JAF能自动探测你的文件的MIME类型
DataHandler dh = new DataHandler(new FileDataSource("d:/1.jpg"));
image.setDataHandler(dh);
image.setContentID("mm");
//附件部分
MimeBodyPart attachPart = new MimeBodyPart();
dh = new DataHandler(new FileDataSource("d:/美女.zip"));
String filename = dh.getName();
attachPart.setDataHandler(dh);
attachPart.setFileName(MimeUtility.encodeText(filename));
//描述2部分的关系;Multipart:描述各部分的关系
MimeMultipart textimage = new MimeMultipart();
textimage.addBodyPart(text);
textimage.addBodyPart(image);
textimage.setSubType("related");//有关系的
//把第一部分和第二部分转成BodyPart
MimeBodyPart textImagePart = new MimeBodyPart();
textImagePart.setContent(textimage);
//把文本图片的部分,和附件加在一起
MimeMultipart mmp = new MimeMultipart();
mmp.addBodyPart(textImagePart);
mmp.addBodyPart(attachPart);
mmp.setSubType("mixed");//复杂关系
message.setContent(mmp);
message.saveChanges();
message.writeTo(new FileOutputStream("d:/3.eml"));
}
} |
邮件的发射:
方式一
方式二
四、利用Tomcat管理JavaMail中的Session对象(JNDI)