Servlet 3.0 新特性全解

文章目录

  • Servlet3.0新特性全解
    • Servlet 3.0 新增特性
    • Servlet3.0的注解
    • Servlet3.0的Web模块支持
    • servlet3.0提供的异步处理
      • 提供异步原因
      • 实现异步原理
      • 配置servlet类成为异步的servlet类
      • 具体实现
      • 异步监听器
      • 改进的ServletAPI(上传文件)

在这里插入图片描述


Servlet3.0新特性全解

tomcat 7以上的版本都支持Servlet 3.0

在这里插入图片描述

Servlet 3.0 新增特性

  1. 注解支持;Servlet、Filter、Listener无需在web.xml中进行配置,可以通过对应注解进行配置;
  2. 支持Web模块;
  3. Servlet异步处理;
  4. 文件上传API简化;

Servlet3.0的注解

  1. @WebServlet :修饰Servlet类,用于部署该Servlet类。
  2. @WebFilter:修饰Filter类,用于部署该Filter类
  3. @WebInitParam:与@WebServlet或@WebFilter注解连用,为它们配置参数
  4. @MultipartConfig:修饰Servlet类,指定该Servlet类负责处理multipart/form-data类型的请求(主要用于处理上传文件)
  5. @ServletSecurity:修饰Servlet类,与JAAS(Java验证和授权API)有关的注解
  6. @HttpConstrait:与@ServletSecurity连用
  7. @HttpMethodConstrait:与@ServletSecurity连用

示例代码片
修饰过滤器Filter:

@WebFilter(
        filterName="log",
        urlPatterns={"/*"},
        initParams={
        @WebInitParam(name="encoding",value="GBK"),
        @WebInitParam(name="loginPage",value="/login.jsp")
        })
public class MyFilter implements Filter {
    //内容省略......
}

修饰Servlet

@WebServlet(name="test",
    urlPatterns={"/basic.do"},
    initParams={
        @WebInitParam(name="userName",value="peter"),
        @WebInitParam(name="age",value="100")
        })
public class TestServlet extends HttpServlet{
    //内容省略....
}

修饰监听器Listener:

@WebListener
public class MyRequestListener implements ServletRequestListener{
    //内容省略...
}

Servlet3.0的Web模块支持

  1. 原来一个web应用的任何配置都需要在web.xml中进行,因此会使得web.xml变得很混乱,而且灵活性差。现在可通过Web模块来部署管理它们。
  2. Web模块对应一个Jar包,即Servlet 3.0可以将每个Servlet、Filter、Listener打成jar包,然后放在WEB-INF\lib中。
  3. 每个模块都有自己的配置文件,这个配置文件的名称为 web-fragment.xml 。
  4. 制作一个Servlet模块的步骤:
    1. 正常编写Servlet,并编译;
    2. 将此编译class文件及所在包通过jar包命令打成jar包;
    3. 将此jar包用winrar打开,将META-INF中的manifest删除后添加 web-fragment.xml;
    4. 将此jar包放入WEB-INF\lib中即可;
  5. web-fragment.xml说明:
    1. <web-fragment>为根元素;
    2. <name></name>表示模块名称(模块的唯一标识);
    3. <ordering></ordering>定义模块加载顺序的标签,当然可以不设置模块加载顺序;
    4. <before><others/></before>表示在所有模块前面加载(第一个加载);
    5. <after><name>A</name></after>表示在A模块后面加载;
    6. 可以在里面部署listener、filter、servlet
    7. 值得注意的是,web.xml中用<absolute-ordering>标签指定的模块加载顺序将会覆盖web模块的web-fragment.xml文件中指定的加载顺序。
  6. 如何用myEclipse打jar包(有些人不知道)
    右键你web项目里的编写的servlet(或filter或listener)类——>Export…——>JAR file——>NEXT——>(Browse)填写导出名字和存放位置——>finish
    这样就生成了我们需要的jar包了
  7. 示例
    servlet类代码片:
@WebServlet(value = "/hello/snow")
public class HelloWorldServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.getWriter().write("DO GEt..." + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
    }

}

访问:
在这里插入图片描述

servlet3.0提供的异步处理

提供异步原因

​ 在以前的servlet中,如果作为控制器的servlet调用了一个较为耗时的业务方法,则servlet必须等到业务执行完后才会生成响应,这使得这次调用成了阻塞式调用,效率比较差

实现异步原理

​ 重新开一个线程单独去调用耗时的业务方法。

配置servlet类成为异步的servlet类

  1. 通过注解asyncSupported=true实现
  2. 通过web.xml配置
