您的位置:首页 > 编程语言 > Java开发

Java Web基础知识之Servlet容器初始化(无web.xml)

2017-08-25 09:38 836 查看
在之前典型的Java Web程序中,部署描述符
web.xml
是必不可少的,在这里我们需要配置各种组件,包括
Servlet
Filter
Listener
等,如果使用过SpringMVC的话,应该会对在
web.xml
中配置
org.springframework.web.servlet.DispatcherServlet
十分熟悉。但是对于所有的配置文件都有的一个通病就是只有在程序部署的时候,一些配置项问题才能被发现,而不能在程序编译开发阶段就发现。所以如果通过编程的方法来设置配置项则是一个最好的选择,我们完全可以抛弃
web.xml
这个部署描述符,而是换用从Servlet
3.0中提出的一个接口
javax.servlet.ServletContainerInitializer
来完成Servlet容器的初始化,该接口的作用是当Web应用启动时,通知一些实现类来执行一些要求的
Servlet
Filter
Listener
等的编程注册。

一、接口说明

ServletContainerInitializer
接口细节:

其中只有一个方法
onStartup(...)
,在执行任何
ServletContext
监听器之前,由Servlet容器调用这个方法,该方法的主要作用是注册Web对象;

实现
ServletContainerInitializer
的类必须使用
@HandleTypes
注解进行标注,以便声明
onStartup(...)
可以处理这个类的实例,所有该类、包括它的子类都会被传递给其中的
Set<Class<?>> c
字段,如果没有这个注解,或者在该注解中使用的类不存在或没有相应的子类,则会传递给该参数一个
null
值;

这个接口被设计在
jar
文件中使用,而无法直接在
war
包中直接使用,而是通过在
jar
中完成定义,然后将
jar
包作为Java Web的依赖包,该接口的实现类会通过Java的
SPI
的注册查询机制被发现;

如果要使用这个类,需要一个元数据文件来说明如何定位该接口的实现类,该文本文件在META-INF/services文件夹下,这个文本文件的名称为
javax.servlet.ServletContainerInitializer
,其中的内容是该接口的实现类的全限定名;



二、编程实现

1、构建
jar
依赖包

首先搭建依赖包工程,这里使用Maven管理工程,依赖项只需要一个,如下:

<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
1
Maven项目目录如下:



其中
ServletContainerInitializer
的实现类为
com.demo.CustomServletContainerInitializer
,为了在jar中加入
META-INF/services
文件夹,只需要将该文件夹直接放到
maven
的资源文件夹
resources
下即可,在打包的时候就会在jar中实现该文件夹,并包括之前的文件;

可以看出
META-INF/services
文件夹中的文本文件名为
javax.servlet.ServletContainerInitializer
,其中的内容为
com.demo.CustomServletContainerInitializer
,为该接口的实现类;

CustomServletContainerInitializer
中的实现如下:

@HandlesTypes({HttpServlet.class})
public class CustomServletContainerInitializer implements ServletContainerInitializer {

public void onStartup(Set<Class<?>> c, ServletContext ctx) throws ServletException {
for(Class<?> clazz: c){
System.out.println(clazz.getName());
}
}
}
1
该实现类在Java Web应用启动时,会调用该方法,传递
HttpServlet
类以及其子类。

2、构建Java Web程序

Java Web程序的工程目录如下:



在工程中必须有
webapp
这个目录,如果没有则会导致异常
java.lang.IllegalArgumentException: Document base ... src\main\webapp does not exist or is not a readable directory


这里我们定义一个
Servlet
TestServlet
,通过使用注解
@javax.servlet.annotation.WebServlet
来标识这个
Servlet
,代码如下:

@WebServlet(urlPatterns = "/testServlet", name = "testServlet")
public class TestServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Writer writer = resp.getWriter();
writer.write("do get");
}

@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Writer writer = resp.getWriter();
writer.write("do post");
}
}
1
这个注解是在应用启动的时候被容器处理,并且都对应的servlet也可以通过相应的URL来访问;

在程序启动的过程中,会发现传递进来很多的servlet子类和Filter的实现类,如下:



其中也包括我们自定义的一个
TestServlet
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  servlet