百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 热门文章 > 正文

Servlet3.0新特性

bigegpt 2024-09-11 01:04 3 浏览

Servlet3.0新特性

主要内容

知识点1: 非阻塞
知识点2: 注解
知识点3: 文件上传

一.非阻塞

示例

我们编写一个PrintServlet,在一个死循环中打印输出:

out.println(Thread.currentThread().getName()+": Hello,我是PrintServlet,马上要进入死循环打印了!");
out.close();
while(true){
 System.out.println("正在打印,请稍后......");
}

在之前版本的Servlet中,访问该Servlet后,再次访问就不再有响应,因为当前线程阻塞,在处理死循环 。

http://localhost:8080/servlet_demo/PrintServlet.do
请求PrintServlet,在后台死循环打印。
http://localhost:8080/servlet_demo/PrintServlet.do
请求PrintServlet,处于阻塞状态,一直在加载状态。

Servlet3.0版本,增加了非阻塞特性:

接收请求后,启动一个异步线程处理请求,客户端可以继续请求这个Servlet,而不必等待上一次请求返回;

默认情况下,Servlet3.0版本Servlet并没有这个特性,需要在web.xml中进行配置:

 <servlet>
 <servlet-name>PrintServlet</servlet-name>
 <servlet-class>servlet.PrintServlet.do</servlet-class>
 <async-supported>true</async-supported>
</servlet>
?
http://localhost:8080/servlet_demo/PrintServlet.do
请求PrintServlet,处于非阻塞状态,依然可以响应

二.注解

Servlet3.0中可以使用注解(annotation)替代web.xml进行配置;

通常用的注解有五种类型:

@WebServlet:对Servlet进行配置
@WebInitParam:配置Servlet初始化参数
@WebFilter:配置过滤器
@WebListener :配置监听器
@MultipartConfig:对文件上传的支持

1.@WebServlet注解

对Servlet进行配置示例,包括的属性如下,这些属性除了vlaue或urlPatterns是必选的,其他的都是可选的:
1)name:等价于web.xml配置文件中的 <servlet-name>。如果没有指定, Servlet 的<servlet-name>取值为类的全限定名,比如XXX.XXX.XXX。
2)urlPatterns:等价于web.xml配置文件中的 <url-pattern> 标签
3)value:等价于 urlPatterns 属性。
4)loadOnStartup:等价于web.xml配置文件中的<load-on-startup> 标签
5)initParams :等价于web.xml配置文件中的<init-param> 标签,他的参数是@WebInitParam注解的集合(此注解之后介绍)
6)asyncSupported:等价于web.xml配置文件中的<async-supported> 标签
7)description:等价于web.xml配置文件中的<description> 标签
8)displayName:等价于web.xml配置文件中的 <display-name> 标签
?

示例

@WebServlet(urlPatterns = {"/demo"}, 
asyncSupported = true, 
loadOnStartup = -1, 
name = "DemoServlet", 
displayName = "chinasofti", 
initParams = {
@WebInitParam(name = "username", value = "etc") 
} 
) 
该注解同下面xml配置相同
<servlet>
 <display-name> DemoServlet </display-name>
 <servlet-name>servlet.DemoServlet</servlet-name>
 <servlet-class>footmark.servlet.SimpleServlet</servlet-class>
 <load-on-startup>-1</load-on-startup>
 <async-supported>true</async-supported>
 <init-param>
 <param-name>username</param-name>
 <param-value>etc</param-value>
 </init-param>
</servlet>
<servlet-mapping>
 <servlet-name> DemoServlet </servlet-name>
 <url-pattern>/demo</url-pattern>
</servlet-mapping>
?

2.@WebInitParam注解

@WebInitParam:配置Servlet初始化参数,常用属性有三个,这三个属性当中只有description为可选属性:
name:等价于web.xml配置文件中的 <param-name>
value :等价于web.xml配置文件中的<param-value>
description:等价于web.xml配置文件中的<description>
?

示例

initParams = {
@WebInitParam(name = "username", value = "qianfeng") 
}
同下面xml文件配置
<init-param>
 <param-name>username</param-name>
 <param-value>qianfeng</param-value>
 </init-param>
?

3.@WebFilter注解

@WebFilter:配置过滤器此注解为声明一个过滤器,主要属性有以下几个。
在这些属性当中value、urlPatterns、servletNames 三个属性至少要包含其中的一个,并且 value 和 urlPatterns 属性只能有一个,如果两个同时配置,一般情况下value取值将会被忽略。其他的都是可选属性。
filterName:等价于web.xml配置文件中的 <filter-name>标签
value:该属性等价于 urlPatterns 属性
urlPatterns:等价于web.xml配置文件中的 <url-pattern> 标签
servletNames:指定该过滤器将应用的 范围。如果是注解的话取值是 @WebServlet 中的 name 属性的取值,如果servlet这 web.xml 中配置的话,取值是 <servlet-name> 的取值
dispatcherTypes:过滤器的转发模式。取值包括:
ASYNC(异步)、ERROR(错误)、FORWARD(请求转发)、INCLUDE(包含)、REQUEST(请求)。
initParams:等价于web.xml配置文件中的<init-param> 标签
asyncSupported:等价于web.xml配置文件中的<async-supported> 标签
description:等价于web.xml配置文件中的<description> 标签
displayName:等价于web.xml配置文件中的<display-name> 标签
?

示例

@WebFilter(servletNames = {"LoginServlet"},filterName="LoginFilter")
public class LoginFilter implements Filter{
........
同下面xml配置
<filter> 
 <filter-name> LoginFilter </filter-name> 
 <filter-class>filter.LoginFilter </filter-class> 
</filter> 
<filter-mapping> 
 <filter-name> LoginFilter </filter-name> 
 <servlet-name> LoginServlet </servlet-name> 
</filter-mapping>
?

4.WebListener 注解

@WebListener:配置监听器,此注解是用来声明监听器,它主要的属性只有一个:
value:这个属性表示的是监听器的描述信息,整个配置可以简写成@WebListener("XXX")

示例

@WebListener("this is a listener")
public class CounterListener implements ServletContextListener{
……
同下面xml文件配置
<listener>
 <listener-class>listener.CounterListener</listener-class>
</listener>
?

三.文件上传

Servlet3.0以前版本没有对文件上传进行支持,只能用第三方组件实现;

Servlet3.0中对文件上传进行了支持,核心接口是Part接口,该接口中的核心方法如下:

方法声明方法描述void delete()删除part对象对应文件项的基本存储,包括删除任何相关的临时磁盘文件String getContentType()请求上传文件的类型String getHeader(String name):获取上传文件内容的指定名字的请求头信息Collection<String> getHeaderNames()获取上传文件请求的全部请求头名称,返回的是一个包含请求头名称的集合Collection<String> getHeaders(String name)通过请求头名称,获取全部对应的请求信息,返回的是一个集合InputStream getInputStream()获取输入流String getName()获取控件的名字Long getSize()获取上传文件的大小void write(String fileName)将文件写入到物理磁盘

在Servlet3.0版本中,请求接口提供了获取Part实例的方法;

方法声明方法描述Part getPart(String name)根据上传控件名称获取上传文件对应的Part对象Collection<Part> getParts()获取所有上传文件对应的Part对象。

示例

upload.jsp:
?
<form action="uploadServelt" method="post" enctype="multipart/form-data“ > 
 文件1:<input type="file" name="myfile1"/><br/> 
 文件2:<input type="file" name="myfile2"/><br/> 
 <input type="submit" name="submit" value="upload"/> 
</form> 
?

定义UploadServlet,实现上传功能;注解内容如下:

@WebServlet("/uploadServelt")
@MultipartConfig( 
 location = "E:\\upload",//文件存放路径
 maxFileSize = 8388608,//最大上传文件大小 
 fileSizeThreshold = 819200,//当数据量大于该值时,内容将被写入文件。
 maxRequestSize = -1 //针对该 multipart/form-data 请求最大数量,默认值为 -1,表示没有限制。以字节为单位。 
) 
?

定义UploadServlet,实现上传功能;核心代码如下 :

 //获取所有上传文件对应的Part对象
 Collection<Part> parts = request.getParts(); 
 //遍历上传文件对应的part对象,将文件写入上传文件目录 
 for (Iterator<Part> iterator = parts.iterator(); iterator.hasNext();) { 
 Part part = iterator.next(); 
 //获取content-disposition请求头,提取文件名称 
 String cotentDisposition = part.getHeader("content-disposition");
 System.out.println("cotent-disposition="+cotentDisposition);
 String fileName = null; 
 //使用正则表达是部分匹配,获取上传文件名称
 Pattern pattern = Pattern.compile("filename=\".+\""); 
 Matcher matcher = pattern.matcher(cotentDisposition); 
 if(matcher.find()){ 
 fileName = matcher.group(); 
 System.out.println("fileName="+fileName);
 fileName = fileName.substring(10, fileName.length()-1); 
 System.out.println("subFileName="+fileName);
 } 
 if(fileName!=null){ 
 part.write(fileName); 
 } 
?

定义过滤器,解决文件名统一编码问题;核心代码如下 :

 public void init(FilterConfig filterConfig) throws ServletException {
 //初始化
 glEncoding = filterConfig.getInitParameter("encoding");
 }
?
 public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
 throws IOException, ServletException {
 if (glEncoding != null) {
 // request编码
 request.setCharacterEncoding(glEncoding);
 // response编码
 response.setContentType("text/html;charset=" + glEncoding);
 }
 // 传给下一个过滤器
 chain.doFilter(request, response);
 }
?

四.常见问题

Servlet3.0的非阻塞特性是什么意思?如何实现?
Servlet3.0中有哪几个常用的注解类型?
Servlet3.0对文件上传进行了哪些支持?

五.总结

Servlet3.0中增加了非阻塞特性支持,可以在web.xml中或者使用注解进行配置,使得Servlet可以异步处理请求;
Servlet3.0可以使用注解替代web.xml的部分内容,常用的注解类型有@WebServlet、@WebFilter、@WebListener、@WebInitParam。
Servlet3.0中对文件上传进行了支持,提供了Part接口以及@MultipartConfig注解,可以方便地实现文件上传;

相关推荐

最全的MySQL总结,助你向阿里“开炮”(面试题+笔记+思维图)

前言作为一名编程人员,对MySQL一定不会陌生,尤其是互联网行业,对MySQL的使用是比较多的。对于求职者来说,MySQL又是面试中一定会问到的重点,很多人拥有大厂梦,却因为MySQL败下阵来。实际上...

Redis数据库从入门到精通(redis数据库设计)

目录一、常见的非关系型数据库NOSQL分类二、了解Redis三、Redis的单节点安装教程四、Redis的常用命令1、Help帮助命令2、SET命令3、过期命令4、查找键命令5、操作键命令6、GET命...

netcore 急速接入第三方登录,不看后悔

新年新气象,趁着新年的喜庆,肝了十来天,终于发了第一版,希望大家喜欢。如果有不喜欢看文字的童鞋,可以直接看下面的地址体验一下:https://oauthlogin.net/前言此次带来得这个小项目是...

精选 30 个 C++ 面试题(含解析)(c++面试题和答案汇总)

大家好,我是柠檬哥,专注编程知识分享。欢迎关注@程序员柠檬橙,编程路上不迷路,私信发送以下关键字获取编程资源:发送1024打包下载10个G编程资源学习资料发送001获取阿里大神LeetCode...

Oracle 12c系列(一)|多租户容器数据库

作者杨禹航出品沃趣技术Oracle12.1发布至今已有多年,但国内Oracle12C的用户并不多,随着12.2在去年的发布,选择安装Oracle12c的客户量明显增加,在接下来的几年中,Or...

flutter系列之:UI layout简介(flutter-ui-nice)

简介对于一个前端框架来说,除了各个组件之外,最重要的就是将这些组件进行连接的布局了。布局的英文名叫做layout,就是用来描述如何将组件进行摆放的一个约束。在flutter中,基本上所有的对象都是wi...

Flutter 分页功能表格控件(flutter 列表)

老孟导读:前2天有读者问到是否有带分页功能的表格控件,今天分页功能的表格控件详细解析来来。PaginatedDataTablePaginatedDataTable是一个带分页功能的DataTable,...

Flutter | 使用BottomNavigationBar快速构建底部导航

平时我们在使用app时经常会看到底部导航栏,而在flutter中它的实现也较为简单.需要用到的组件:BottomNavigationBar导航栏的主体BottomNavigationBarI...

Android中的数据库和本地存储在Flutter中是怎样实现的

如何使用SharedPreferences?在Android中,你可以使用SharedPreferencesAPI来存储少量的键值对。在Flutter中,使用Shared_Pref...

Flet,一个Flutter应用的实用Python库!

▼Flet:用Python轻松构建跨平台应用!在纷繁复杂的Python框架中,Flet宛如一缕清风,为开发者带来极致的跨平台应用开发体验。它用最简单的Python代码,帮你实现移动端、桌面端...

flutter系列之:做一个图像滤镜(flutter photo)

简介很多时候,我们需要一些特效功能,比如给图片做个滤镜什么的,如果是h5页面,那么我们可以很容易的通过css滤镜来实现这个功能。那么如果在flutter中,如果要实现这样的滤镜功能应该怎么处理呢?一起...

flutter软件开发笔记20-flutter web开发

flutterweb开发优势比较多,采用统一的语言,就能开发不同类型的软件,在web开发中,特别是后台式软件中,相比传统的html5开发,更高效,有点像c++编程的方式,把web设计出来了。一...

Flutter实战-请求封装(五)之设置抓包Proxy

用了两年的flutter,有了一些心得,不虚头巴脑,只求实战有用,以供学习或使用flutter的小伙伴参考,学习尚浅,如有不正确的地方还望各路大神指正,以免误人子弟,在此拜谢~(原创不易,转发请标注来...

为什么不在 Flutter 中使用全局变量来管理状态

我相信没有人用全局变量来管理Flutter应用程序的状态。毫无疑问,我们的Flutter应用程序需要状态管理包或Flutter的基本小部件(例如InheritedWidget或St...

Flutter 攻略(Dart基本数据类型,变量 整理 2)

代码运行从main方法开始voidmain(){print("hellodart");}变量与常量var声明变量未初始化变量为nullvarc;//未初始化print(c)...