1:servlet3.0及以上版本熟悉
1 ;@WebServlet 注解
2;@WebFilter
3:@WebListener
4:@WebInitParam
This annotation is used to specify any init parameters that must be passed to the Servlet or the Filter. It is an attribute of the WebServlet and WebFilter annotation.
官方示例
@WebServlet(”/foo”)
public class CalculatorServlet extends HttpServlet{
//...
}
@WebServlet(name=”MyServlet”, urlPatterns={"/foo", "/bar"})
public class SampleUsingAnnotationAttributes extends HttpServlet{
public void doGet(HttpServletRequest req, HttpServletResponse res) {
}
}
相当于
<servlet>
<servlet-name>FileSteamUpload</servlet-name>
<servlet-class>com.hd.common.utils.FileSteamUpload</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>FileSteamUpload</servlet-name>
<url-pattern>/servlet/FileSteamUpload</url-pattern>
</servlet-mapping>
<servlet>
注解版代替web.xml的方法
servlet3.0及以上提供的方法
官方使用说明
An instance of the ServletContainerInitializer is looked up via the jar services API by the container at container / application startup time.
The framework providing an implementation of the ServletContainerInitializer MUST bundle in the META-INF/services directory of the jar file a file called javax.servlet.ServletContainerInitializer, as per the jar services API,
that points to the implementation class of the ServletContainerInitializer.
1、Servlet容器启动会扫描,当前应用里面每一个jar包的 ServletContainerInitializer的实现 单纯的servlet我们按照下面操作也行
2、提供ServletContainerInitializer的实现类;
必须绑定在,META-INF/services/javax.servlet.ServletContainerInitializer
文件的内容就是ServletContainerInitializer实现类的全类名;
总结:容器在启动应用的时候,会扫描当前应用每一个jar包里面(注意:当我们用springmvc时spring帮我们实现了ServletContainerInitializer 我们只需继承spring帮我们实现的类后面说明)
给servlet中注册Servlet、Filter、Listener
public class MyServletContainerInitializer implements ServletContainerInitializer {
/**
* 应用启动的时候,会运行onStartup方法;
*
* Set<Class<?>> arg0:感兴趣的类型的所有子类型;
* ServletContext arg1:代表当前Web应用的ServletContext;一个Web应用一个ServletContext;
*
* 1)、使用ServletContext注册Web组件(Servlet、Filter、Listener)
* 2)、使用编码的方式,在项目启动的时候给ServletContext里面添加组件;
* 必须在项目启动的时候来添加;
* 1)、ServletContainerInitializer得到的ServletContext;
* 2)、ServletContextListener得到的ServletContext;
*/
@Override
public void onStartup(Set<Class<?>> arg0, ServletContext sc) throws ServletException {
// TODO Auto-generated method stub
System.out.println("感兴趣的类型:");
for (Class<?> claz : arg0) {
System.out.println(claz);
}
//注册组件 ServletRegistration
ServletRegistration.Dynamic servlet = sc.addServlet("userServlet", new UserServlet());
//配置servlet的映射信息
servlet.addMapping("/user");
//注册Listener
sc.addListener(UserListener.class);
//注册Filter FilterRegistration
FilterRegistration.Dynamic filter = sc.addFilter("userFilter", UserFilter.class);
//配置Filter的映射信息
filter.addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST), true, "/*");
}
}
2:注解版整合spring springmvc
了解知识 spring-web这个jar包帮我们实现了servlet ServletContainerInitializer接口
以注解方式来启动SpringMVC;
继承AbstractAnnotationConfigDispatcherServletInitializer;
实现抽象方法指定DispatcherServlet的配置信息;
官方案例:
示例说明:
//web容器启动的时候创建对象;调用方法来初始化容器以前前端控制器
public class MyWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
//获取根容器的配置类;(Spring的配置文件) 父容器;
@Override
protected Class<?>[] getRootConfigClasses() {
// TODO Auto-generated method stub
return new Class<?>[]{RootConfig.class};
}
//获取web容器的配置类(SpringMVC配置文件) 子容器;
@Override
protected Class<?>[] getServletConfigClasses() {
// TODO Auto-generated method stub
return new Class<?>[]{AppConfig.class};
}
//获取DispatcherServlet的映射信息
@Override
protected String[] getServletMappings() {
// TODO Auto-generated method stub
return new String[]{"/"};
}
springmvc配置类的编写
1)、@EnableWebMvc:开启SpringMVC定制配置功能;
<mvc:annotation-driven/>;
2)、配置组件(视图解析器、视图映射、静态资源映射、拦截器。。。)
extends WebMvcConfigurerAdapter
!注意 官方文档中让实现 WebMvcConfigurer 接口 但是这个接口定义了所有springmvc能配置的东西 我们很多都是用不到的 但是spring帮我们实现WebMvcConfigurer这个接口并提供了调用方法
我们开发中只需继承WebMvcConfigurerAdapter就行
public class AppConfig extends WebMvcConfigurerAdapter {
//定制
//视图解析器
@Override
public void configureViewResolvers(ViewResolverRegistry registry) {
// TODO Auto-generated method stub
//默认所有的页面都从 /WEB-INF/ xxx .jsp
//registry.jsp();
registry.jsp("/WEB-INF/views/", ".jsp");
}
//静态资源访问
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
// TODO Auto-generated method stub
configurer.enable();
}
//拦截器
@Override
public void addInterceptors(InterceptorRegistry registry) {
// TODO Auto-generated method stub
//super.addInterceptors(registry);
registry.addInterceptor(new MyFirstInterceptor()).addPathPatterns("/**");
}
参照官方文档 https://docs.spring.io/spring-framework/docs/5.3.4-SNAPSHOT/reference/html/web.html#mvc-config
3:servlet3.0及以上的另一强大功能 异步调用
官方描述:
An object implementing the AsyncContext interface may be obtained from the
ServletRequest via one of startAsync methods. Once you have an
AsyncContext, you can use it to either complete the processing of the request via
the complete() method or use one of the dispatch methods described below.
1 支持异步处理需 asyncSupported=true
@WebServlet(value="/xxxx",asyncSupported=true)
2 开启异步模式
AsyncContext startAsync = req.startAsync();
3 业务逻辑进行异步处理;开始异步处理
startAsync.start(new Runnable() {
@Override
public void run() {
try {
System.out.println("副线程开始。。。"+Thread.currentThread()+"==>"+System.currentTimeMillis());
sayHello();
startAsync.complete();
//获取到异步上下文
AsyncContext asyncContext = req.getAsyncContext();
//4、获取响应
ServletResponse response = asyncContext.getResponse();
response.getWriter().write("hello async...");
System.out.println("副线程结束。。。"+Thread.currentThread()+"==>"+System.currentTimeMillis());
} catch (Exception e) {
}
}
});
示例代码
@WebServlet(value="/async",asyncSupported=true)
public class HelloAsyncServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1、支持异步处理asyncSupported=true
//2、开启异步模式
System.out.println("主线程开始。。。"+Thread.currentThread()+"==>"+System.currentTimeMillis());
AsyncContext startAsync = req.startAsync();
//3、业务逻辑进行异步处理;开始异步处理
startAsync.start(new Runnable() {
@Override
public void run() {
try {
System.out.println("副线程开始。。。"+Thread.currentThread()+"==>"+System.currentTimeMillis());
sayHello();
startAsync.complete();
//获取到异步上下文
AsyncContext asyncContext = req.getAsyncContext();
//4、获取响应
ServletResponse response = asyncContext.getResponse();
response.getWriter().write("hello async...");
System.out.println("副线程结束。。。"+Thread.currentThread()+"==>"+System.currentTimeMillis());
} catch (Exception e) {
}
}
});
System.out.println("主线程结束。。。"+Thread.currentThread()+"==>"+System.currentTimeMillis());
}
public void sayHello() throws Exception{
System.out.println(Thread.currentThread()+" processing...");
Thread.sleep(3000);
}
}
spring基于servlet3.0的异步处理
官方示例:
官方说明
DeferredResult
processing works as follows:
-
The controller returns a
DeferredResult
and saves it in some in-memory queue or list where it can be accessed. -
Spring MVC calls
request.startAsync()
. -
Meanwhile, the
DispatcherServlet
and all configured filters exit the request processing thread, but the response remains open. -
The application sets the
DeferredResult
from some thread, and Spring MVC dispatches the request back to the Servlet container. -
The
DispatcherServlet
is invoked again, and processing resumes with the asynchronously produced return value.
Callable
processing works as follows:
-
The controller returns a
Callable
. -
Spring MVC calls
request.startAsync()
and submits theCallable
to aTaskExecutor
for processing in a separate thread. -
Meanwhile, the
DispatcherServlet
and all filters exit the Servlet container thread, but the response remains open. -
Eventually the
Callable
produces a result, and Spring MVC dispatches the request back to the Servlet container to complete processing. -
The
DispatcherServlet
is invoked again, and processing resumes with the asynchronously produced return value from theCallable
.