Servlet3.0 新特性全解
Servlet3.0新特性全解
tomcat 7以上的版本都支持Servlet 3.0
Servlet 3.0 新增特性
- 注解支持;Servlet、Filter、Listener无需在web.xml中进行配置,可以通过对应注解进行配置;
- 支持Web模块;
- Servlet异步处理;
- 文件上传API简化;
Servlet3.0的注解
- @WebServlet :修饰Servlet类,用于部署该Servlet类。
- @WebFilter:修饰Filter类,用于部署该Filter类
- @WebInitParam:与@WebServlet或@WebFilter注解连用,为它们配置参数
- @MultipartConfig:修饰Servlet类,指定该Servlet类负责处理multipart/form-data类型的请求(主要用于处理上传文件)
- @ServletSecurity:修饰Servlet类,与JAAS(Java验证和授权API)有关的注解
- @HttpConstrait:与@ServletSecurity连用
- @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模块支持
- 原来一个web应用的任何配置都需要在web.xml中进行,因此会使得web.xml变得很混乱,而且灵活性差。现在可通过Web模块来部署管理它们。
- Web模块对应一个Jar包,即Servlet 3.0可以将每个Servlet、Filter、Listener打成jar包,然后放在WEB-INF\lib中。
- 每个模块都有自己的配置文件,这个配置文件的名称为 web-fragment.xml 。
- 制作一个Servlet模块的步骤:
- 正常编写Servlet,并编译;
- 将此编译class文件及所在包通过jar包命令打成jar包;
- 将此jar包用winrar打开,将META-INF中的manifest删除后添加 web-fragment.xml;
- 将此jar包放入WEB-INF\lib中即可;
- web-fragment.xml说明:
<web-fragment>
为根元素;<name></name>
表示模块名称(模块的唯一标识);<ordering></ordering>
定义模块加载顺序的标签,当然可以不设置模块加载顺序;<before><others/></before>
表示在所有模块前面加载(第一个加载);<after><name>A</name></after>
表示在A模块后面加载;- 可以在里面部署listener、filter、servlet
- 值得注意的是,web.xml中用
<absolute-ordering>
标签指定的模块加载顺序将会覆盖web模块的web-fragment.xml文件中指定的加载顺序。
- 如何用myEclipse打jar包(有些人不知道)
右键你web项目里的编写的servlet(或filter或listener)类——>Export…——>JAR file——>NEXT——>(Browse)填写导出名字和存放位置——>finish
这样就生成了我们需要的jar包了 - 示例
servlet类代码片:
@WebServlet(value = "/hello/snow")
public class HelloWorldServlet extends HttpServlet {@Overrideprotected 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类
- 通过注解asyncSupported=true实现
- 通过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必须设为falseactx.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{//异步调用完成时触发@Overridepublic void onComplete(AsyncEvent event) throws IOException {// 省略.... }//异步调用出错时触发@Overridepublic void onError(AsyncEvent event) throws IOException {// 省略.... }//异步调用开始触发@Overridepublic void onStartAsync(AsyncEvent event) throws IOException {// 省略.... }//异步调用超时触发@Overridepublic void onTimeout(AsyncEvent event) throws IOException {// 省略.... }}
还需要在异步Servlet里注册异步监听器,即添加如下代码即可:
actx.addListener(new MyAsyncListener());
Filter异步调用与Servlet一样。
改进的ServletAPI(上传文件)
-
改进内容
- HttpServletRequest增加了对上传文件的支持
- ServletContext允许通过编程的方式动态注册Servlet、Filter
-
HttpServletRequest提供了如下两个方法处理文件的上传
Part getPart(String name)
根据名称获取文件上传域Collection<Part> getParts()
获取所有文件上传域
-
上传文件时一定要为表单域设置enctype属性,它表示表单数据的编码方式,有如下三个值:
application/x-www-form-urlencoded (默认),它只处理表单里的value属性值,它会将value值处理成URL编码方式。如果此时表单域里有上传文件的域(type=”file”),则只会获取该文件在上传者电脑里的绝对路径串,该串没什么实际意义。
- multipart/form-data 此处编码方式会以二制流的方式来处理表单数据,此时会将文件内容也封装到请求参数里。
- texst/plain 当表单的action属性为mailto:URL的形式时比较方便,主要适用于直接通过表单发送邮件的方式
-
上传文件的Servlet需要加上@MultipartConfig注解
-
通过request获取的Part对象就可以操作文件域了
-
示例
@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应用设置初始化参数。
相关文章:

Servlet3.0 新特性全解
Servlet3.0新特性全解 tomcat 7以上的版本都支持Servlet 3.0 Servlet 3.0 新增特性 注解支持;Servlet、Filter、Listener无需在web.xml中进行配置,可以通过对应注解进行配置;支持Web模块;Servlet异步处理;文件上传AP…...

PAT A1045 Favorite Color Stripe
1045 Favorite Color Stripe 分数 30 作者 CHEN, Yue 单位 浙江大学 Eva is trying to make her own color stripe out of a given one. She would like to keep only her favorite colors in her favorite order by cutting off those unwanted pieces and sewing the rem…...

真实业务场景使用-门面模式(外观)设计模式
1.前言 最近接到要修改的业务功能,这个业务增删改查很多功能都需要校验时间,比如: 1.失效时间不能超过自己父表的失效时间, 2.失效时间不能是当前时间 3.失效时间不能早于生效时间 类似这样的不同的判断还有很多,…...

基于多动作深度强化学习的柔性车间调度研究(Matlab代码实现)
💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…...

出口亚马逊平衡车CE/UKCA认证注意事项
平衡车UKC认证 CE认证 认证项目:BS EN/EN71-1-2-3 UKCA认证标志与CE认证标志有什么不同? UKCA标记过程基本上遵循与CE标记相同的规则和规定。大多数制造商仍然可以根据测试结果和其他技术文档自行声明他们的产品,但在特定情况下,他们需要从第…...

云原生环境下的安全实践:保护应用程序和数据的关键策略
文章目录 云原生环境下的安全实践:保护应用程序和数据的关键策略一.安全措施和实践1. 身份和访问管理:2. 容器安全:3. 网络安全:4. 日志和监控:5. 持续集成和持续交付(CI/CD)安全:6.…...

vue 改变数据后,数据变化页面不刷新
文章目录 导文文章重点方法一:使用this.$forceUpdate()强制刷新方法二:Vue.set(object, key, value)方法三:this.$nextTick方法四:$set方法 导文 在vue项目中,会遇到修改完数据,但是视图却没有更新的情况 v…...

【Qt编程之Widgets模块】-006:QSortFilterProxyModel代理的使用方法
QSortFilterProxyModel是model的代理,不能单独使用,真正的数据需要另外的一个model提供,它的工鞥呢是对被代理的model(source model)进行排序和过滤。所谓过滤:也就是说按着你输入的内容进行数据的筛选,因为器过滤功能…...

上林赋 汉 司马相如
亡是公听然而笑曰:“楚则失矣,而齐亦未为得也。夫使诸侯纳贡者,非为财币,所以述职也。封疆画界者,非为守御,所以禁淫也。今齐列为东藩,而外私肃慎,捐国逾限,越海而田&…...

7.对象模型
对象模型 信号和槽 信号和槽是一种用于对象之间通信的机制。信号是对象发出的通知,槽是用于接收这些通知的函数。 当对象的状态发生变化时[按钮被点击],它会发出一个信号[clicked()],然后与该对象连接的槽函数将被自动调用。 若某个信号与多…...

机器学习——基本概念
如何选择合适的模型评估指标?AUC、精准度、召回率、F1值都是什么?如何计算?有什么优缺点? 选择合适的模型评估指标需要结合具体的问题场景,根据不同的需求来选择不同的指标。以下是几个常用的评估指标: AUC…...

Qt---感觉挺重要的部分
目录 一、讲述Qt信号槽机制与优势与不足 二、Qt信号和槽的本质是什么 三、描述QT中的文件流(QTextStream)和数据流(QDataStream)的区别 四、描述QT的TCP通讯流程 服务端:(QTcpServer) 客户端:(QTcpSocket…...

springboot+vue家乡特色推荐系统(源码+文档)
风定落花生,歌声逐流水,大家好我是风歌,混迹在java圈的辛苦码农。今天要和大家聊的是一款基于springboot的家乡特色推荐系统。项目源码以及部署相关请联系风歌,文末附上联系信息 。 💕💕作者:风…...

在Shell脚本中通过ssh从脚本运行函数
文章目录 在Shell脚本中通过ssh从脚本运行函数declare -f 和typset -f,这两个命令有什么区别declare -f 和typset -f,这两个命令可以通过ssh运行脚本中的函数吗如果我有main.sh和util.sh,并且在main.sh中引用了util.sh,该怎么办&a…...

简单学习一下 MyBatis 动态SQL使用及原理
MyBatis 是一个优秀的持久层框架,它提供了丰富的 SQL 映射功能,可以让我们通过 XML 或注解方式来定义 SQL 语句。它很大程度上简化了数据库操作,提高了开发效率。动态 SQL 是其中一个非常重要的功能,可以让我们根据不同的条件动态…...

WhatsApp如何让客户参与变得更简单?
WhatsApp对你的品牌来说可能和Twitter和Facebook一样重要,你可能已经把它们纳入你的社交媒体战略。 是的,WhatsApp不仅仅可以用来给同事发短信或与远方的亲戚视频聊天,它也适用于商业。 在发展WhatsApp业务时,小企业主得到了最优…...

记一次 MySQL 主从同步异常的排查记录,百转千回
本文主要内容如下: 一、现象 最近项目的测试环境遇到一个主备同步的问题: 备库的同步线程停止了,无法同步主库的数据更改。 备库报错如下: 完整的错误信息: Relay log read failure: Could not parse relay log even…...

Cpython的多线程技术之痛
历史原因 在Python官网下载的默认解释器是采用C语言编写的Cpython解释器。在Python语言开发之初,计算机都是单核CPU,每个单核CPU同一时刻只能运行一个线程。为了模拟多线程工作,这里采用了模拟机制,让不同线程根据时间片段&#…...

NDK OpenGL离屏渲染与工程代码整合
NDK系列之OpenGL离屏渲染与工程代码整合,本节主要是对上一节OpenGL渲染画面效果代码进行封装设计,将各种特效代码进行分离解耦,便于后期增加其他特效。 实现效果: 实现逻辑: 1.封装BaseFilter过滤器基类,…...

Python基础入门编程代码练习(二)
一、求1~100之间不能被3整除的数之和 循环条件:i<100循环操作 实现代码如下: def sums():sum 0for num in range(1, 101):if num % 3 ! 0:sum numprint("1~100之间不能被3整除的数之和为:%s" % (sum))sums() print("1~…...

C# | 对象池
对象池 文章目录 对象池前言什么是对象池对象池的优点对象池的缺点 实现思路示例代码 结束语 前言 当我们开发一个系统或者应用程序时,我们通常需要创建很多的对象,这些对象可能是线程、内存、数据库连接、文件句柄等等。在某些情况下,我们需…...

CSS小技巧之圆形虚线边框
虚线相信大家日常都用的比较多,常见的用法就是使用 border-style 控制不同的样式,比如设置如下边框代码: border-style: dotted dashed solid double;这将设置顶部的边框样式为点状,右边的边框样式为虚线,底部的边框样…...

QString与QByteArray互相转换的方法
QString与QByteArray互相转换的方法 [1] QString与QByteArray互相转换的方法QString转QByteArray方法QByteArray转QString方法QByteArray类同样不以’\0’为结尾QByteArray转QString,主要用buf.toHex()即可 [2] Qt开发串口通讯软件中的数据转换问题1.读取串口命令-Q…...

Springboot +Flowable,设置流程变量的方式(一)
一.简介 为什么需要流程变量。 举个例子,假设有如下一个流程,截图如下: 这是一个请假流程,那么谁请假、请几天、起始时间、请假理由等等,这些都需要说明,不然领导审批的依据是啥?那么如何传递…...

机器学习13(正则化)
文章目录 简介正则化经验风险和结构风险过拟合正则化建模策略 逻辑回归逻辑回归评估器 练习评估器训练与过拟合实验评估器的手动调参 简介 这一节详细探讨关于正则化的相关内容,并就 sklearn 中逻辑回归(评估器)的参数进行详细解释由于 skle…...

并发编程学习(十一):原子数组、
1、数组类型的原子类 原子数组类型,这个其实和AtomicInteger等类似,只不过在修改时需要指明数组下标。 CAS是按照来根据地址进行比较。数组比较地址,肯定是不行的,只能比较下标元素。而比较下标元素,就和元素的…...

递归到动态规划:省去枚举行为
如果在动态规划的过程中没有枚举行为,那严格位置依赖和傻缓存的方式并没有太大区别,但是当有枚举行为的时候(一个位置依赖于多个位置),那严格位置依赖是有优化空间的,枚举行为也许可以省去,题目…...

服务(第二十一篇)mysql高级查询语句(二)
①视图表: 视图表是虚拟表,用来存储SQL语句的定义 如果视图表和原表的字段相同,是可以进行数据修改的; 如果两者的字段不通,不可以修改数据。 语法: 创建:create view 试图表名 as ... 查…...

MYSQL高可用配置(MHA)
1、什么是MHA MHA(Master High Availability)是一套优秀的MySQL高可用环境下故障切换和主从复制的软件。 MHA 的出现就是解决MySQL 单点的问题。 MySQL故障切换过程中,MHA能做到0-30秒内自动完成故障切换操作。 MHA能在故障切换的过程中最大…...

单精度浮点数与十进制数据相互转换
一、float基础: Float类型占4个字节,也就是32bit,其中最高位是符号位,2~9位是指数位,后边的23bit是数值位.如下所示 大部分数据的二进制形式都可以用科学计数法表示,即1.m*2^n这种形式,只要知道m和n,就能确定一个数值 二、小数位如何转变为二进制: 下面…...