【Java Web开发学习】Spring MVC添加自定义Servlet、Filter、Listener

【Java Web开发学习】Spring MVC添加自定义Servlet、Filter、Listener

 转载:https://www.cnblogs.com/yangchongxing/p/9968483.html

自定义Servlet

package cn.ycx.servlet;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class MyServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;
    public MyServlet() {
        super();
    }
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("myservlet");
        response.getWriter().append("Served at: ").append(request.getContextPath());
    }
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }
}

 

自定义Filter

package cn.ycx.filter;

import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
public class MyFilter implements Filter {
    public MyFilter() {
    }
    public void destroy() {
    }
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        System.out.println("myfilter");
        chain.doFilter(request, response);
    }
    public void init(FilterConfig fConfig) throws ServletException {
    }
}

 静态资源处理Filter

package cn.ycx.filter;

import java.io.FileInputStream;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
public class StaticFilter implements Filter {
    public StaticFilter() {
    }
    public void destroy() {
    }
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        System.out.println("StaticFilter");
        HttpServletRequest httpServletRequest = (HttpServletRequest) request;
        String path = httpServletRequest.getServletPath();
        String realPath = httpServletRequest.getServletContext().getRealPath(path);
        System.out.println(realPath);
        ServletOutputStream out = response.getOutputStream();
        FileInputStream in = new FileInputStream(realPath);
        byte[] buf = new byte[2048];
        int len = -1;
        while((len = in.read(buf)) != -1) {
            out.write(buf, 0, len);
        }
        in.close();
        out.flush();
        out.close();
    }
    public void init(FilterConfig fConfig) throws ServletException {
    }
}

 

自定义Listener

package cn.ycx.listener;

import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;

public class MyServletRequestListener implements ServletRequestListener {
    @Override
    public void requestDestroyed(ServletRequestEvent sre)  { 
        System.out.println("requestDestroyed");
    }
    @Override
    public void requestInitialized(ServletRequestEvent sre)  { 
        System.out.println("requestInitialized");
    }
}

 

方式一、基于Java初始化器WebApplicationInitializer添加(支持Servlet3.0的容器)

package cn.ycx.initializer;

import javax.servlet.FilterRegistration;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;

import org.springframework.web.WebApplicationInitializer;

import cn.ycx.filter.MyFilter;
import cn.ycx.filter.StaticFilter;
import cn.ycx.listener.MyServletRequestAttributeListener;
import cn.ycx.listener.MyServletRequestListener;
import cn.ycx.servlet.MyServlet;

public class MyInitializer implements WebApplicationInitializer {

    @Override
    public void onStartup(ServletContext servletContext) throws ServletException {
        System.out.println(">>>>>>>>>>>> 自定义 onStartup ...");
        
        // 自定义Servlet
        ServletRegistration.Dynamic myServlet = servletContext.addServlet("myservlet", MyServlet.class);
        myServlet.addMapping("/myservlet");
        
        // 自定义Filter
        FilterRegistration.Dynamic staticFilter = servletContext.addFilter("staticfilter", StaticFilter.class);
        staticFilter.addMappingForUrlPatterns(null, false, "/static/*");
        FilterRegistration.Dynamic myFilter = servletContext.addFilter("myfilter", MyFilter.class);
        myFilter.addMappingForUrlPatterns(null, false, "/*");
        
        // 自定义Listener
        servletContext.addListener(MyServletRequestListener.class);
        servletContext.addListener(MyServletRequestAttributeListener.class.getName());
    }
}

 

addServlet 重载方法

public ServletRegistration.Dynamic addServlet(String servletName, String className);
public ServletRegistration.Dynamic addServlet(String servletName, Servlet servlet);
public ServletRegistration.Dynamic addServlet(String servletName,Class <? extends Servlet> servletClass);

addFilter 重载方法

public FilterRegistration.Dynamic addFilter(String filterName, String className);
public FilterRegistration.Dynamic addFilter(String filterName, Filter filter);
public FilterRegistration.Dynamic addFilter(String filterName,Class <? extends Filter> filterClass);

addListener 重载方法

public void addListener(String className);
public <T extends EventListener> void addListener(T t);
public void addListener(Class <? extends EventListener> listenerClass);

addMappingForUrlPatterns方法第二个参数isMatchAfter相同时,Filter的执行顺序由其在onStartup方法中的添加顺序决定,为false的优先级比为true高

/**
     * Adds a filter mapping with the given url patterns and dispatcher
     * types for the Filter represented by this FilterRegistration.
     *
     * <p>Filter mappings are matched in the order in which they were
     * added.
     * 
     * <p>Depending on the value of the <tt>isMatchAfter</tt> parameter, the
     * given filter mapping will be considered after or before any
     * <i>declared</i> filter mappings of the ServletContext from which
     * this FilterRegistration was obtained.
     *
     * <p>If this method is called multiple times, each successive call
     * adds to the effects of the former.
     *
     * @param dispatcherTypes the dispatcher types of the filter mapping,
     * or null if the default <tt>DispatcherType.REQUEST</tt> is to be used
     * @param isMatchAfter true if the given filter mapping should be matched
     * after any declared filter mappings, and false if it is supposed to
     * be matched before any declared filter mappings of the ServletContext
     * from which this FilterRegistration was obtained
     * @param urlPatterns the url patterns of the filter mapping
     *
     * @throws IllegalArgumentException if <tt>urlPatterns</tt> is null or
     * empty
     * @throws IllegalStateException if the ServletContext from which this
     * FilterRegistration was obtained has already been initialized
     */
    public void addMappingForUrlPatterns(EnumSet<DispatcherType> dispatcherTypes, boolean isMatchAfter, String... urlPatterns);

为什么实现这个接口容器就能加载自定义类呢?

因为在Servlet3.0环境中,容器会在类路径中查找实现javax.servlet.ServletContainerInitializer接口的类,并用它来配置Servlet容器。Spring提供了这个接口的实现类名为SpringServletContainerInitializer,这个类会查找实现WebApplicationInitializer接口的类,并将任务交给他们来完成。

SpringServletContainerInitializer类源码

@HandlesTypes(WebApplicationInitializer.class)
public class SpringServletContainerInitializer implements ServletContainerInitializer {
    @Override
    public void onStartup(Set<Class<?>> webAppInitializerClasses, ServletContext servletContext)
            throws ServletException {

        List<WebApplicationInitializer> initializers = new LinkedList<WebApplicationInitializer>();

        if (webAppInitializerClasses != null) {
            for (Class<?> waiClass : webAppInitializerClasses) {
                // Be defensive: Some servlet containers provide us with invalid classes,
                // no matter what @HandlesTypes says...
                if (!waiClass.isInterface() && !Modifier.isAbstract(waiClass.getModifiers()) &&
                        WebApplicationInitializer.class.isAssignableFrom(waiClass)) {
                    try {
                        initializers.add((WebApplicationInitializer) waiClass.newInstance());
                    }
                    catch (Throwable ex) {
                        throw new ServletException("Failed to instantiate WebApplicationInitializer class", ex);
                    }
                }
            }
        }

        if (initializers.isEmpty()) {
            servletContext.log("No Spring WebApplicationInitializer types detected on classpath");
            return;
        }

        servletContext.log(initializers.size() + " Spring WebApplicationInitializers detected on classpath");
        AnnotationAwareOrderComparator.sort(initializers);
        for (WebApplicationInitializer initializer : initializers) {
            initializer.onStartup(servletContext);//我们自定义的WebApplicationInitializer类在这里被执行
        }
    }

}

 

posted @ 2018-11-16 11:53  翠微  阅读(2036)  评论(0编辑  收藏  举报