<servlet>
        <servlet-name>test1</servlet-name>
        <servlet-class>com.zrgk.servlet.AsyncServlet</servlet-class>
        <async-suppored>true</async-suppored>       
    </servlet>
    <servlet-mapping>
        <servlet-name>test1</servlet-name>
        <url-pattern>/basic.do</url-pattern>
    </servlet-mapping>

具体实现

java代码:

@WebServlet(name="AsyncServlet",urlPatterns={"/testAsyn.do"},asyncSupported=true)  
public class AsyncServlet extends HttpServlet{  
   public void service(HttpServletRequest request,HttpServletResponse response)throws ServletException,IOException{ 
       //解决乱码
       request.setCharacterEncoding("GBK");  
       response.setContentType("text/html;charset=GBK");  
       //通过request获得AsyncContent对象
       AsyncContext actx = request.startAsync(); //重点方法**
       //设置异步调用超时时长
        actx.setTimeout(30*3000);  
        //启动异步调用的线程
        actx.start(new MyThread(actx));//重点方法**

       // 直接输出到页面的内容(不等异步完成就直接给页面)
        //但这些内容必须放在标签内,否则会在页面输出错误内容,这儿反正我测试是这样,具体不知对不对??
       PrintWriter out = response.getWriter();
       out.println("<h1>不等异步返回结果就直接返到页面的内容</h1>");  
       out.flush(); 
   }  
}  

//异步处理业务的线程类
public class MyThread implements Runnable {
     private AsyncContext actx;  
     //构造
     public MyThread(AsyncContext actx){  
            this.actx = actx;  
     }  
     public void run(){  
        try{  
            //等待5秒,模拟处理耗时的业务
           Thread.sleep(4*1000); 
           //获得request对象,添加数据给页面
           ServletRequest req = actx.getRequest();
           req.setAttribute("content","异步获得的数据");
           //将请求dispath到index.jsp页面,该页面的session必须设为false
           actx.dispatch("/index.jsp");  
        }catch(Exception e){
            e.printStackTrace();
        }  
     }   
}

​ 页面代码(页头里session设为false,表时该页面不会再创建session):

<%@ page language="java" import="java.util.*" pageEncoding="utf-8" session="false"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<html>  
  <body>
    <a href="<%=basePath%>/testAsyn.do">测试异步调用</a>
    异步结果:${content}
  </body>
</html>

异步监听器

​ 异步监听器用来监听异步Servlet的异步处理事件,通过实现AsyncListener接口实现,代码如下:

public class MyAsyncListener implements AsyncListener{

    //异步调用完成时触发
    @Override
    public void onComplete(AsyncEvent event) throws IOException {
        // 省略....       
    }

    //异步调用出错时触发
    @Override
    public void onError(AsyncEvent event) throws IOException {
        // 省略....       
    }

    //异步调用开始触发
    @Override
    public void onStartAsync(AsyncEvent event) throws IOException {
        // 省略....       
    }

    //异步调用超时触发
    @Override
    public void onTimeout(AsyncEvent event) throws IOException {
        // 省略....       
    }

}

​ 还需要在异步Servlet里注册异步监听器,即添加如下代码即可:

 actx.addListener(new MyAsyncListener());

​ Filter异步调用与Servlet一样。

改进的ServletAPI(上传文件)

  1. 改进内容

    1. HttpServletRequest增加了对上传文件的支持
    2. ServletContext允许通过编程的方式动态注册Servlet、Filter
  2. HttpServletRequest提供了如下两个方法处理文件的上传

    Part getPart(String name) 根据名称获取文件上传域

    1. Collection<Part> getParts() 获取所有文件上传域
  3. 上传文件时一定要为表单域设置enctype属性,它表示表单数据的编码方式,有如下三个值:

    application/x-www-form-urlencoded (默认),它只处理表单里的value属性值,它会将value值处理成URL编码方式。如果此时表单域里有上传文件的域(type=”file”),则只会获取该文件在上传者电脑里的绝对路径串,该串没什么实际意义。

    1. multipart/form-data 此处编码方式会以二制流的方式来处理表单数据,此时会将文件内容也封装到请求参数里。
    2. texst/plain 当表单的action属性为mailto:URL的形式时比较方便,主要适用于直接通过表单发送邮件的方式
  4. 上传文件的Servlet需要加上@MultipartConfig注解

  5. 通过request获取的Part对象就可以操作文件域了

  6. 示例

