Servlet---服务端小应用程序(服务器端的小组件)

零.前置知识

1.tomcat—服务器容器

tomcat就是一个服务器容器,通常说的将项目部署到服务器,就是将项目部署到tomcat中(将项目放到tomcat容器中)。

浏览器向服务器发送一个HTTP请求,请求访问demo09.html页面,(容器里面是有这个资源的,因为代码就在项目里写着,项目已经放到容器里了),服务器响应资源,给浏览器返回字符串<html><from>…那些。浏览器解析成网页,给用户展示出来。

在这里插入图片描述

2.IDEA创建一个web项目

1.先建立一个普通的Java工程(或者模块)
在这里插入图片描述
2.右击工程或者模块点击:
在这里插入图片描述

3.勾上Web Application,点击OK
在这里插入图片描述
4.导入依赖
点击工程结构,里面有这个工程下的模块
在这里插入图片描述
将依赖加进去:
在这里插入图片描述
在这里插入图片描述
再点击应用,点击OK

5.注意先有的Artifacts,添加jar后需要在工程结构下的problems将jar add到Artifacts中,点一下就行啦
在这里插入图片描述

7.配置tomcat,点击Edit Configurations在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
点击apply,然后点Server
在这里插入图片描述
点击apply,点击OK,tomcat部署成功,点击小绿箭头就可以运行了。

3.Servlet服务器端的小组件

可以看到:Servlet就是服务器端的一个小组件。
在这里插入图片描述

Sevlet是服务器端的应用程序
AddServlet完成的功能
1.获取用户(客户端)发给我的数据。为什么要获取这个数据?
2.调用DAO中的方法完成功能,比如完成添加功能。(一个Servlet对应一个业务功能)。
3.在控制台打印添加成功。

配置一个Servlet的具体流程如下:

  • 客户端给服务器发HTTP请求(将这个请求封装成Http request对象,里面封装的是信息,可以得到发送的信息,如何得到?),客户端响应<html字符串给浏览器,浏览器解析成页面
  • 用户在浏览器输入表单点击添加后,又向服务器发送一个请求。action=“add”。请求的就是Servlet为add的组件,浏览器并把数据带给服务器。服务器里面有个组件叫做add,add就是一个java类,AddServlet是服务器端的应用程序,add和AddServlet是如何对应上的?
  • add组件下还有一个DAO组件,是用来操作数据库的。

为什么要获取请求的信息?
因为在添加功能时,获取到了用户输入的信息,将这些信息封装到对象中(对象对应着一条一条的记录)。再调用DAO层的方法,将对象都追加到list中,就添加到数据库中了。

如何获取请求的信息?
req.getParameter(“fname”); "fname"和<form标签中的name="fname"相对应,否则获取不到。

图解:
在这里插入图片描述

add和AddServlet是如何对应上的?
1.用户给服务器发请求。action=add
2.服务器tomcat中,web.xml中找到url-pattern=/add。(在xml文件中要配置)
3.找到url-pattern=/add上一行servlet-name=AddServlet
4.找到和sevlet-mapping中servlet-name一致的servlet
5.找到sevlet中servlet-calss—>找到了com.atguigu.servlets.Addservlet。这是一个Java类,写的是全类名
用户发送的是post请求(method=post),因此tomcat会执行AddServlet中的doPost方法

配置图解:
在这里插入图片描述

在这里插入图片描述

Servlet3.0新增了注解,在AddServlet类上加注解:
@WebServlet(“/add”) 就可以通过action=add 直接找到AddServlet类(Servlet组件)
就不用web.xml文件了,删掉都可以~

整体架构:
在这里插入图片描述
代码:
Servlet:AddServlet:

protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //post方式下,设置编码,防止中文乱码
        //需要注意的是,设置编码这一句代码必须在所有的获取参数之前
        //get方式目前不需要设置编码(基于tomcat8)
        //(tomcat8之前)如果是get请求发送的中文数据,转码稍微有些麻烦
        req.setCharacterEncoding("UTF-8");
        //通过请求把数据带给服务器 通过request对象获取的
        String fname = req.getParameter("fname");
        //通过Http请求得到的信息只能是字符串,可以强转
        String priceStr = req.getParameter("price");
        Integer price = Integer.parseInt(priceStr);
        String fcountStr = req.getParameter("fcount");
        Integer fcount = Integer.parseInt(fcountStr);
        String remark = req.getParameter("remark");
        FruitDAO fruitDAO=new FruitDAOImpl();
        boolean flag = fruitDAO.addFruit(new Fruit(0, fname, price, fcount, remark));
        System.out.println(flag?"添加成功":"添加失败");
    }

web.xml:

<?xml version="1.0" encoding="UTF-8"?>
<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/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    <servlet>
        <servlet-name>AddServlet</servlet-name>
        <servlet-class>com.atguigu.servlets.AddServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>AddServlet</servlet-name>
        <url-pattern>/add</url-pattern>
    </servlet-mapping>
</web-app>

add.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form action="add" method="post">
    名称:<input type="text" name="fname"><br>
    价格:<input type="text" name="price"><br>
    库存:<input type="text" name="fcount"><br>
    备注:<input type="text" name="remark"><br>
    <input type="submit" value="添加">
</form>
</body>
</html>

一.设置编码

tomcat8之后使用get方式不用设置编码,使用post方式如下设置编码,要放在doPost()方法的首行

req.setCharacterEncoding("UTF-8");

tomcat8之前get方式较麻烦,post和上述方式一样

String fname=req.getParameter("fname");
//先用原始的方式打散,打散成字节流
byte[] bytes=fname.getBytes("iso-8859-1");
//再使用utf-8的编码格式组合
fname=new String(bytes,"UTF-8");

二.Servlet的继承关系

1.Servlet接口:init() service() destory()

------GenericServlet抽象子类:实现了init() destory() 抽象方法service()
------------ HttpServlet抽象子类:实现了service()方法,在方法内部通过了request.getMethod()来判断请求的方式,然后根据请求方式调用内部的do方法。每一个do方法进行了简单实现,主要是请求方式不符合,则报405错误。目的是让我们的Servlet子类去重谢对应的方法(如果重写的不对,则使用父类的405错误实现)

目前遇到的状态码:
200:正常响应。
404:找不到资源。
405:请求方式不支持。比如,表单发送请求method=post,Servlet方法中必须重写doPost。没有重写(重写错)默认调用的是父类的service方法,就报405。
500:服务器内部错误。比如没连接上数据库,空指针异常,找不到类等等

在这里插入图片描述
在这里插入图片描述

三.Servlet的生命周期

实例化、服务、销毁

1.tomcat负责维护Servlet的生命周期

2.每个Servlet在tomcat容器中只有一个实例,它是线程不安全的

在这里插入图片描述

3.Servlet的启动时机:<load-on-start-up>,数字越小,启动越早,最小值是0,设置为1时,是随着tomcat启动的。

<servlet>
        <servlet-name>Demo02Servlet</servlet-name>
        <servlet-class>com.aiguigu.servlets.Demo02Servlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>Demo02Servlet</servlet-name>
        <url-pattern>/demo02</url-pattern>
    </servlet-mapping>

四.Http协议

由Request和Response组成

1.请求包含了三部分:请求行、请求消息头、请求主体

在这里插入图片描述

2.响应包含了三部分:相应行、响应消息行、相应主体

在这里插入图片描述

五.会话Session HttpSession

HttpSession表示一次会话:
在这里插入图片描述

**为什么需要会话?**通过会话跟踪技术解决Http无状态问题
因为Http协议是无状态的,默认情况下,服务器无法区分两次请求是否来源于同一个客户端。第一次创建一个唯一的SessionID(通过cookie)的方式交给客户端,下一次客户端发请求的适合会把这个ID带过来,服务器就知道是谁了。

Session保存作用域:一次会话范围都有效
在这里插入图片描述
常用的API:
在这里插入图片描述

六.服务器内部转发以及客户端重定向

1.服务器内部转发:

在这里插入图片描述
在这里插入图片描述

2.客户端重定向:

在这里插入图片描述
在这里插入图片描述

七.thymeleaf视图模板技术

