Servlet3.0 新特性全解

news2025/2/27 14:06:27

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(name="test",urlPatterns={"/basic.do"})
public class TestServlet extends HttpServlet{

    //使用该方法可响应客户端的所有请求
    public void service(HttpServletRequest req, HttpServletResponse resp)throws IOException{
        System.out.println("进servlet了");
        PrintStream out = new PrintStream(resp.getOutputStream());
        //向页面输入下面字符串
        out.print("1234567890");
    }

}

web-fragment.xml代码片

<web-fragment version="3.0" xmlns="http://java.sun.com/xml/ns/javaee"  
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
   xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-fragment_3_0.xsd">  

   <!-- 指定模块名称 :唯一标识-->  
   <name>mySerModule</name>  
   <!-- 加载顺序 -->  
   <ordering>  
      <!-- 在其它模块之前加载 -->  
      <before>  
         <others/>  
      </before>  
   </ordering>      
</web-fragment> 

​ 在web-fragment.xml里的配置和之前的web.xml里类似,如果是注解实现的servlet的配置,则在web-fragment.xml里就将不再写配置了,如果不是,则还需要写配置。
打成jar包放在一个项目里面启动后,就可通过上面servlet注解配置的/basic.do路径访问上面的servle了。

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应用设置初始化参数。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

DEV SIT UAT PET SIM PRD PROD常见环境英文缩写含义

一、英文缩写 英文中文 DEV development开发 SIT System Integrate Test系统整合测试&#xff08;内测&#xff09; UAT User Acceptance Test用户验收测试 PET Performance Evaluation Test性能评估测试&#xff08;压测&#xff09; SIM simulation仿真 PRD/PROD produ…

我们花一个月调研了小红书种草的新机会和增长策略

分析师&#xff1a;Jane、彬超 编辑&#xff1a;yolo 出品&#xff1a;增长黑盒研究组 *本报告为增长黑盒独立研究系列&#xff0c; 与第三方不存在任何利益关系 随着618的临近&#xff0c;小红书再次成为了品牌重要的“营销战场”。面临着经济环境的不确定性&#xff0c;想必各…

数据结构_串

目录 1. 串的定义和实现 1.1 串的定义 1.2 串的存储结构 1.2.1 定长顺序存储表示 1.2.2 堆分配存储表示 1.2.3 块链存储表示 1.3 串的基本操作 2. 串的模式匹配 2.1 简单的模式匹配算法 2.2 串的模式匹配算法——KMP算法 2.2.1 字符串的前缀、后缀和部分匹配值 2.2…

你不知道的裁员攻略:真正的离职赔偿是2N起步,不是N+1!计算赔偿金时,年终奖要计入总收入!...

最近裁员现象猖獗&#xff0c;许多人都不知道如何维护自己的合法权益&#xff0c;在和公司撕扯时屡屡被坑。一位曾经和字节撕过且成功的网友&#xff0c;友情给大家写了一份离职攻略。但要注意&#xff0c;这份攻略只针对那些守规矩的大公司&#xff0c;如果是不守规矩的小公司…

得ChatGPT者,得智能客服天下?

‍数据智能产业创新服务媒体 ——聚焦数智 改变商业 在现代社会&#xff0c;高效、专业的客服服务已成为企业、组织机构竞争力的关键要素。智能客服系统应运而生&#xff0c;智能客服系统对客服的赋能作用和价值主要表现在提高效率、降低成本、优化用户体验、深度挖掘用户需求…

【综述】结构化剪枝

目录 摘要 分类 1、依赖权重 2、基于激活函数 3、正则化 3.1 BN参数正则化 3.2 额外参数正则化 3.3 滤波器正则化 4、优化工具 5、动态剪枝 6、神经架构搜索 性能比较 摘要 深度卷积神经网络&#xff08;CNNs&#xff09;的显著性能通常归因于其更深层次和更广泛的架…

QML转换(Transformation)

目录 一 QML介绍 二 QML的使用场合 三 实例演示 一 QML介绍 QML是Qt Quick的缩写&#xff0c;它是一种新型的、面向对象的、跨平台的脚本语言&#xff0c;可以用来描述用户界面或应用程序的交互逻辑。QML可以在Qt应用程序中使用&#xff0c;也可以在其他JavaScript应用程序中…

Python入门(九)字典(二)

字典&#xff08;二&#xff09; 1.遍历字典1.1 遍历所有键值对1.2 遍历字典中的所有键1.3 按特定顺序遍历字典中的所有键 2.嵌套2.1 字典列表2.2 在字典中存储列表2.3 在字典中存储字典 作者&#xff1a;xiou 1.遍历字典 一个Python字典可能只包含几个键值对&#xff0c;也可…

【源码解析】SpringBoot自定义条件及@Conditional源码解析

