Java三大器

filter过滤器

用的功能很简单,但是很重要(做框架的时候可能才会用得很深)

平时用就是实现一下Filter接口(重写它得doFliter(),init(),destroy()方法,放行chain.doFilter(request,response);),并在web.xml里边进行配置就完事了

另外一个是它的最佳实践:

公共代码得提取(如request,response指定编码解码方式,公共代码提到一块(处理post))

对request,response的方法进行增强(装饰者模式(包装,同样是乱码处理,使处理参数的能力更强大,支持中文(处理get))/动态代理(反射))(自动登陆)

进行权限控制

//装饰者模式(这个模式也很好记,就是你想用request对象的时候,你又希望它的getParameter()方法更加强大,可以处理中文,那么你可以建一个新类,对它的方法进行增强)
//(应用场景:不想增加很多子类/只想增强类的一些方法,例如在EncodingFilter过滤器中对request的getParameter方法进行增强,处理其中文参数乱码问题)
public class EncodingFilter implements Filter{

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        
        //在传递request之前对request的getParameter方法进行增强
        /*
         * 装饰者模式(包装)
         * 
         * 1、增强类与被增强的类要实现统一接口(继承同一个父类)
         * 2、在增强类中传入被增强的类(构造)
         * 3、需要增强的方法重写 不需要增强的方法调用被增强对象的
         * 
         */
        
        //被增强的对象req
        HttpServletRequest req = (HttpServletRequest) request;
        //增强对象enhanceRequest
        EnhanceRequest enhanceRequest = new EnhanceRequest(req);
        
        
        chain.doFilter(enhanceRequest, response);
    }

    @Override
    public void destroy() {
        
    }
    
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        
    }
}

class EnhanceRequest extends HttpServletRequestWrapper{
    //HttpServletRequestWrapper这个包装类就是专门用来你继承,进而写增强方法的
    private HttpServletRequest request;

    public EnhanceRequest(HttpServletRequest request) {//核心:传入被增强的类
        super(request);
        this.request = request;
    }
    