@WebServlet(name="uploadServlet",urlPatterns="/upload.do")
@MultipartConfig
public class UploaderServlet extends HttpServlet {

    public void service(HttpServletRequest request,HttpServletResponse response) throws IOException, ServletException{
        //获得Par对象(每个Part对象对应一个文件域)
        Part part = request.getPart("file");
        long size = part.getSize(); //获取上传文件大小
        String info = part.getHeader("content-disposition");//获得包含原始文件名的字符串
        //获取原始文件名
        String fileName = info.substring(info.indexOf("filename=\"")+10,info.length()-1);
        //将文件上传到某个位置
        part.write(getServletContext().getRealPath("/uploadFiles")+"/"+fileName);
    }
}

ServletContext 提供了如下方法动态注册Servlet、Filter
addServlet(); 动态注册Servlet
addFilter(); 动态注册Filter
addListener(); 动态注册Listener
setInitParameter(String name ,String value); 为Web应用设置初始化参数。


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/905445.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

mysql 通过GROUP BY 聚合并且拼接去重另个字段

我的需求&#xff1a; 我想知道同一个手机号出现几次&#xff0c;并且手机号出现在哪些地方。下面是要的效果。 源数据: CREATE TABLE bank (id bigint(20) unsigned NOT NULL AUTO_INCREMENT,user_id int(11) NOT NULL DEFAULT 0,tel varchar(255) COLLATE utf8mb4_unicode_…

新加坡托管服务器VS香港托管服务器:AI时代的选择策略

在人工智能迅速发展的今天&#xff0c;服务器作为数据存储与计算的核心基础设施&#xff0c;其性能、稳定性和地理位置对于用户体验和业务效率至关重要。对于中国用户而言&#xff0c;在选择服务器时&#xff0c;新加坡服务器和香港服务器无疑是两个极具吸引力的选项。两者同属…

Linux的硬盘管理

硬盘有价&#xff0c;数据无价 1. 硬盘的概念 硬盘是一种计算机的存储设备&#xff0c;通常是由一个或者多个磁性盘片组成。硬盘即可以安装在计算机的内部&#xff0c;也可以外接计算机。 保存数据 数据&#xff1a;操作系统&#xff0c;应用程序&#xff0c;文档多媒体文件…

震惊,盖子居然重现CSDN?

盖子奇迹般重回C站 众所周知&#xff0c;盖子上次发布文章是在2024年5月18号&#xff08;感兴趣的可以回去看一下&#xff0c;链接放在下面了&#xff09; 盖子的c小课堂——第二十七讲&#xff1a;背包变形题_恰好装满的01背包-CSDN博客https://blog.csdn.net/m0_73334782/a…

PostgreSQL的学习心得和知识总结(一百五十七)|新的 COPY 选项 LOG_VERBOSITY

目录结构 注&#xff1a;提前言明 本文借鉴了以下博主、书籍或网站的内容&#xff0c;其列表如下&#xff1a; 1、参考书籍&#xff1a;《PostgreSQL数据库内核分析》 2、参考书籍&#xff1a;《数据库事务处理的艺术&#xff1a;事务管理与并发控制》 3、PostgreSQL数据库仓库…

【力扣打卡系列】二叉树的最近公共祖先

坚持按题型打卡&刷&梳理力扣算法题系列&#xff0c;语言为go&#xff0c;Day18 二叉树的最近公共祖先 题目描述 解题思路 最近公共祖先分类讨论 当前节点是空节点&#xff08;返回当前节点&#xff09;当前节点是p&#xff08;返回当前节点&#xff09;当前节点是q&am…

Redis常见面试题总结(上)

Redis 基础 什么是 Redis? Redis &#xff08;REmote DIctionary Server&#xff09;是一个基于 C 语言开发的开源 NoSQL 数据库&#xff08;BSD 许可&#xff09;。与传统数据库不同的是&#xff0c;Redis 的数据是保存在内存中的&#xff08;内存数据库&#xff0c;支持持久…

Training-free layout control with cross-attention guidance

https://zhuanlan.zhihu.com/p/666445024https://zhuanlan.zhihu.com/p/666445024 支持两种模式,1.sd文生图;2.绑定了dreambooth和text inversion的图像编辑。 # ------------------ example input ------------------examples &

‌Spring MVC的主要组件有哪些?

前言 SpringMVC的核心组件包括DispatcherServlet、Controller、HandlerMapping、HandlerAdapter、ViewResolver、ModelAndView等&#xff0c;它们协同工作以支持基于MVC架构的Web应用程序开发。这些组件使得开发人员能够以一种声明式和模块化的方式构建Web应用程序&#xff0c…

