57_2设置Servlet模板、Servlet线程安全问题、跳转

设置Servlet模板

设置Servlet模板
再创建类就有了
Servlet模板
模板代码

#if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "")package ${PACKAGE_NAME};#end
#parse("File Header.java")import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;public class ${Class_Name} extends HttpServlet {@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException ,IOException {
this.doPost(request, response);
}@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {}
}

Servlet线程安全问题

面试题:Servlet是否是单例的?

不是单例,但是一般情况下是单例,

如果Servlet实现了SingleThreadModel接口,该Servlet对象在第一次线程阻塞时会创建新的对象 – 已过时

出现原因

多个客户端访问同一个Servlet中的资源时,有可能会出现线程安全问题

@WebServlet("/ser01")
public class Servlet01 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {this.doPost(request, response);}private  int num;@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {num++;try {Thread.sleep(5000);} catch (InterruptedException e) {throw new RuntimeException(e);}response.getWriter().println(num);}
}

这里直接输入指定Servlet访问
添加运行
单独运行
单独运行
浏览器1运行【num++】,同时再开个浏览器运行访问【num++】,就会新开的num变成1+1+1=3
未实现接口两个浏览器同时运行

解决方案:

加锁、使用线程安全的类

1.将Servlet实现SingleThreadModel(已过时),因为当线程阻塞,就会创建新的Servlet对象

2.利用线程锁机制, synchronized或lock

经验:尽可能的不要使用成员变量,而是使用局部变量

实现SingleThreadModel接口
public class Servlet01 extends HttpServlet implements SingleThreadModel{
public Servlet01() {System.out.println("Servlet01被创建了");}......}

添加无参构造,实现接口
添加无参构造,实现接口
再运行
实现接口运行
未实现接口输出个数【单例】
未实现接口输出个数
实现接口,在阻塞【非单例】情况下会创建新的servlet对象,虽然解决了问题,但不可取
创建次数

加锁
@WebServlet("/ser01")
//public class Servlet01 extends HttpServlet implements SingleThreadModel {
public class Servlet01 extends HttpServlet {public Servlet01() {System.out.println("Servlet01被创建了");}@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {this.doPost(request, response);}private int num;@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {synchronized (this){num++;try {Thread.sleep(5000);} catch (InterruptedException e) {throw new RuntimeException(e);}response.getWriter().println(num);}}
}

跳转

方式:转发和重定向
欢迎页面:
跳转

情况:

  1. 页面 跳 页面
    页跳页
  1. 页面 跳 Servlet
    页跳s01页跳s01
    页跳s02页跳s02
    页跳s03
    页跳s03
  1. Servlet 跳 Servlet
    s跳s01s跳s01
    s跳s02s跳s02
  1. Servlet 跳 页面
    s跳页01s跳页01
    s跳页02s跳页02

页面

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body><h1>页面 跳 页面</h1><a href="page01.html">跳转到页面1</a><br /><button onclick="fun01()">跳转到页面1</button><br /><form action="page01.html" method="post"><input type="submit" value="跳转到页面1"></form><br /><h1>页面 跳 Servlet</h1><a href="ser01?username=xxx&password=123&nickname=爽了">跳转到Servlet01</a><br /><!--get请求--><button onclick="fun02()">跳转到Servlet01</button><br /><!--get请求--><form action="ser01" method="post"><!--可选请求方式-->账号:<input type="text" name="username"><br />密码:<input type="password" name="password"><br />昵称:<input type="text" name="nickname"><br /><input type="submit" value="跳转到Servlet01"></form><br /><h1>Servlet 跳 Servlet</h1><p>转发方式:Servlet02 -> Servlet03</p><p>浏览器地址栏输入:http://localhost:8080/MyDay18_Web03_war_exploded/ser02</p><p>重定向方式:Servlet04 -> Servlet05</p><p>浏览器地址栏输入:http://localhost:8080/MyDay18_Web03_war_exploded/ser04</p><h1>Servlet 跳 页面</h1><p>转发方式:Servlet06 -> page02.html</p><p>浏览器地址栏输入:http://localhost:8080/MyDay18_Web03_war_exploded/ser06</p><p>重定向方式:Servlet07 -> page03.html</p><p>浏览器地址栏输入:http://localhost:8080/MyDay18_Web03_war_exploded/ser07</p><script type="text/javascript" >function  fun01(){window.location = "page01.html";}function fun02() {window.location = "ser01?username=xxx&password=123&nickname=爽了";}
</script>
</body>
</html>

java代码