简单来说就是把数据库中的数据渲染在页面上:
在这里插入图片描述

步骤:
1.添加thymeleaf的jar
2.新建一个Servlet类ViewBaseServlet。(里面有两个方法)固定的,以后会被框架替代,先不管里面是什么了
3.在web.xml文件中添加配置:配置前缀view-prefix,配置后缀suffix
4.使我们的Servlet继承ViewBaseServlet
5.根据逻辑视图名称 得到 物理视图名称
6.使用thymeleaf标签
th:if
th:unless
th:each
th:text

整体架构:
在这里插入图片描述
web.xml中配置thymeleaf的参数

<context-param>
        <param-name>view-prefix</param-name>
        <param-value>/</param-value>
    </context-param>
    <context-param>
        <param-name>view-suffix</param-name>
        <param-value>.html</param-value>
    </context-param>

IndexServlet中:
将得到的list放在session作用域中,后续用key取。
并得到真实的视图名称:

@WebServlet("/index")
public class IndexServlet extends ViewBaseServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        FruitDAO fruitDAO = new FruitDAOImpl();
        List<Fruit> fruitList = fruitDAO.getFruitList();
        //保存到session作用域
        HttpSession session = req.getSession();
        //向当前的session作用域保存一个数据
        session.setAttribute("fruitList",fruitList);
        //处理模板:视图名称index
        //那么thymeleaf会将这个 逻辑视图名称 对应到物理视图名称上去
        //逻辑视图名称:index
        //物理视图名称:view-prefix + 逻辑视图名称 + view-suffix
        //所以 真实的视图名称是:/index.html   所以这是最终跳转的页面 就是web下的index.html
        super.processTemplate("index",req,resp);
    }
}

index.html中:

<html xmlns:th="http://www.thymeleaf.org">
	<head>
		<meta charset="utf-8">
		<link rel="stylesheet" href="css/index.css">
	</head>
	<body>
		<div id="div_container">
			<div id="div_fruit_list">
				<p class="center f30">欢迎使用水果库存后台管理系统</p>
				<table id="tbl_fruit">
					<tr>
						<th class="w20">名称</th>
						<th class="w20">单价</th>
						<th class="w20">库存</th>
						<th>操作</th>
					</tr>
					<tr th:if="${#lists.isEmpty(session.fruitList)}">
						<td colspan="4">对不起,库存为空</td>
					</tr>
					<tr th:unless="${#lists.isEmpty(session.fruitList)}" th:each="fruit : ${session.fruitList}">
						<td th:text="${fruit.fname}">苹果</td>
						<td th:text="${fruit.price}">5</td>
						<td th:text="${fruit.fcount}">20</td>
						<td><img src="imgs/del.jpg" class="delImg"/></td>
					</tr>
				</table>
			</div>
		</div>
	</body>
</html>

大概解释一下:这块应该不用很懂。。。vue有渲染的技术
在这里插入图片描述

八.保存作用域

原始情况下,有四个:page(页面级别,已经不用了,除非用的是jsp),request(请求级别,一次请求响应范围),session(一次会话范围),application(整个应用程序范围)

1.request 一次请求响应范围有效

两个Servlet之间使用客户端重定向的方式:第二次获取不到,因为不是一次响应
在这里插入图片描述
两个Servlet之间使用服务器内部转发的方式:第二次能获取到,属于一次响应
在这里插入图片描述

2.session 一次会话范围有效

是一次会话范围,不管是客户端重定向还是服务器内部转发的方式,都能获取到,因为是一次会话范围,只要session没有失效。
c1访问组件2是能获取到的。
c2直接访问组件2是获取不到的,null.
在这里插入图片描述

3.application 一次应用程序有效

应用程序级别,只要有一个客户端给里面保存了,剩下的所有客户端也能访问到。
在这里插入图片描述

总结了一天~点个赞趴~代码放的不全,需要哪块的工具包或者jar请留言~

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Linux】进程相关笔记

文章目录查看进程方式批量化注释fork进程状态R状态S状态D状态T状态t状态退出码问题X&&Z状态僵尸进程的危害makefile 新知识孤儿进程查看进程方式 ls /proc ls /proc/13045 (可以查看到之情进程的属性) ps axj | head -1 && ps ajx | grep myprocess(文件名) |…