Python突破浏览器TLS/JA3 指纹

初识指纹遇到一个网站,忽然发现无论如何如何更换UA和代理请求都是403&#xff0c;curl_cffi 可模拟真实浏览器的 TLS | JA3 指纹。 查看 tls 指纹的网站&#xff1a; https://tls.browserleaks.com/json不同网站的生成的指纹可能有差异&#xff0c;但是多次访问同一个网站生成…

Redis新数据类型

新数据类型 Bitmaps 命令 setbit 实例 getbit 实例 bitcount 实例 bitop 实例 Bitmaps与set 对比 HyperLogLog 命令 pfadd 实例 pfcount 实例 pfmerge 实例 Geospatial 命令 geoadd 实例 geopos 实例 geodist 实例 georadius 实例 Bitmaps Ⅰ.B…

【Qt】QTableView添加下拉框过滤条件

实现通过带复选框的下拉框来为表格添加过滤条件 带复选框的下拉框 .h文件 #pragma once #include <QCheckBox> #include <QComboBox> #include <QEvent> #include <QLineEdit> #include <QListWidget>class TableComboBox : public QComboBox …

Java Executor ScheduledExecutorService 源码

前言 相关系列 《Java & Executor & 目录》《Java & Executor & ScheduledExecutorService & 源码》《Java & Executor & ScheduledExecutorService & 总结》《Java & Executor & ScheduledExecutorService & 问题》 涉及内容 …

C++:继承~派生类以及衍生的多继承与菱形继承问题

C中的继承其实是一个C中的坑,主要体现在其多继承(菱形继承)方面,我们先来了解下继承的概念 一,继承的概念与定义 1.1继承的概念 继承(inheritance)机制是面向对象程序设计使代码可以复用的最重要的手段&#xff0c;它允许我们在保持原有类特性的基础上进行扩展&#xff0c;增…

Python 从入门到实战43(Pandas数据结构)

我们的目标是&#xff1a;通过这一套资料学习下来&#xff0c;可以熟练掌握python基础&#xff0c;然后结合经典实例、实践相结合&#xff0c;使我们完全掌握python&#xff0c;并做到独立完成项目开发的能力。 上篇文章我们学习了NumPy数组操作的相关基础知识。今天学习一下pa…

工程项目智能化管理平台,SpringBoot框架智慧工地源码,实现工程建设施工可视化、智能化的全过程闭环管理。

智慧工地管理系统的建设以“1个可扩展性平台2个应用端3方数据融合N个智能设备”为原则。以“智、保、安、全”为导向&#xff0c;与工程建设管理信息系统、综合安防平台深度集成&#xff0c;构建统一的标准化工地平台&#xff0c;实现现场人员、车辆、项目、安全、进度等方面的…

使用React构建现代Web应用

&#x1f496; 博客主页&#xff1a;瑕疵的CSDN主页 &#x1f4bb; Gitee主页&#xff1a;瑕疵的gitee主页 &#x1f680; 文章专栏&#xff1a;《热点资讯》 使用React构建现代Web应用 1 引言 2 React简介 3 安装React 4 创建React项目 5 设计应用结构 6 创建组件 7 使用组件…

哈希——哈希表处理哈希冲突的方法

处理哈希冲突 实践中哈希表⼀般还是选择除法散列法作为哈希函数。 当然哈希表无论选择什么哈希函数也避免不了冲突&#xff08;主要作用就是减少冲突&#xff09;&#xff0c;那么插入数据时&#xff0c;如何解决冲突呢&#xff1f;主要有两种两种方法&#xff0c;开放定址法和…

海外云手机是什么?对外贸电商有什么帮助?

在外贸电商领域&#xff0c;流量引流已成为卖家们关注的核心问题。越来越多的卖家开始利用海外云手机&#xff0c;通过TikTok等社交平台吸引流量&#xff0c;以推动商品在海外市场的销售。那么&#xff0c;海外云手机到底是什么&#xff1f;它又能为外贸电商卖家提供哪些支持呢…

Hadoop-001-本地虚拟机环境搭建

一、安装VMware 官方下载VMware&#xff1a; https://vmware.mdsoft.top/?bd_vid5754305114651491003 二、下载镜像文件 阿里云镜像仓库&#xff1a; https://mirrors.aliyun.com/centos/ 本文档使用 CentOS-7-x86_64-DVD-1810-7.6.iso 搭建虚拟机 三、搭建虚拟机 1、编辑…