@WebServlet("/ser01")
public class Servlet01 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {this.doPost(request, response);}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {request.setCharacterEncoding("UTF-8");response.setContentType("text/html;charset=UTF-8");String username = request.getParameter("username");String password = request.getParameter("password");String nickname = request.getParameter("nickname");System.out.println("Servlet01接收到来自客户端的请求了:" + username + " -- " + password + " -- " + nickname);response.getWriter().println(username + " -- " + password + " -- " + nickname);}
}
@WebServlet("/ser02")
......
//doPost方法不同
//转发方式
request.getRequestDispatcher("ser03").forward(request,response);
@WebServlet("/ser03")
......
//doPost方法不同
System.out.println("Servlet03接受到请求了");
@WebServlet("/ser04")
......
//doPost方法不同
//重定向方式
response.sendRedirect("ser05");
@WebServlet("/ser05")
......
//doPost方法不同
System.out.println("Servlet05接受到请求了");
@WebServlet("/ser06")
......
//doPost方法不同
//转发方式
request.getRequestDispatcher("page02.html").forward(request,response);
@WebServlet("/ser07")
......
//doPost方法不同
//重定向方式
response.sendRedirect("page03.html");
转发和重定向的区别

理解图

@WebServlet("/ser01")
public class Servlet01 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {this.doPost(request, response);}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {/*** 知识点:转发和重定向的区别*///区别一:发送请求次数的区别//注意:转发发送1次请求//request.getRequestDispatcher("page01.html").forward(request,response);//http://localhost:8080/Day18_04_war_exploded/ser01//注意:重定向发送2次请求//response.sendRedirect("page01.html");//http://localhost:8080/Day18_04_war_exploded/page01.html//区别二:访问外部资源//注意:转发不能访问外部资源(因为服务器不能访问其他的服务器)//request.getRequestDispatcher("https://www.baidu.com").forward(request,response);//注意:重定向可以访问外部资源(因为本服务器通过响应告诉客户端重新向其他服务器发送请求)//response.sendRedirect("https://www.baidu.com");//区别三:访问受保护的页面//注意:转发可以访问受保护的页面(因为转发是服务器内部的跳转)//request.getRequestDispatcher("WEB-INF/page02.html").forward(request,response);//注意:重定向不可以访问受保护的页面(因为客户端不能直接访问受保护文件夹里的资源)response.sendRedirect("WEB-INF/page02.html");}
}

受保护的页面,放在web\WEB-INF
保护页面

  <h1>受保护的页面</h1>

页面

  <h1>页面1</h1>

转发
转发
重定向
重定向

中文页面

设置请求和响应的编码格式不能解决,对应跳转中文页面还需加编码类进行设置
跳转中文页面地址栏就不会显示乱码和找不到
中文页面乱码

@WebServlet("/ser01")
public class Servlet01 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {this.doPost(request, response);}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//设置请求和响应的编码格式request.setCharacterEncoding("UTF-8");response.setContentType("text/html;charset=UTF-8");//跳转中文页面// response.sendRedirect("页面1.html");response.sendRedirect(URLEncoder.encode("页面1.html","UTF-8"));}
}

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SAP 采购订单审批 Flexible Workflow

目录 1 简介 2 业务数据 1&#xff09;下采购订单&#xff0c;如果订单金额超过 15w 生成 Flexible Workflow 审批 2&#xff09;审批采购订单 - 系统默认主页显示需要审批的采购订单&#xff0c;也可以设置成发邮件提醒 3 后台配置 4 前台主数据定义 1&#xff09;创建…

c++ 智能指针shared_ptr与make_shared

shared_ptr是C11引入的一种智能指针&#xff0c;‌它允许多个shared_ptr实例共享同一个对象&#xff0c;‌通过引用计数来管理对象的生命周期。‌当最后一个持有对象的shared_ptr被销毁时&#xff0c;‌它会自动删除所指向的对象。‌这种智能指针主要用于解决资源管理问题&…

Qt遇到qt自身组件找不到

比如在使用qtcharts的时候&#xff0c;找不到 解决方法&#xff1a; 在cmakelist中添加 find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Charts REQUIRED) 是一个 CMake 命令&#xff0c;用于查找并配置 Qt 库中的特定组件。这条命令的作用是找到 Qt 的主要版本&#xff08;…

ElasticSearch搜索

ES搜索 elastic search 一套搜索引擎技术,主要技术栈包括 Elasticsearch&#xff1a;用于数据存储、计算和搜索 Kibana&#xff1a;用于数据可视化 在数据库模糊查询中,因为不走索引,所以效率很低,而在搜索引擎中,不仅效率高,而且即使出现个别错字,或者用拼音搜索,甚至用同…

路径规划 | Q-learning机器人路径规划算法(Matlab)

目录 效果一览基本介绍程序设计参考文献 效果一览 基本介绍 Q-learning机器人路径规划算法 机器人路径规划&#xff0c;机器人路径避障。求解常见的路径规划问题。内含算法的注释&#xff0c;模块化编程。 强化学习中的价值学习算法是一类重要的强化学习算法&#xff0c;它们通…

ntp服务重启报错Failed to restart ntpd.service: Unit is masked.

问题概述&#xff1a; 重启ntp服务报错Failed to restart ntpd.service: Unit is masked&#xff0c;使用systemctl unmask ntpd.service命令关闭屏蔽还是报错Failed to restart ntpd.service: Unit is masked 解决方法&#xff1a; 重装ntp服务 yum remove ntpyum install…

Go 1.19.4 结构体-Day 09

