首页 > 其他分享 >57_2设置Servlet模板、Servlet线程安全问题、跳转

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

时间:2024-08-03 16:58:55浏览次数:17  
标签:57 request doPost 跳转 Servlet01 Servlet response 页面

设置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"));
    }
}

标签:57,request,doPost,跳转,Servlet01,Servlet,response,页面
From: https://blog.csdn.net/gangain/article/details/140730863

相关文章

  • D36 2-SAT P5782 [POI2001] 和平委员会
    视频链接:D362-SATP5782[POI2001]和平委员会_哔哩哔哩_bilibili   P5782[POI2001]和平委员会-洛谷|计算机科学教育新生态(luogu.com.cn)//2-SAT+tarjanO(n+m)#include<iostream>#include<cstring>#include<algorithm>usingnamespacestd;const......
  • 电子科技集团WJ20057型热网智能终端数据监测MODBUS通信协议
    WJ2007型热网智能终端数据监测MODBUS通信协议  1、 WJ2007终端增加数据通信协议,上传实时数据;采用MODBUS通信协议,格式见表1;   地址功能起始地址点数CRC校验0x010x030x000x000x000x420xC50xFB1byte1bytes2byt......
  • iis安装数字证书ssl并实现http跳转https的301重定向
    iis安装数字证书ssl并实现http跳转https的301重定向为了增强网站的安全性,实现域名访问从HTTP自动跳转到HTTPS,您可以按照以下步骤操作:安装SSL证书:首先,您需要为您的网站获取一个SSL证书。这可以通过向证书颁发机构(CA)申请免费的证书(如Let'sEncrypt提供的证书)或购买商业证书来完成......
  • 钢铁百科:A572Gr50成分解析、A572Gr50切割加工
    一、A572Gr50材质:A572Gr50钢板是一种高强度低合金铌-钒结构钢板,属于美标低合金高强度板。二、A572Gr50执行标准:A572Gr50钢板执行ASTMA572/A572M标准,该标准与ASME标准SA-572/SA-572M完全等同。三、A572Gr50化学成分:A572Gr50钢板的化学成分主要包括以下元素及其含量:*碳(C......
  • 代码随想录算法训练营第57天 | 并查集理论基础
    并查集理论基础https://www.programmercarl.com/kamacoder/图论并查集理论基础.html107.寻找存在的路径https://kamacoder.com/problempage.php?pid=1179代码随想录https://www.programmercarl.com/kamacoder/0107.寻找存在的路径.html#思路并查集理论基础并查集用于判断......
  • 跳转语句
    跳转语句break语句:格式:break;作用:立即退出当前的循环(for、while或do-while)或switch语句。使用场景:通常用于在满足特定条件时提前终止循环。continue语句:格式:continue;作用:跳过当前循环的剩余部分,并立即开始下一次循环迭代。使用场景:当某个条......
  • 抖音私信如何跳转微信,抖音卡片制作教程
       在社交媒体平台中,抖音和微信都是非常受欢迎的应用程序。抖音是一款短视频分享平台,而微信是一款社交聊天应用。有时候,我们可能希望将抖音视频分享到微信上,但是却无法直接在抖音上找到跳转微信的功能。所以在本文中,我们将探讨如何生成抖音跳转微信链接的方法。首先,我们需要......
  • ESP32 使用MAX98357 播放MP3
    使用ESP32和MAX98357音频放大器芯片来播放音乐,效果令人惊叹! 【ESP32开发指南】   首先使用ESP32板和MAX98357芯片进行了简单的接线,下载了ArduinoI2S的库,然后用ArduinoIDE并编写了一些简单的代码来实现音乐播放。当我们启动程序并播放这首歌时,我们听到了一个令人惊叹的......
  • P3957 [NOIP2017 普及组] 跳房子
    思路:首先发现单调性,灵活性增加\(x+1\)的答案肯定不会比增加\(x\)的答案更劣。那么可以二分求\(g\),则机器人每次可以移动\([\max(d-mid,1),d+mid]\)这个区间内的距离,为了方便,设为\([l,r]\)。考虑动态规划求得能走到的最大分数,令\(dp_i\)表示走到第\(i\)个格子的最大......
  • VS2022 C# 按F12 默认跳转到[反编译]修改为[从元数据]的设置
    1.当光标选中Timer,按F12]如下图默认跳转为Timer[反编译 ]如下图 2.想要跳转到Timer[从元数据],设置如下,【工具】->[选项]->[文本编辑器]->[C#]->[高级]->取消勾选[支持导航到反编译源码]->[确认] 3.再次在光标选中Timer,按F12跳转结果是Timer[从元数据]如下: 4.点击前面......