垃圾回收之CMS、G1、ZGC对比

ZGC&#xff08;The Z Garbage Collector&#xff09;是JDK 11中推出的一款低延迟垃圾回收器&#xff0c;它的设计目标包括&#xff1a; 停顿时间不超过10ms&#xff1b;停顿时间不会随着堆的大小&#xff0c;或者活跃对象的大小而增加&#xff1b;支持8MB~4TB级别的堆&#x…

【C++】string类的模拟实现

目录 一、前言 二、模拟实现 1、构造函数 2、拷贝构造函数 3、operator 4、operator[] 5、迭代器 6、string类的比较 7、string类的扩容 7.1、reserve 7.2、resize 8、string类的尾插 8.1、push_back 与 append 8.2、operator 9、string类的insert 9.1、插入字符…

deepin15.11无法正常输入汉字问题的解决

1,起因 本来是sougou输入法 但是由于自己突发奇想 在那瞎折腾 一不小心把配置给弄坏了 就再也回不到之前可以正常打印汉字的状态 历经两个小时的折腾 总算是又能输入汉字啦 耗费两个多小时 对当下的我来说时间成本着实有点高 但是把问题给解决了 总算还是有点收获 平时的学习过…

注意力机制 | CNN-BiLSTM-Attention基于卷积-双向长短期记忆网络结合注意力机制多输入单输出回归预测(Matlab程序)

注意力机制 | CNN-BiLSTM-Attention基于卷积-双向长短期记忆网络结合注意力机制多输入单输出回归预测(Matlab程序) 目录 注意力机制 | CNN-BiLSTM-Attention基于卷积-双向长短期记忆网络结合注意力机制多输入单输出回归预测(Matlab程序)预测结果评价指标基本介绍程序设计参…

qt 编译器 调试器

电脑版本&#xff1a;win10 64位 qt版本&#xff1a;based on Qt 5.14.0&#xff08;msvc 2017&#xff0c; 32位&#xff09; Qt Creator 4.11.0 qt安装包&#xff1a;qt-opensource-windows-x86-5.9.9.exe 安装过程一路next&#xff0c;安装完成后&#xff0c;默认使用的…

Spring IoC循环依赖问题

什么是循环依赖 循环依赖其实就是循环引⽤&#xff0c;也就是两个或者两个以上的 Bean 互相持有对⽅&#xff0c;最终形成闭环。⽐如A依赖于B&#xff0c;B依赖于C&#xff0c;C⼜依赖于A。 注意&#xff0c;这⾥不是函数的循环调⽤&#xff0c;是对象的相互依赖关系。循环调…

一个服务端同学的Vue框架入门及实践

做为服务端同学&#xff0c;接触前端代码较少&#xff0c;刚毕业的时候用过 jQuery Bootstrap2/3&#xff0c;当时的感觉就是&#xff0c;容易上手&#xff0c;学习门槛相对较低&#xff0c;另外就是有一个非常成熟的 jQuery 插件库&#xff0c;在这里&#xff0c;几乎可以找到…

vue集成tui.calendar日历组件

vue集成tui.calendar日历组件前言一、简介、效果图二、vue简单集成(集成js版本,没有使用官方的vue2版本)1.引包2.简单示例三、自定义功能1.需求分析、效果展示2.实现思路前言 vue2的集成在git上官方已经给出了demo这里就不贴代码了。本次主要是vue3集成 最近有个功能需要一个日…

重发布实验

基础配置&#xff1a; [r1]int l0 [r1-LoopBack0]ip add 1.1.1.1 24 [r1-LoopBack0]int g0/0/0 [r1-GigabitEthernet0/0/0]ip ad 192.168.12.1 24 [r1-GigabitEthernet0/0/0]int g0/0/1 [r1-GigabitEthernet0/0/1]ip add 192.168.123.1 24 [r1]ospf 1 router-id 1.1.1.1 [r1-o…

自学大数据第12天~Hbase

先留个问题~ERROR: KeeperErrorCode ConnectionLoss for /hbase/master 稍后解决 找到了问题的根因: 查看报错日志 事关tmp文件夹的配置,所以去找一下hbase配置文件中关于这个文件夹的配置项 我的策略是将这个配置项注销掉 然后启动hbase ,之后hmaster就成功启动了; 接着s…

熟练Redis之无处不在的锁

为了保证并发访问的正确性&#xff0c;Redis提供了两种方法,分别是加锁和原子操作 Redis加锁两个问题:一个是&#xff0c;如果加锁操作多&#xff0c;会降低系统的并发访问性能;第二个是&#xff0c;Redis客户端要加锁时&#xff0c;需要用到分布式锁&#xff0c;而分布式锁实…

Coremail奇安信发布2022中国企业邮箱安全性研究:应对ChatGPT带来的安全挑战

日前&#xff0c;广东盈世科技计算机有限公司与奇安信集团联合编写发布《2022中国企业邮箱安全性研究报告》。 报告数据显示&#xff1a;2022年&#xff0c;全国企业邮箱用户共收到各类钓鱼邮件约425.9亿封&#xff0c;相比2021年收到各类钓鱼邮件的342.2亿封增加了24.5%。 一…

华为OD机试用java实现 -【RSA 加密算法】

最近更新的博客 华为od 2023 | 什么是华为od,od 薪资待遇,od机试题清单华为OD机试真题大全,用 Python 解华为机试题 | 机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南华为od机试,独家整理 已参加机试人员的实战技巧本篇题解:RSA 加密算法 题目 RSA 加密…

【愚人节专场】Java实现定时发送小情话

首先&#xff0c;感谢大佬的帮助~附上大佬的博客以示尊敬https://blog.csdn.net/qq_38591577/article/details/128164308?spm1001.2014.3001.5502 功能实现&#xff1a; 在名为愚人节&#xff0c;实为告白/情人节的日子里&#xff0c;怎么样才能引起TA的关注呢&#xff1f;不…

49天精通Java,第21天,Java内部类,看看文心一言、ChatGPT怎么说

目录文心一言谈Java内部类ChatGPT谈Java内部类下面来聊聊哪吒的见解。一、为什么需要内部类&#xff1f;二、内部类分为四种三、成员内部类1、什么是成员内部类2、代码实例3、成员内部类进阶代码实例4、控制台显示5、外部类访问内部类四、局部内部类五、匿名内部类1、匿名内部类…

Dragonfly 最新正式版本 v2.0.9 已经发布!

作者&#xff1a;戚文博-蚂蚁集团 Dragonfly 最新正式版本 v2.0.9 已经发布&#xff01;感谢 Dragonfly 的贡献者们&#xff0c;同时也感谢默默支持 Dragonfly 项目的各个公有云团队。欢迎访问 d7y.io [ 1] 网站来了解详情&#xff0c;下面具体介绍 v2.0.9 版本带来了那些更新。…

【Redis】十大数据类型(下篇)

文章目录redis位图(bitmap) --- 底子还是string基本命令图示setbit key offset value setbit 键 偏移位 只能零或者1getbit key offset 查看获取字符串长度 strlen统计key中包含1的个数 bitcount keybitop 统计两个比特key是否都为1技术落地&#xff1a;打卡签到&#xff0c;频…

【C语言蓝桥杯每日一题】——等差数列

【C语言蓝桥杯每日一题】——等差数列&#x1f60e;前言&#x1f64c;等差数列&#x1f64c;解题思路分析&#xff1a;&#x1f60d;解题源代码分享&#xff1a;&#x1f60d;总结撒花&#x1f49e;&#x1f60e;博客昵称&#xff1a;博客小梦 &#x1f60a;最喜欢的座右铭&…

让ChatGPT帮我写shell脚本, 结局很感人

七问ChatGPT, 剑指shell脚本编写 step1: 初问step2: 再问step3: 三问step4: 四问step5: 五问step6: 问个derstep7: 解决问题step8: 小问一下关于ChatGPT思考昨天浏览一篇关于脚本的技术文章的时候, 偶然看见一篇文章中写道关于mysql备份的脚本. 但是这个脚本时基于本地的MySQL服…