spring注解驱动第八节之Servlet3.0

四、Servlet3.0

本章节不详细介绍相关servlet的只是,只大概讲解如果抛弃传统的web.xml配置文件来注册servlet三大组件

Servlet3.0以后,引入一个接口,javax.servlet.ServletContainerInitializer,该接口的onStartup方法可以在ServletContext启动完成之前,创建组件,并且实现了该接口的类通过特定格式的配置,能够在Servlet容器启动的时候自动被识别到然后被加载,最终完成组件的创建工作,包含每一个jar包里的ServletContainerInitializer的实现。格式规则必须绑定在classpath下,META-INF/services/javax.servlet.ServletContainerInitializer文件下META-INF/services/这一块为文件路径,javax.servlet.ServletContainerInitializer这个是文件的名称,而不是类名,然后将实现了ServletContainerInitializer接口的全类名粘贴到这个文件内容里即可。使用IDEA直接新建packageMETA-INF会不能直接创建,但是可以直接创建META-INF/services,然后再在这个路径下新建文件即可

1. 创建一个Servlet工程,勾选Web Application,取名servlet-annotation

2. 创建基于注解的Servlet,对于Servlet提供直接的注解支持WebServlet

package com.ddf.annotation.servlet;

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

/**
 * @author DDf on 2018/8/14
 * 使用注解代替web.xml配置文件来识别Servlet
 */
@WebServlet("/hello")
public class HelloServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.getWriter().write("hello!");
    }
}

3. 编写待注册的Servlet组件,不使用WebServlet注解

package com.ddf.annotation.servlet;

import com.ddf.annotation.servlet.configuration.CustomsContainerInit;

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

/**
 * @author DDf on 2018/8/14
 * 使用编码方式映射servlet {@link CustomsContainerInit}
 */
public class CustomServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        resp.setContentType("text/html;charset=UTF-8");
        resp.getWriter().write("使用编码方式映射Servlet..........");
    }
}

4. 编写Filter

package com.ddf.annotation.servlet.filter;

import javax.servlet.*;
import java.io.IOException;

/**
 * @author DDf on 2018/8/14
 */
public class CustomFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("过滤器初始化。。。。。。。。");
        System.out.println("servlet容器: " + filterConfig.getServletContext());

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("目标方法被拦截.............");
        filterChain.doFilter(servletRequest, servletResponse);
    }

    @Override
    public void destroy() {
        System.out.println("销毁方法。。。。。。。。。。。");
    }
}

5. 编写Listener

package com.ddf.annotation.servlet.listener;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

/**
 * @author DDf on 2018/8/14
 * 监听servlet容器的创建和销毁
 */
public class CustomListeners implements ServletContextListener {
    @Override
    public void contextInitialized(ServletContextEvent servletContextEvent) {
        System.out.println("监听容器初始化。。。。。。。。。");
        System.out.println(servletContextEvent);
    }

    @Override
    public void contextDestroyed(ServletContextEvent servletContextEvent) {
        System.out.println("监听容器销毁..........");
        System.out.println(servletContextEvent);
    }
}

6. 编写注册三大组件的配置类,实现ServletContainerInitializer接口

package com.ddf.annotation.servlet.configuration;

import com.ddf.annotation.servlet.CustomServlet;
import com.ddf.annotation.servlet.filter.CustomFilter;
import com.ddf.annotation.servlet.listener.CustomListeners;

import javax.servlet.*;
import javax.servlet.annotation.HandlesTypes;
import java.util.EnumSet;
import java.util.Set;

/**
 * @author DDf on 2018/8/14
 * @HandlesTypes 容器启动的时候会将@HandlesTypes指定的这个类型下面的子类(实现类,子接口等)传递过来作为onStartup的第一个参数
 *
 * 1、Servlet容器启动会扫描,当前应用里面每一个jar包的
 * ServletContainerInitializer的实现
 * 2、提供ServletContainerInitializer的实现类;
 * 必须绑定在classpath下,META-INF/services/javax.servlet.ServletContainerInitializer
 * 文件的内容就是ServletContainerInitializer实现类的全类名;
 */
@HandlesTypes(value={Filter.class})
public class CustomsContainerInit implements ServletContainerInitializer {


    /**
     * 在容器启动的时候创建servlet组件,不需要使用配置文件
     * @param set
     * @param servletContext
     * @throws ServletException
     */
    @Override
    public void onStartup(Set<Class<?>> set, ServletContext servletContext) throws ServletException {
        System.out.println("@HandlesTypes传入的类型有: ");
        for (Class clazz : set) {
            System.out.println(clazz);
        }

        // 注册Servlet
        ServletRegistration.Dynamic customServlet = servletContext.addServlet("customServlet", new CustomServlet());
        customServlet.addMapping("/custom");

        // 注册Listener
        servletContext.addListener(CustomListeners.class);

        // 注册Filter
        FilterRegistration.Dynamic customFilter = servletContext.addFilter("customFilter", new CustomFilter());
        customFilter.addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST), true, "/*");

    }
}

7. 识别ServletContainerInitializer实现类

src下新建META-INF\services\javax.servlet.ServletContainerInitializer文件,粘贴自定义实现类的全类名

com.ddf.annotation.servlet.configuration.CustomsContainerInit

8. 启动容器,访问ip:port/servlet-annotation/custom,然后销毁容器,日志如下,正确识别

@HandlesTypes传入的类型有: 
class com.ddf.annotation.servlet.filter.CustomFilter
监听容器初始化。。。。。。。。。
javax.servlet.ServletContextEvent[source=org.apache.catalina.core.StandardContext$NoPluggabilityServletContext@1e99db28]
过滤器初始化。。。。。。。。
servlet容器: org.apache.catalina.core.ApplicationContextFacade@1af646c8
目标方法被拦截.............
目标方法被拦截.............
14-Aug-2018 16:29:26.003 信息 [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory D:\tomcat8\webapps\manager
14-Aug-2018 16:29:26.039 信息 [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory D:\tomcat8\webapps\manager has finished in 36 ms
目标方法被拦截.............
销毁方法。。。。。。。。。。。
监听容器销毁..........
javax.servlet.ServletContextEvent[source=org.apache.catalina.core.StandardContext$NoPluggabilityServletContext@1e99db28]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值