1. 结构体介绍 1.1 什么是结构体 结构体&#xff08;struct&#xff09;是一种用户定义的类型&#xff0c;它由一系列的字段组成&#xff0c;每个字段都有自己的名称和类型。 结构体也是值类型的&#xff0c;就算加了指针也是&#xff0c;只不过是复制的内存地址。 1.2 为什么…

2024年的AI人工智能风口是Python?一篇文章告诉你为什么!

Python是一种面向对象的、解释型的、通用的、开源的脚本编程语言&#xff0c;它之所以非常流行&#xff0c;我认为主要有三点原因&#xff1a; 1.Python 简单易用&#xff0c;学习成本低&#xff0c;看起来非常干净&#xff1b; 2.Python 标准库和第三库众多&#xff0c;功能…

stack和list

前言 stack和list的使用就不讲了&#xff0c;讲一下模拟实现&#xff0c;然后讲一下deque&#xff0c;最后讲一下优先队列 1. stack的模拟实现 template<class T,class container>//这个container是vector&#xff0c;或者list或者deque&#xff08;后面会说&#xff0…

测试用例之等价类划分、边界值法

&#x1f345; 点击文末小卡片&#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 一、测试用例/案例 1、定义&#xff1a;是在测试执行之前&#xff0c;由测试人员编写的指导测试过程的重要文档&#xff0c;主要包括&#xff1a;用例编号、测试目…

Windows安装服务

&#xff08;1&#xff09;下载设置工具 https://nssm.cc/release/nssm-2.24.zip &#xff08;2&#xff09;根据自己系统选择工具32/64版本 &#xff08;3&#xff09;选择版本后进入文件夹&#xff0c;打开cmd命令窗口输入命令&#xff1a;nssm.exe install &#xff08;4&a…

阿里云实时计算Flink在多行业的应用和实践

摘要&#xff1a;本文整理自 Flink Forward Asia 2023 中闭门会的分享。主要分享实时计算在各行业的应用实践&#xff0c;对回归实时计算的重点场景进行介绍以及企业如何使用实时计算技术&#xff0c;并且提供一些在技术架构上的参考建议。内容分为以下四个部分&#xff1a; 业…

SQL Server 端口配置

目录 默认端口 更改端口 示例&#xff1a;更改 TCP 端口 示例&#xff1a;验证端口设置 远程连接测试 示例&#xff1a;使用 telnet 测试连接 配置防火墙 示例&#xff1a;Windows 防火墙设置 远程连接测试 示例&#xff1a;使用 telnet 测试连接 默认端口 TCP/IP: …

jmeter 重试机制

一、功能实现 我们在测试过程中&#xff0c;请求接口可能是因为请求超时&#xff0c;或者接口异常失败&#xff0c;导致整个测试链路验证失败&#xff0c;jmeter重试机制&#xff0c;这个时候就可以避免上述问题发生 二、配置 1、添加线程组 首先&#xff0c;确保你已经在测…

ctfshow~菜狗杯 你会异或吗

下载文件附件得到一张png图片&#xff0c;用010打开看一下 全是乱码&#xff0c;结合题目提示 你会异或吗 和 神秘数字:0x50 我们试一下图片十六进制值异或十六进制0x50 打开010然后工具–>十六进制运算–>二进制异或 输入0x50 得到一张新的图片 然后到微信里的图片文字提…

函数模板和类模板

前言&#xff1a;各位老铁好&#xff0c;今天来分享函数模板和类模板的知识&#xff0c;这个算是一个小知识&#xff0c;但这个小知识非常重要&#xff0c;相信学C的各位老铁一定听过STL这个名词&#xff0c;那么STL是什么呢&#xff1f;它与我们今天分享的这个函数模板和类模板…

《Milvus Cloud向量数据库指南》——图像数据:ResNet50与图像及视频搜索的深度解析

图像数据:ResNet50与图像及视频搜索的深度解析 在当今信息爆炸的时代,图像和视频作为最直观、最富表现力的媒体形式之一,其搜索与检索技术显得尤为重要。无论是科研探索、艺术创作还是日常娱乐,人们越来越依赖于高效的图像和视频搜索工具来快速定位所需内容。其中,ResNet…

高频JMeter软件测试面试题

近期&#xff0c;有很多粉丝在催更关于Jmeter的面试题&#xff0c;索性抽空整理了一波&#xff0c;以下是一些高频JMeter面试题&#xff0c;拿走不谢~ 一、JMeter的工作原理 JMeter就像一群将请求发送到目标服务器的用户一样&#xff0c;它收集来自目标服务器的响应以及其他统计…

光伏气象站:绿色能源时代的守护者

光伏气象站&#xff0c;顾名思义&#xff0c;是结合了光伏发电技术与气象监测功能的创新设备。 它不仅能够利用太阳能自发电&#xff0c;实现绿色能源自给自足&#xff0c;还能精准监测并记录温度、湿度、风速、风向等关键气象参数。这些数据对于评估光伏系统的发电效率、优化电…

Java后端初开-->架构师学习路线!无偿分享!让你少走弯路

由于平台篇幅原因&#xff0c;很多java面试资料内容展示不了&#xff0c;需要的java面试宝典的伙伴们转发文章关注后&#xff0c;扫描下方二维码免费获取: