Servlet3.0简介

Servlet 3.0 作为 Java EE 6 规范体系中一员,随着 Java EE 6 规范一起发布。该版本在前一版本(Servlet 2.5)的基础上提供了若干新特性用于简化 Web 应用的开发和部署。其中有几项特性的引入让开发者感到非常兴奋,同时也获得了 Java 社区的一片赞誉之声:

1.异步处理支持:有了该特性,Servlet 线程不再需要一直阻塞,直到业务处理完毕才能再输出响应,最后才结束该 Servlet 线程。在接收到请求之后,Servlet 线程可以将耗时的操作委派给另一个线程来完成,自己在不生成响应的情况下返回至容器。针对业务处理较耗时的情况,这将大大减少服务器资源的占用,并且提高并发处理速度。

2.新增的注解支持:该版本新增了若干注解,用于简化 Servlet、过滤器(Filter)和监听器(Listener)的声明,这使得 web.xml 部署描述文件从该版本开始不再是必选的了。

3.可插性支持:熟悉 Struts2 的开发者一定会对其通过插件的方式与包括 Spring 在内的各种常用框架的整合特性记忆犹新。将相应的插件封装成 JAR 包并放在类路径下,Struts2 运行时便能自动加载这些插件。现在 Servlet 3.0 提供了类似的特性,开发者可以通过插件的方式很方便的扩充已有 Web 应用的功能,而不需要修改原有的应用。

也就是说我们完全可以通过注解来取代web.xml,这也就是注解版的web开发。

一.@WebServlet("/hello")

@WebServlet(name="Hello",urlPatterns={"/hello.view"},loadOnStartup=1)  
public class Hello extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.getWriter().write("hello,world");
}
}

上面的@WebServlet告知容器,loadOnStartup,当值为0或者大于0时,表示容器在应用启动时就加载这个servlet;当是一个负数时或者没有指定时,则指示容器在该servlet被选择时才加载。

HelloServlet这个Servlet的名称是Hello,这是由name属性指定的,而如果客户端请求的URL是/hello.view,则由具Hello名称的Servlet来处理,这是由urlPatterns属性来指定的。在Java EE相关应用程序中使用标注时,可以记得的是,没有设置的属性通常会有默认值。例如,若没有设置@WebServlet的name属性,默认值会是Servlet的类完整名称。

相类似的注解还有@WebFilter(),@WebListener() 分别可以使用类似注解注册Filter以及Listener

二.ServletContainerInitializer

如果是本地项目可以通过上述注解来注册组件,但是如果是第三方的插件,无法通过@WebServlet()等注解注册组件,在web容器启动时为提供给第三方组件机会做一些初始化的工作,例如注册servlet或者filtes等,servlet规范中通过ServletContainerInitializer实现此功能

1.创建配置文件

首先创建在src或java目录下创建一个META-INF目录,然后在该目录下创建services目录,services下再创建javax.servlet.ServletContainerInitializer文件

2.创建MyServletContainerInitializer类该类必须实现ServletContainerInitializer

//容器启动时,会将HandlesTypes指定类型下面的子类,实现类,子接口传递过来
@HandlesTypes(value = {HelloService.class})
public class MyServletContainerInitializer implements ServletContainerInitializer {
/**
* 应用启动,会运行onStartup方法
* ServletContext arg1:代表当前WEb应用的ServletContext,一个web应用相当于一个webContext
*
* @param set 所有HandlesTypes指定的类型以及子类
* @param servletContext
* @throws ServletException
*/
@Override
public void onStartup(Set<Class<?>> set, ServletContext servletContext) throws ServletException {
for (Class<?> cla:set){
System.out.println("============================="+cla.getName());
} }
}

3.配置文件内容

在services目录下创建的文件里面内容为MyServletContainerInitializer的全类名:com.wang.servlet.MyServletContainerInitializer

4.启动应用

启动服务器,启动后会自动调用MyServletContainerInitializer的onStartup方法,其中@HandlesTypes类注解的作用是可以将感兴趣的类的子类(不包括该类)通过onStartup的第一个参数,以集合的形式传进来传进来。

三.使用ServletContainerInitializer注册三大组件

public class UserServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.getWriter().write("wanggggggg");
}
}
/**
* 监听项目的启动和停止
*/
public class UserListener implements ServletContextListener {
//监听启动
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
System.out.println("UserListener contextInitialized.....");
}
//监听销毁
@Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
System.out.println("UserListener contextDestroyed.....");
}
}
public class UserFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("UserFilter init...");
} @Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("UserFilter doFilter...");
filterChain.doFilter(servletRequest,servletResponse);
} @Override
public void destroy() {
System.out.println("UserFilter destroy...");
}
}

 使用编码的方式给servlet注册组件。

  @Override
public void onStartup(Set<Class<?>> set, ServletContext servletContext) throws ServletException {
for (Class<?> cla:set){
System.out.println("============================="+cla.getName());
}
//注册Servlet
ServletRegistration.Dynamic userServlet = servletContext.addServlet("userServlet", new UserServlet());
//配置Servlet映射信息
userServlet.addMapping("/userServlet"); //注册监听器
servletContext.addListener(UserListener.class); //注册Filter
FilterRegistration.Dynamic userFilter = servletContext.addFilter("userFilter", UserFilter.class);
//配置Filter的映射信息
userFilter.addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST),true,"/");
}

注意:必须在项目启动的时候添加组件,在项目运行时不允许注册组件,可以通过以下两种方式:

1.使用ServletContainerInitializer机制来注册组件;

2.利用ServletContextListener监听项目启动时注册组件。

Spring注解开发系列VII --- Servlet3.0的更多相关文章

  1. Spring注解开发系列Ⅵ --- AOP&事务

    注解开发 --- AOP AOP称为面向切面编程,在程序开发中主要用来解决一些系统层面上的问题,比如日志,事务,权限等待,Struts2的拦截器设计就是基于AOP的思想,横向重复,纵向抽取.详细的AO ...

  2. Spring注解开发系列专栏

    这个系列主要是讲Spring注解的使用,可以为后面SpringBoot的学习带来一定的帮助.我觉得从Spring直接过度到SpringBoot还是有点快,还是得需要一个演变的过程.从Spring开发, ...

  3. Spring注解开发系列VIII --- SpringMVC

    SpringMVC是三层架构中的控制层部分,有过JavaWEB开发经验的同学一定很熟悉它的使用了.这边有我之前整理的SpringMVC相关的链接: 1.SpringMVC入门 2.SpringMVC进 ...

  4. Spring注解开发系列Ⅰ--- 组件注册(上)

    传统的Spring做法是使用.xml文件来对bean进行注入或者是配置aop.事物,这么做有两个缺点:1.如果所有的内容都配置在.xml文件中,那么.xml文件将会十分庞大:如果按需求分开.xml文件 ...

  5. Spring注解开发系列Ⅴ --- 自动装配&Profile

    自动装配: spring利用依赖注入和DI完成对IOC容器中各个组件的依赖关系赋值.自动装配的优点有: 自动装配可以大大地减少属性和构造器参数的指派. 自动装配也可以在解析对象时更新配置. 自动装配的 ...

  6. Spring注解开发系列Ⅱ --- 组件注册(下)

    1.@Import注册组件 @Import主要功能是通过导入的方式实现把实例加入springIOC容器中, /** * 给容器注册组件 * 1.包扫描+组件标注注解(@Controller,@Serv ...

  7. Spring注解开发系列Ⅲ --- 生命周期

    Bean的生命周期 Spring Bean 的生命周期在整个 Spring 中占有很重要的位置,掌握这些可以加深对 Spring 的理解. 首先看下生命周期图: 再谈生命周期之前有一点需要先明确: S ...

  8. Spring注解开发系列Ⅳ --- 属性赋值

    在Spring框架中,属性的注入我们有多种方式,我们可以通过构造方法注入,可以通过set方法注入,也可以通过p名称空间注入,方式多种多样,对于复杂的数据类型比如对象.数组.List集合.map集合.P ...

  9. Spring注解开发系列Ⅸ --- 异步请求

    一. Servlet中的异步请求 在Servlet 3.0之前,Servlet采用Thread-Per-Request的方式处理请求,即每一次Http请求都由某一个线程从头到尾负责处理.如果要处理一些 ...

随机推荐

  1. spring-redis-session 自定义 key 和过期时间

    对于分布式应用来说,最开始遇到的问题就是 session 的存储了,解决方案大致有如下几种 使用 spring-session 它可以把 session 存储到你想存储的位置,如 redis,mysq ...

  2. 【温故知新】Java web 开发(四)JSTL 与 JDBC 的增删改查

    本篇开始使用 jstl 这个 jsp 的标签库,在同一个 Servlet 中实现处理 CRUD 请求,以及使用 jdbc 数据库基本操作.然后你会发现 Servlet 和 jdbc 还是有很多不方便之 ...

  3. Win10系统中搭建服务器的方法

    1.我的电脑->找到并点击“控制面板”->点击“程序”->点击“启用或关闭Windows功能”2.按如下图方式选中复选框   服务器批量管理软件 3.点击确定,打开iis管理器(右键 ...

  4. 一文详解滑动平均法、滑动平均模型法(Moving average,MA)

    任何关于算法.编程.AI行业知识或博客内容的问题,可以随时扫码关注公众号「图灵的猫」,加入”学习小组“,沙雕博主在线答疑~此外,公众号内还有更多AI.算法.编程和大数据知识分享,以及免费的SSR节点和 ...

  5. Javascript用途,语法特点,难点,调试工具,引入方式,命名规范,变量声明及赋值,数据类型,运算符

    JavaScript用来干什么 数据的验证 将动态的内容写入到网页当中(ajax) 对事件做出相应 读写html当中的内容 检测浏览器 创建cookies 模拟动画 语法特点 基于对象和事件驱动的松散 ...

  6. 洛谷P1189 SEARCH 题解 迭代加深

    题目链接:https://www.luogu.com.cn/problem/P1189 题目大意: 给你一个 \(n \times m\) 的矩阵,其中有一些格子可以走,一些各自不能走,然后有一个点是 ...

  7. js动态改变下拉框内容

    今天为大家分享一篇js动态设置select下拉菜单的默认选中项实例,具有很好的参考价值,希望对大家有所帮助. 代码实例如下: <!DOCTYPE html> <html lang=& ...

  8. python文件及目录操作

    python文件及目录操作 读/写文件 新建/打开文件 写入 #举个例子,打开D:\test\data.txt #以写入模式打开文件 #如果test(上级目录)不存在则报错 #如果data.txt(文 ...

  9. 【tf.keras】Linux 非 root 用户安装 CUDA 和 cuDNN

    TensorFlow 2.0 for Linux 使用时报错:(cuDNN 版本低了) E tensorflow/stream_executor/cuda/cuda_dnn.cc:319] Loade ...

  10. 正则表达式grep命令

    grep命令 作用:文本搜索工具,根据用户指定的“模式”对目标文本逐行进行匹配检查:打印匹配到的行. 模式::由正则表达式字符及文本字符所编写的过滤条件 语法:grep [OPTIONS] PATTE ...