    //对getParaameter增强,增强的是原来类的方法
    @Override
    public String getParameter(String name) {
        String parameter = request.getParameter(name);//乱码
        try {
            parameter = new String(parameter.getBytes("iso8859-1"),"UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return parameter;
    }
}

Listener监听器

监听三个域对象:request,session,servletContext

 ServletContext代表整个web应用,只有一个

步骤:实现接口,覆盖方法,xml中进行配置

ServletContextListener

方法中可以获取到被监听的对象(两方法,一个是通用的)

应用:

web应用一创建,加载数据库驱动,连接池的初始话

加载spring初始配置文件(applicationContext.xml)

任务调度(定时器:Timer/TimeTask)

 HttpSession(多个)

服务端没有某浏览器对应的session时创建

 3种销毁:应用正常关闭,手动销毁,过期(默认30min)

应用:统计访问量

ServletRequest(瞬间的事)

ServletContext,HttpSession,ServletRequest三个域对象的属性变化(getAttribute,setAttribute,removeAttribute)

对象感知监听器((绑定,解绑)(钝化,活化)),(对象需要实现接口,不需要配置xml)

绑定状态:就一个对象被放到session域中
解绑状态:就是这个对象从session域中移除了
钝化状态:是将session内存中的对象持久化(序列化)到磁盘
活化状态:就是将磁盘上的对象再次恢复到session内存中

package com.itheima.domian;

import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionBindingListener;

public class Person implements HttpSessionBindingListener{

    private String id;
    private String name;
    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    
    
    @Override
    //绑定的方法
    public void valueBound(HttpSessionBindingEvent event) {
        System.out.println("person被绑定了");
    }
    @Override
    //解绑方法
    public void valueUnbound(HttpSessionBindingEvent event) {
        System.out.println("person被解绑了");
    }
    
    
    
}
Person p = new Person();
p.setId("100");
p.setName("zhangsanfeng");

//将person对象绑到session中
session.setAttribute("person", p);

//将person对象从session中解绑
session.removeAttribute("person");

一个对象必须要实现了Serializable接口,才能被存储到磁盘上

钝化:服务器正常关闭时,session中的对象会被钝化到磁盘

活化:服务器正常启动时,session会活化这个对象(外界又可以正常的访问这个session了)

另外,钝化和活化你可以进行主动控制(context.xml,默认配置1分钟不用被销毁)

package com.itheima.domian;

import java.io.Serializable;
import javax.servlet.http.HttpSessionActivationListener;
import javax.servlet.http.HttpSessionEvent;

public class Customer implements HttpSessionActivationListener,Serializable{

    private String id;
    private String name;
    
    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    
    
    @Override
    //钝化
    public void sessionWillPassivate(HttpSessionEvent se) {
        System.out.println("customer被钝化了");
    }
    @Override
    //活化
    public void sessionDidActivate(HttpSessionEvent se) {
        System.out.println("customer被活化了");
    }
    
    
}
<?xml version="1.0" encoding="UTF-8"?>
<Context>
    <!-- maxIdleSwap:session中的对象多长时间不使用就钝化 -->
    <!-- directory:钝化后的对象的文件写到磁盘的哪个目录下 配置钝化的对象文件在 work/catalina/localhost/钝化文件 -->
    <Manager className="org.apache.catalina.session.PersistentManager" maxIdleSwap="1">
        <Store className="org.apache.catalina.session.FileStore" directory="itheima32" />
    </Manager>
</Context>

Listener 监听器结合Timer定时任务实现每天定时给过生日的员工发邮件

  <listener>
      <listener-class>com.itheima.birthday.BirthdayListener</listener-class>
  </listener>
package com.itheima.birthday;

import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

import javax.mail.MessagingException;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanListHandler;

import com.itheima.mail.MailUtils;

public class BirthdayListener implements ServletContextListener{

    @Override
    public void contextInitialized(ServletContextEvent sce) {
        //当web应用启动 开启任务调动---功能在用户的生日当前发送邮件
        //开启一个定时器
        Timer timer = new Timer();
        timer.scheduleAtFixedRate(new TimerTask() {
            
            @Override
            public void run() {
                // 为当前的生日的用户发邮件
                //1、获得今天过生日的人
                //获得今天的日期
                SimpleDateFormat format = new SimpleDateFormat("MM-dd");
                String currentDate = format.format(new Date());
                //根据当前时间从数据查询今天过生日的人
                QueryRunner runner = new QueryRunner(DataSourceUtils.getDataSource());
                String sql = "select * from customer where birthday like ?";
                List<Customer> customerList = null;
                try {
                    customerList = runner.query(sql, new BeanListHandler<Customer>(Customer.class) ,"%"+currentDate+"%");
                } catch (SQLException e) {
                    e.printStackTrace();
                } //08-18
                //2、发邮件
                if(customerList!=null&&customerList.size()>0){
                    for(Customer c : customerList){
                        String emailMsg = "亲爱的:"+c.getRealname()+",生日快乐!";
                        try {
                            MailUtils.sendMail(c.getEmail(), "生日祝福", emailMsg);
                            System.out.println(c.getRealname()+"邮件发送完毕");
                        } catch (MessagingException e) {
                            e.printStackTrace();
                        }
                    }
                }
                
                
            }
        }, new Date(), 1000*10);
        //实际开发中起始时间是一个固定的时间
        //实际开发中间隔时间是1天
    }

    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        
    }

}

Interceptor拦截器

Java三大器:过滤器,监听器,拦截器Interceptor

拦截器是依赖Java反射机制来实现的。拦截器的实现,用到的是JDK实现的动态代理,我们都知道,JDK实现的动态代理,需要依赖接口。拦截器

是在面向切面编程中应用的,就是在你的service或者一个方法前调用一个方法,或者在方法后调用一个方法。拦截器不是在web.xml,比如struts在

struts.xml中配置。

过滤器可以简单的理解为“取你所想取”,过滤器关注的是web请求;拦截器可以简单的理解为“拒你所想拒”,拦截器关注的是方法调用

猜你喜欢

转载自www.cnblogs.com/lovesufang/p/12694181.html