• 【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类在这里被执行
            }
        }
    
    }
  • 相关阅读:
    使用css制作三角
    BZOJ3029: 守卫者的挑战
    Codeforces 442B. Andrey and Problem
    嘴巴题8 BZOJ2318: Spoj4060 game with probability Problem
    嘴巴题7 BZOJ1426: 收集邮票
    嘴巴题6 BZOJ3450JoyOI1952 Easy
    BZOJ1453: [Wc]Dface双面棋盘
    BZOJ2957: 楼房重建
    BZOJ4515: [Sdoi2016]游戏
    BZOJ3679: 数字之积
  • 原文地址:https://www.cnblogs.com/yangchongxing/p/9968483.html
Copyright © 2020-2023  润新知