自定义注解 自定义条件类 public class MessageCondition extends SpringBootCondition {Overridepublic ConditionOutcome getMatchOutcome(ConditionContext context, AnnotatedTypeMetadata metadata) {MultiValueMap<String, Object> attrs metadata.getAllAnnota…

成年人的崩溃只在一瞬间,程序员凌晨三点写的代码竟被女友删了...

对于恋爱中的情侣来说&#xff0c;吵架是很正常的事情&#xff0c;就算是再怎么亲密&#xff0c;也难免会出现意见不合的时候。 吵架不可怕&#xff0c;可怕的是&#xff0c;受吵架情绪的影响&#xff0c;做出一些比较“极端”的事情。 之前某社交平台上一位女生吐槽自己的男…

Ubuntu 本地部署 Stable Diffusion web UI

Ubuntu 本地部署 Stable Diffusion web UI 0. 什么是 Stable Diffusion1. 什么是 Stable Diffusion web UI2. Github 地址3. 安装 Miniconda34. 创建虚拟环境5. 安装 Stable Diffusion web UI6. 启动 Stable Diffusion web UI7. 访问 Stable Diffusion web UI8. 其他 0. 什么是…

我这里取出来的数据(最后边的excel)有点问题,我没有要取性别的数据,但是表里有...

点击上方“Python爬虫与数据挖掘”&#xff0c;进行关注 回复“书籍”即可获赠Python从入门到进阶共10本电子书 今 日 鸡 汤 上穷碧落下黄泉&#xff0c;两处茫茫皆不见。 大家好&#xff0c;我是皮皮。 一、前言 前几天在Python钻石群【不争】问了一个Python自动化办公的问题&…

PyCharm安装教程,图文教程(超详细)

「作者简介」&#xff1a;CSDN top100、阿里云博客专家、华为云享专家、网络安全领域优质创作者 「推荐专栏」&#xff1a;对网络安全感兴趣的小伙伴可以关注专栏《网络安全入门到精通》 PyCharm 一、PyCharm下载安装二、Python下载安装三、创建项目四、安装模块1、pip安装2、P…

商城系统商品属性的数据库设计思路

京东商城的数据库是如何搭建的&#xff0c;那么多商品&#xff0c;每种商品的参数各不相同&#xff0c;是怎样设计数据库的&#xff1f; 在提及这种设计思路前&#xff0c;首先得了解数据表可以分为两种结构: 1\横表,也就是我们经常用到的表结构&#xff0c; 2\纵表,这种结构…

ASEMI代理LT8609AJDDM#WTRPBF原装ADI车规级芯片

编辑&#xff1a;ll ASEMI代理LT8609AJDDM#WTRPBF原装ADI车规级芯片 型号&#xff1a;LT8609AJDDM#WTRPBF 品牌&#xff1a;ADI /亚德诺 封装&#xff1a;DFN-10 批号&#xff1a;2023 安装类型&#xff1a;表面贴装型 引脚数量&#xff1a;10 工作温度:-40C~125C 类型…

MySQL学习---13、存储过程与存储函数

1、存储过程概述 MySQL从5.0版本开始支持存储过程和函数。存储过程和函数能够将负杂的SQL逻辑封装在一起&#xff0c;应用程序无序关注存储过程和函数内部复杂的SQL逻辑&#xff0c;而只需要简单的调用存储过程和函数就可以。 1.1 理解 含义&#xff1a;存储过程的英文是Sto…

ASEMI代理LTC2954CTS8-2#TRMPBF原装ADI车规级芯片

编辑&#xff1a;ll ASEMI代理LTC2954CTS8-2#TRMPBF原装ADI车规级芯片 型号&#xff1a;LTC2954CTS8-2#TRMPBF 品牌&#xff1a;ADI/亚德诺 封装&#xff1a;TSOT-23-8 批号&#xff1a;2023 引脚数量&#xff1a;23 工作温度&#xff1a;-40C~85C 安装类型&#xff1a…

若依框架(RuoYI)项目打包(jar)方法,部署到 Linux 服务器

序言 在若依框架的 bin 目录下&#xff0c;存在着三个 bat 文件&#xff0c;一个是清除之前的依赖的自动化 bat 脚本&#xff08;clean.bat&#xff09;&#xff0c;一个是自动化项目打包的 bat 脚本&#xff08;package.bat&#xff09;&#xff0c;一个是运行若依项目的脚本…

云原生CAx软件:技术约束

Pivotal公司的Matt Stine于2013年首次提出Cloud Native(云原生)的概念&#xff0c;从概念提出到技术落地&#xff0c;云原生还处于不断发展过程中&#xff0c;关于云原生的定义也不断在完善。 云原生为使用开源软件堆栈来创建容器化、动态编排和面向微服务的应用程序。 Heroku创…

YOLOv8 深度解析!一文看懂,快速上手实操(附实践代码)

关注并星标 从此不迷路 计算机视觉研究院 公众号ID&#xff5c;ComputerVisionGzq 学习群&#xff5c;扫码在主页获取加入方式 开源地址&#xff1a;https://github.com/ultralytics/ultralytics 计算机视觉研究院专栏 作者&#xff1a;Edison_G YOLOv8 是 ultralytics 公司在 …