JavaWeb去除web.xml

Servlet去除Web.xml

阿尔高 晚上 高山 福尔根湖湖 夜间 雾 5k风景壁纸_彼岸图网

了解Tomcat的SPI机制

Tomcat容器在启动时会扫描项目中META-INF/service下面的javax.servlet.ServletContainerInitializer文件,文件中配置实现了ServletContainerInitializer接口的启动类,利用这一特性,我们可以去除掉web.xml,在容器启动是配置我们自己的启动类。

代码演示
1、新建项目

1、新建一个Maven - webapp项目

image-20200616083649021

2、项目建好目录如下

image-20200616084817093

3、加入Servlet-api依赖 注意scope设置为provided


<dependency>

<groupId>javax.servlet</groupId>

<artifactId>javax.servlet-api</artifactId>

<version>3.1.0</version>

<scope>provided</scope>

</dependency>

代码开发
1、新建一个类实现ServletContainerInitializer接口

/**

* @author Kevin Liu

* @date 2020/6/16 8:51 上午

*/

public class MyServletContainerInitializer implements ServletContainerInitializer {

@Override

public void onStartup(Set<Class<?>> set, ServletContext servletContext) throws ServletException {

}

}

该接口只有一个方法onStartup,该方法有两个参数

  1. Set<Class<?>> set,在当前类上可以加一个注解@HandlesTypes,我们看看HandlerType源码

image-20200616090012928

该注解会传入一个Class对象的数组,也就是说,这个注解中的Class对象数组最终会放到上述onStartup的第一个参数中。

看看加上注解的类


/**

* @author Kevin Liu

* @date 2020/6/16 8:51 上午

*/

@HandlesTypes(TestHandleType.class)

public class MyServletContainerInitializer implements ServletContainerInitializer {

@Override

public void onStartup(Set<Class<?>> set, ServletContext servletContext) throws ServletException {



}

}

最终 程序在运行时会讲TestHandlerType.class传入Set<Class<?>> set 这个参数中,TestHandlerType自己可以随便新建一个测试一下。

  1. ServletContext servletContext 第二个参数为最重要的一个参数,表示Servlet上下文,我们可以向里面添加Servlet,listener,Filter三大JavaWeb对象
2、新建一个Servlet

public class HelloServlet extends HttpServlet {




@Override

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

resp.getWriter().write("Hello World");

}



@Override

protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

doGet(req, resp);

}

}

这个Servlet很简单,收到请求返回HelloWorld

3、往ServletContext加入Servlet

回到刚才的onStartUp方法,代码如下:


@Override

public void onStartup(Set<Class<?>> set, ServletContext servletContext) throws ServletException {

// 1.往容器中加入Servlet

ServletRegistration.Dynamic helloServlet = servletContext.addServlet("helloServlet", new HelloServlet());

// 2.设置Servlet映射 比如 访问/hello则访问helloServlet

helloServlet.addMapping("/hello");

}

4、META-INF/services目录下新建javax.servlet.ServletContainerInitializer文件

文件位置以及文件内容如下

image-20200616093236982

文件内容为初始化类的全类名

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GP0UmLAT-1592306060079)(/Users/kevin/Library/Application%20Support/typora-user-images/image-20200616093310779.png)]

5、将当前项目使用tomcat启动,配置如下

image-20200616091342921

6、浏览器访问http://localhost:8080/servlet/hello

image-20200616093814496

证明我们的Servlet添加成功。

测试Filter
测试代码

public class HelloFilter implements Filter {

@Override

public void init(FilterConfig filterConfig) throws ServletException {



}



@Override

public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {

System.out.println("进入拦截器");

filterChain.doFilter(servletRequest,servletResponse);

}



@Override

public void destroy() {



}

}


// 1、往容器加入Filter

FilterRegistration.Dynamic helloFilter = servletContext.addFilter("helloFilter", new HelloFilter());

// 2、设置需要拦截的路径

helloFilter.addMappingForUrlPatterns(null,false,"/");

// 3、这个方法能传递初始值 在init FilterConfig参数中能拿到

helloFilter.setInitParameter("test","test");



测试结果

image-20200616124027000

测试Listener
测试代码

public class HelloListener implements ServletContextListener {



@Override

public void contextInitialized(ServletContextEvent servletContextEvent) {

System.out.println("容器启动");

}



@Override

public void contextDestroyed(ServletContextEvent servletContextEvent) {

System.out.println("容器销毁");

}

}


// 1、添加监听器

servletContext.addListener(new HelloListener());

测试结果

image-20200616124502922

image-20200616124510541

结语

使用tomcat的Spi机制排除掉复杂的web.xml配置。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值