Servlet笔记(十) servlet监听器 JavaMail

来源:互联网 发布:网络约车平台 编辑:程序博客网 时间:2024/06/08 16:56
一,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)
 
 
 
 
 
 
 
 
 
 
 
 
0 0