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

news2024/11/25 16:25:37

设置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 {

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }

    private  int num;

    @Override
    protected 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被创建了");
    }

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }

    private int num;

    @Override
    protected 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 {

    @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 {
        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 {

    @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 {
        /**
         * 知识点:转发和重定向的区别
         */

        //区别一:发送请求次数的区别
        //注意:转发发送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 {

    @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 {
        //设置请求和响应的编码格式
        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.coloradmin.cn/o/1967508.html

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

相关文章

java开发环境搭建基础番外篇之----Maven在windows的安装及配置

一.背景 公司安排了带徒弟任务&#xff0c;写点基础的环境搭建这些吧。搭建基础开发环境&#xff0c;主要是jdk、eclipse、git、maven、mysql。后续再考虑编写jenkins、nexus、docker、1panel等CI/CD环境搭建。 本次主要内容是maven在window是系统中的安装及配置。我的开发环境…

电梯节能(能量回馈)样板间,现场勘察效果

一、现场勘察&#xff1a;电表倒转回馈 二、真实数据 三、真实现场勘察情况&#xff1a; 【电梯机房背景】 2023-07-26日&#xff0c;电梯机房勘察&#xff08;该机房控制2部电梯&#xff0c;分为【内外】间&#xff0c;各有1台电梯控制柜控制1台电梯&#xff09;。 【发热电…

美股收涨英伟达大涨,美联储降息预期升温

昨夜美股三大股指集体收涨&#xff0c;受“小非农”数据与鲍威尔为9月开启降息背书的利好影响&#xff0c;英伟达大涨近13%&#xff0c;引领科技股强势反弹。 一、大盘动态 截至收盘&#xff0c;道指涨0.24%&#xff0c;纳指涨2.64%&#xff0c;标普涨1.58%。美国十年国债收益…

记一次mybatisplus和postgresql自增主键冲突的问题解决

问题出现前提&#xff1a; 1. postgresql设置字段自增 2. springboot项目集成mybatisplus向表中新增数据 现象&#xff1a;db中字段没有自增且无规律。 springboot项目中实体类如下&#xff1a; 其中id为本次要自增的字段。 整个设置字段自增的过程&#xff1a; 首先&…

el-table-column 遍历 如何将 year 作为表头 processstatus为值

使用 Vue 的计算属性来动态生成列&#xff0c;并使用 v-for 在 <el-table> 的 <el-table-column> 上来遍历这些列。此外&#xff0c;我们还需要一个方法来处理每行数据的显示&#xff0c;因为每行的数据&#xff08;sonList&#xff09;需要根据年份来显示对应的 p…

uniapp使用uView的单选框自定义图片标题和副标题

效果图&#xff1a; 我这边是在一个弹框里面&#xff0c;需要一个单选框 实现代码&#xff1a; html代码&#xff1a; <u-popup :round"15" mode"center" :closeOnClickOverlay"false" bgColor"transparent"><view class&…

水泥电阻在电源电路中的作用

水泥电阻是将电阻线绕在无碱性耐热瓷件上&#xff0c;外面加上耐热、耐湿及耐腐蚀之材料保护固定并把绕线电阻体放入方形瓷器框内&#xff0c;用特殊不燃性耐热水泥充填密封而成。水泥电阻的外侧主要是陶瓷材质&#xff08;一般可分为高铝瓷和长石瓷&#xff09;。 水泥电阻器…

navicat 17 安装

百度网盘 链接: https://pan.baidu.com/s/1nFFQzWhjxRUM_X6bVlWNGw?pwd8888 提取码: 8888 1.双击运行安装包 2.点击下一步 2.勾选我同意&#xff0c;点击下一步 3.自定义安装路径&#xff0c;点击下一步 4.注意勾选桌面快捷方式&#xff0c;点击下一步 5.点击安装 6.点击完…

游戏类型有哪些?游戏分类详细解说(二)

在游戏行业中&#xff0c;对游戏进行分类可以帮助玩家、开发者和市场分析师更好地理解市场趋势、玩家偏好和游戏设计元素。 游戏分类可以从多个维度进行&#xff0c;上一期跟大家分享了目前现有的游戏品类&#xff0c;本期跟大家分享具体游戏分类维度&#x1f447; 1、题材维度…

要抓住国际白银现货行情 以下这几点需要注意

国际白银现货行情最近表现不甚稳定&#xff0c;在七月上旬出现了比较强势的上涨&#xff0c;但随后出现强势的下跌&#xff0c;跌破了30关口。如果我们要抓住国际白银现货行情&#xff0c;那么以下这几点我们就需要注意。 一&#xff0c;建立交易计划&#xff0c;并且按计划执行…

Day1-软件包管理及shell命令

1. Linux介绍 1.1 Linux的发展 在Unix基础上发展而来 GNU GUN is Not Unix GPL General Public License 1.2 各种Linux发行版本 Red Hat Ubuntu 1.3 Linux体系结构 1.4命令终端 在桌面环境下的命令终端仿真器程序很多&#xff0c;它们各有特色&#xff0c;拥有各自的用户…

QT——常用的窗口相关知识点

1. 常用的窗口标志设置 设置窗口无标题栏 // 设置窗口无标题栏this->setWindowFlags(Qt::CustomizeWindowHint);设置窗口无边框 // 设置窗口无边框setWindowFlags(Qt::FramelessWindowHint);设置窗口置顶 // 设置窗口置顶setWindowFlags(Qt::FramelessWindowHint|Qt::Windo…

Harbor镜像仓库教程(单节点)

1.前置内容 1.1 harbor概述 众所周知&#xff0c;docker镜像仓库被墙了&#xff0c;所以部署我们私有环境内的Registry也是非常必要的。 Harbor是由VMware公司开源的企业级的Docker Registry管理项目&#xff0c;相比docker官方拥有更丰富的权限权利和完善的架构设计&#xff…

Linux笔记 --- 组合数据类型

结构体 简单的定义结构体的方法 struct student {char name;int age;float score; };//使用student模板创建两个结构体变量 struct student Jack,Rose; 结构体中可以存放除了函数以外的任何数据类型的数据&#xff0c;在创建结构体时student被称为结构体模板名称&#xff0c;…

CRM是什么?如何用CRM管理好客户?

在企业的销售运营中&#xff0c;客户是是贯穿始终的主体。客户的需求、偏好与满意度&#xff0c;指引着企业未来改变、优化的方向。而企业销售运营的核心&#xff0c;就是“客户至上”。 面对庞杂的客户信息&#xff0c;如何快速高效的进行客户管理呢&#xff1f;那就是要有一…

windows下在线预览服务kkFileView4.4.0问题记录

前几天找到一个开源项目&#xff1a;kkFileView&#xff0c;感觉可能以后可能会用到&#xff0c;所以尝试了下。 通过git下载下来&#xff0c;版本是4.4.0&#xff0c;通过idea打开项目&#xff0c;发现老是无法找到组件aspose-cad&#xff0c;版本是23.9. 找了好多文章&#x…

MyBatis-Plus是啥?有啥用?让 MyBatis 开发更简单、更高效!

让 MyBatis 开发更简单、更高效! 在当今快节奏的软件开发世界中,提高开发效率是每个程序员都追求的目标。而 MyBatis-Plus 则是一款能够帮助开发者在 MyBatis 项目中事半功倍的神奇工具。本文将为您深入探索 MyBatis-Plus 的核心特性和强大功能,助您在 MyBatis 开发之路上驰骋畅…

计算word文件打印页数 VBA实现

目录 场景复现环境说明实现原理计算当前文件夹下所有word文件页数总和利用递归计算当前文件夹所有work文件页面数量几个BUG计算结果软件报价后话 场景复现 最近需要帮我弟打印高考资料&#xff0c;搜集完资料去网上打印&#xff0c;商家发出了这个计算页数的界面。我就好奇怎么…

Robotaxi火了,中国智驾公司冲击全球无人车第一股

作者 |芦苇 编辑 |德新 全球Robotaxi第一股要来了&#xff0c;中国的文远知行可能比Waymo、Cruise更早上市。 7月末&#xff0c;文远知行向美国SEC提交招股书&#xff0c;此次发行由摩根士丹利、摩根大通及中金公司牵头&#xff0c;股票代码「WRD」。 作为全球第一家上市的R…

React 学习——路由跳转(Link、useNavigate)、跳转时传递参数(问号传递、path中冒号拼接)

需要四个页面&#xff1a;项目入口index.js文件&#xff0c;router配置路由跳转文件&#xff0c;article组件页面&#xff0c;login组件页面 1、项目入口index.js文件 注意&#xff1a;要安装这个依赖 react-router-dom import React from react import { createRoot } fro…