Servlet3 简单测试

embedded/2025/1/23 14:20:56/

1.注解定义servlet的时候如果 @WebServlet("some") 如果url-pattern前面不加 / 回报以下的错误,和web.xml中定义是一致的。

java.lang.IllegalArgumentException: Invalid [some] in servlet mapping

2.urlPatterns = {"/some" , "/aaa" , "/bbb"} 和 value= {"/some" , "/aaa" , "/bbb"} 的作用是一样的都是用来定义访问改Servlet的 url-pattern 但是只能用一个 不能两个同事出现

3.如果同一个Servlet的类 既在web.xml中定义 又通过注解@WebServlet定义 那么最终只会注册一个Servlet实例 url-pattern 为 web,xml的url-pattern 和 注解中url-pattern 的并集

例如: web.xml 中 url-pattern为 /ccc @WebServlet中定义的 url-pattern 为 /aaa /bbb .那么该Servlet的最终 url-pattern 为 /aaa /bbb /ccc

4.如果web.xml中Servlet配置如下

 <servlet><servlet-name>Some-Servlet</servlet-name><servlet-class>com.fll.servletannotation.servlets.SomeServlet</servlet-class><init-param><param-name>address</param-name><param-value>北京</param-value></init-param>
</servlet><servlet-mapping><servlet-name>Some-Servlet</servlet-name><url-pattern>/ccc</url-pattern>
</servlet-mapping>

 用注解配置如下

java">@WebServlet(urlPatterns = {"/some" , "/aaa" , "/bbb"} ,initParams = {@WebInitParam(name = "name" , value = "冯亮亮") , @WebInitParam(name = "age" , value = "20")})
public class SomeServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {response.setContentType("text/html;charset=UTF-8");PrintWriter writer = response.getWriter();writer.write("我是通过注解定义的Servlet3.0 <br>");Enumeration<String> initParameterNames = this.getInitParameterNames();while (initParameterNames.hasMoreElements()){String name = initParameterNames.nextElement();String value = this.getInitParameter(name);writer.write("name=" + name + " value=" + value + "<br>");}}
}

那么当通过 /some /aaa /bbb 访问是返回的是:
我是通过注解定义的Servlet3.0
name=name value=冯亮亮
name=age value=20

当通过 /ccc 访问的时候 返回的是:
我是通过注解定义的Servlet3.0
name=address value=北京

 4.如果 同一个 Filter的类 既在 web.xml url-pattern=/* 中定义了 Filter 又通过 @WebFilter("/*") 定义Filter那么相当于注册的两个独立的 Filter 实例。一个请求如果既符合 web.xml 中的url-pattern 又符合 @WebFilter("/*") 中的 url-pattern 那么这两个 Filter 都会被执行

5.如果同一个 Listener的类 同时在 web.xml 和 @WebListener中定义 Listener 那么只会注册一个 Listener 实例

6. 当 web.xml 中的 metadata-complete="true" 时所有注解的配置都会失效 false时 注解配置生效

<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaeehttp://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"version="4.0" metadata-complete="true"></web-app>

 7.上传文件

java">@MultipartConfig
@WebServlet("/upload")
public class UploadServlet extends HttpServlet {@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {Part filePart = request.getPart("file");Collection<String> headers = filePart.getHeaderNames();for (String headerName : headers){String header = filePart.getHeader(headerName);System.out.println(headerName + "=================" + header);}//打印结果//content-disposition=================form-data; name="file"; filename="1501131329.png"//content-type=================image/png//获取该 part 的文件名String fileName = filePart.getSubmittedFileName();String realPath = this.getServletContext().getRealPath("/upload");String filePath = realPath + "/" + fileName;filePart.write(filePath);}
}

注意:(1)Servlet类上添加 @MultipartConfig
Annotation that may be specified on a {@link javax.servlet.Servlet} class, indicating that instances of the Servlet expect requests that conform to the multipart/form-data MIME type.

该注解的注释大概意思是: 该注解是被放在Servlet类上的,表明这个Servlet类的实例希望请求遵守 multipart/form-data MIME type.

8. Servlet异步
获取AsyncContext 对象的时候要用 AsyncContext asyncContext = request.startAsync();

千万不要使用AsyncContext asyncContext = request.getAsyncContext(); 这个方法是一个递归调用

如果该Servlet的属性 asyncSupported = false 的时候 执行上面的语句回报以下的错误

the processing chain do not support async [com.fll.servletannotation.servlets.AsyncServlet]

java.lang.IllegalStateException: 当前链的筛选器或servlet不支持异步操作。

9.具体代码

java">/*** @author fll*/
@WebServlet(urlPatterns = "/async" , asyncSupported = true)
public class AsyncServlet extends HttpServlet {private static Logger logger = LoggerFactory.getLogger(AsyncServlet.class);@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {System.out.println("================================");response.setContentType("text/html;charset=UTF-8");final PrintWriter writer = response.getWriter();writer.write("主线程开始<br>");//AsyncContext asyncContext = request.getAsyncContext();final AsyncContext asyncContext = request.startAsync();asyncContext.addListener(new AsyncListener() {@Overridepublic void onComplete(AsyncEvent event) throws IOException {logger.info("=============================== onComplete");}@Overridepublic void onTimeout(AsyncEvent event) throws IOException {logger.info("=============================== onTimeout");}@Overridepublic void onError(AsyncEvent event) throws IOException {logger.info("=============================== onError");}@Overridepublic void onStartAsync(AsyncEvent event) throws IOException {logger.info("=============================== onStartAsync");}});//asyncContext.setTimeout(3000);asyncContext.start(new Runnable() {@Overridepublic void run() {for (int i = 0; i < 10; i++) {try {Thread.sleep(500);System.out.println("================ " + i);writer.write("================ " + i + "<br>");} catch (InterruptedException e) {e.printStackTrace();}}asyncContext.complete();//asyncContext.dispatch("show.jsp");//asyncContext.dispatch("show.jsp");等价于 request.getRequestDispatcher("show.jsp").include(request , response);同样有通知主线程子线程已经执行完毕的作用  也就是该方法也会将response中的数据写道浏览器中}});writer.write("主线程结束<br>");}}

以上代码 浏览器看到的内容是:
主线程开始
主线程结束
================ 0
================ 1
================ 2
================ 3
================ 4
================ 5
================ 6
================ 7
================ 8
================ 9

说明执行顺序是 主线程线执行完 然后等待asyncContext.complete();执行 一起把数据写到浏览器

如过将超时事件设置为 2秒 打印结果如下:

主线程开始

主线程结束

================ 0

================ 1

================ 2

================ 3

================ 4

说明 当超时的时候也会自动将response中的数据写到浏览器中

10.同步线程执行完成得通知 asyncContext.complete(); 如果不执行该语句 主线程会一直等待异步线程的执行完成 知道超时 默认的超时时间是 30秒。也可以asyncContext.setTimeout(3000);修改超时时间 超时之后监听器的onTimeout方法会被回调。

 


http://www.ppmy.cn/embedded/156319.html

相关文章

微前端qiankun的部署

微前端qiankun的部署 本地开发主应用配置启动端口子应用配置启动端口测试环境部署:场景 1:主应用和微应用部署到同一个服务器(同一个 IP 和端口)微应用都放在在一个特殊名称(不会和微应用重名)的文件夹下主应用配置子应用配置配置nginx本地开发 主应用配置启动端口 打开…

1.22双指针刷题

acwing799最长连续不重复子序列问题 acwing800数组元素的目标和 acwing2816判断子序列 洛谷AT_abc352_b Typing CF1968B Prefiquence交不了 #include<iostream> #include<cstring> using namespace std; int n,a,b; string s,t; int k;int main(){cin>…

招商蛇口:于高新 CID,启幕品质人居新篇

在房地产行业的风云变幻中&#xff0c;招商蛇口始终以卓越之姿领航前行。在第二十一届&#xff08;2024&#xff09;蓝筹年会上&#xff0c;招商蛇口凭借财务稳健、产品与运营等多方面的出色表现&#xff0c;成功入选 “可持续蓝筹价值企业”。在 2024 第十届产业园区大会上&am…

在MyBatis的XML映射文件中,<trim>元素所有场景下的完整使用示例

在MyBatis的XML映射文件中&#xff0c;<trim>元素用于动态地添加SQL语句的一部分&#xff0c;例如SET或WHERE子句&#xff0c;并可以处理前缀、后缀以及多余的逗号或AND等连接符。下面是一些<trim>元素在不同场景下的完整使用示例&#xff1a; 示例1: 使用<trim…

数据链路层协议

数据链路层协议 1、MA网络&#xff1a; 以太网协议 定义&#xff1a;以太网不是一个网络&#xff0c;而是一个协议&#xff0c;传输标准EthernetII 类型帧的网络 特征&#xff1a;多路访问&#xff0c;广播式的网络&#xff0c;需要使用MAC地址对设备进行区分和标识 构建方法…

线程池的数据结构是什么 为什么会占用堆内存 线程池是一个对象吗

线程池是一种用于管理和复用线程以执行多个任务的设计模式&#xff0c;它通过预先创建一组线程&#xff0c;并将这些线程重复用于执行提交给线程池的任务&#xff0c;从而减少因频繁创建和销毁线程带来的开销。在Java中&#xff0c;线程池通常通过java.util.concurrent包下的Th…

Pandas 数据分析(二)【股票数据】

股票数据分析 写在前面题目背景021 加载股票数据到CSV文件022 查看基本信息和数据统计023 更改索引列为普通数据列024 给数据添加月份和年份025 计算每年的平均收盘价026 找到收盘价最低的数据行027 筛选出部分数据列028 设置日期列为索引列029 删除不需要的数据列030 对数据列…

CSS 默认值

HTML 元素的 CSS 默认值 下表显示了所有 HTML 元素的默认 CSS 浏览器值。 元素默认的 CSS 值a:link color: (internal value);text-decoration: underline;cursor: auto; a:visited color: (internal value);text-decoration: underline;cursor: auto; a:link:activecolor: (…