-
javaWeb - 1 — servlet — 更新完毕
1、先来聊一些javaWeb相关的知识
-
简单了解一下:web的发展史
- 1)、web就是网页的意思嘛
-
-
2)、web的分类
-
(1)、静态web
-
使用HTML、CSS技术,主要包括图片和文本
- 优点:简单,只做信息的展示 即:提供给所有人看的信息都是一样的
- 缺点:无法和用户进行交互
-
使用HTML、CSS技术,主要包括图片和文本
-
(1)、静态web
-
2)、web的分类
-
-
-
(2)、动态web
-
最早的动态web采用的是:CGI / prel技术,能够实现动态展示网页内容,可以和用户交互,服务器可以访问系统和数据
- 但是:伸缩性差、安全性差、扩展性差、维护成本高
- 可是:这种模式开创了先河,为后来人打下了基础,因为:后续的就是从这里获取的灵感,然后进行发展的
-
最早的动态web采用的是:CGI / prel技术,能够实现动态展示网页内容,可以和用户交互,服务器可以访问系统和数据
-
(2)、动态web
-
-
-
-
-
后来的动态web
- 主要采用的技术 PHP、ASP、JSP / Servlet( 这是javaWeb阶段主学的东西 ,虽然现在已经开始被其他东西替代了,但是:这个对于流程的理解更好,同时这也是底层原理知识 ) —— 这些技术能够在一个一个框架下开发出拓展性比较好、安全性还不错的web程序
-
后来的动态web
-
-
-
-
-
- 在java中,动态资源开发的技术统称javaweb技术,这玩意儿就是连接前后台的关键点
-
-
-
-
-
(3)、web应用程序
- 简单来说:就是能够提供给浏览器访问的程序
-
(3)、web应用程序
-
-
-
-
- a.html 、 b.html 、c.html......多个web资源,这些web资源可以被外界访问,对外界提供服务
- 我们所能够访问的任何一个页面或资源,都在世界的某一个角落中存着的( HTML中提到的万维网 )
- 这些web资源都统一在一个文件夹下 tomcat----->webapps web应用程序
-
一个web应用由多部分组成( 静态web 、动态web )
- HTML、CSS、js
- jsp 、 Servlet
- java程序
- jar包
- 配置文件( Properties )
-
-
-
-
-
- web应用程序想要让外界访问,需要一个服务器来管理
-
-
-
-
-
-
多提一嘴:客户端和服务器
- 客户端:能够享受服务器提供服务的机器 简单点来说:就是客户发起请求的地方 如:搜索一个东西
- 服务端:能够给客户端提供服务的机器 简单点来说:就是响应客户请求的地方 如:搜索东西,会响应出搜索的结果涩
-
多提一嘴:客户端和服务器
-
-
-
-
-
-
详讲静态web
- *.html 这些都是网页的后缀, 只要服务器中有相应的html,那么就可以读取,进行展示
-
详讲静态web
-
-
-
-
-
-
-
静态web的执行过程
-
静态web的缺点
-
无法和用户进行交互,每个人看到的都是同一个页面内容
-
多提一嘴:
- 轮播图、点击特效这些都是伪动态
- js 实际开发中用的最多
- 同时静态web无法和数据库进行交互,数据无法持久化,所以:无法和用户进行交互
-
多提一嘴:
-
无法和用户进行交互,每个人看到的都是同一个页面内容
-
静态web的执行过程
-
-
-
-
-
-
-
详讲动态web
- web的页面可以动态显示,页面的效果因人而异( 好比:淘宝,每个人进去的页面都不一样,当然:这个复杂得多 )
-
详讲动态web
-
-
-
-
-
-
动态web的执行过程
-
动态web的执行过程
-
-
-
-
-
- 缺点:出现了错误,需要我们重新修改程序,重新发布
-
优点:可以动态展示信息,每个人看到的结果都不一样,还可以和数据库进行交互
-
-
-
-
-
4)、web服务器相关
- PHP 开发速度很快,代码简单( 70%是WP ) 但是:无法承载大访问量的情况,即:只适合做小项目( 局限性 )
-
ASP 国内最早的动态web技术 ,是微软的
- 它是在HTML中嵌入了VB脚本 即:ASP +COM
- 但是:每一个页面基本上都是几千行代码,代码中的页面布局极其混乱 维护成本高
-
4)、web服务器相关
-
-
-
-
-
JSP / Servlet
-
软件的结构
-
B / S browser / Server 浏览器和服务器结构 如:某某官网、某某网址
- 这种更新时,只需要更新到服务器中去就可以,但是:受网速影响
- 开发简单,且共享性强,成本低
- 但是:数据安全性低( 因为是在浏览器上,每个人都可以访问 )、数据传输慢、对服务器要求高、软件个性化弱( 每个人基本上都是同样的样式效果 )
-
B / S browser / Server 浏览器和服务器结构 如:某某官网、某某网址
-
软件的结构
-
JSP / Servlet
-
-
-
-
-
-
-
-
C / S client / Server 客户端和服务器结构 如:手机上的软件、电脑上的软件
- 响应速度快( 因为数据这些是在本机中的 ),交互性强、具有较强的存储模式、对网速要求不高
- 但是:针对性开发,更新不灵活( 需要连着把客户端 和 服务端都更新了 ,基本上不更新就不能用 )
-
C / S client / Server 客户端和服务器结构 如:手机上的软件、电脑上的软件
-
-
-
-
-
-
-
- 所需要的服务器 ——> Tomcat,想要哪个版本自己找 ,然后解压到自己的盘符中去 我使用的是Tomcat 9.0.43
-
-
-
-
-
5)、留个高难度的面试题
-
请你谈谈网站是如何访问的?
- (1)、输入网址 回车
-
(2)、去本机的C:\Windows\System32\drivers\etc\hosts中找域名映射
-
-
有,则:直接返回对应的ip地址,这个文件中有我们访问的web程序,则:可以访问
-
没有,就去DNS服务器上找,有就返回,没有就返回找不到
-
有,则:直接返回对应的ip地址,这个文件中有我们访问的web程序,则:可以访问
-
-
请你谈谈网站是如何访问的?
-
5)、留个高难度的面试题
-
2、聊聊和协议相关的
-
1)、响应状态码
- 200 授权成功 即:响应成功
- 304 可以正常执行,但是:没有响应结果
- 401 授权错误
- 403 请求不允许
- 404 资源找不到( 一般都是资源路径错误 ——— 一开始玩的时候:这个是打交道最多的 ) 4开头的基本上都是请求方面的错误
-
500 服务器内部的错误,如:网关,还有一种情况:自己的代码错误 这也是最常见,也是调试起来最头疼的,因为:需要看代码整理逻辑。
- 牢骚一下:老衲看到有人整出了这种错误,我恩是想锤死他
-
2)、HTTP协议
- 指的是超文本传输协议,另外的理论知识:面向百度编程、百度百科
-
-
(1)、HTTP的组成
- HTTP请求 和 HTTP响应
-
(1)、HTTP的组成
-
-
-
①、HTTP请求 Request
-
结构的样子
-
访问一个网站,然后利用network抓包看一下,如:访问百度
-
Request URL: chrome- extension://bfdogplmndidlpjfhoijckpakkdjkkil/content/display/library /notifier/notification.css 指的是:请求的地址 Request Method: GET 指的是:请求的方式 Status Code: 200 OK 指的是:响应状态码 Referrer Policy: origin-when-cross-origin 指的是:策略 其实还有一个:但是这里没显示,补上 Remote address: 指的是:远程地址
-
-
访问一个网站,然后利用network抓包看一下,如:访问百度
-
结构的样子
-
①、HTTP请求 Request
-
-
-
-
②、HTTP响应 Response
-
一样的抓包看一下
-
老衲比较懒, 里面的不想说明,就字面意思
-
-
一样的抓包看一下
-
②、HTTP响应 Response
-
3、安装Maven ———— 注:如果想用导入jar到项目中、然后标记文件类型的方式玩也可以,老衲懒,所以:直接上Maven
-
1)、Maven是什么?
-
就是项目管理工具。如果会使用导入jar的方式写代码的人,试想一下:每次都需要去找jar包麻不麻烦,因此:能不能偷个懒,让别人帮我们自动下载jar?
- 有的,就是Maven,要是没有的话,还讲个锤子^_^
-
就是项目管理工具。如果会使用导入jar的方式写代码的人,试想一下:每次都需要去找jar包麻不麻烦,因此:能不能偷个懒,让别人帮我们自动下载jar?
-
2)、安装Maven
-
(1)、下载Maven —— 直接搜索Maven就可以找到官网的,是Apache下的
-
下载网址:Maven – Download Apache Maven 学技术:选择最新的
- 下载好了之后,把压缩包解压到自己的盘符中即可
- 还是老样子:建议单独建一个文件夹,然后安装一个东西,就在里面新建一个对应的文件夹( 好找,这才像个学计算机的人,不然自己的文件放在哪里,自己都不知道,那学个锤子 )
-
下载网址:Maven – Download Apache Maven 学技术:选择最新的
-
(1)、下载Maven —— 直接搜索Maven就可以找到官网的,是Apache下的
-
-
(1)、配置环境变量
-
配置内容如下:
- 新建MAVEN_HOME 路径就是Maven的目录路径
- M2_HOME Maven的bin目录下 ———— 其实这两个本质都是一样的,只是有一代Maven和二代Maven而已,而且有些文件找的是这二者中其中一个,因此:以防万一就把两个都配上
- 在path中配置 %MAVEN_HOME%\bin
-
配置内容如下:
-
(1)、配置环境变量
-
-
(3)、测试Maven是否安装成功
-
在Dos窗口中输入 mvn -version
-
有这个页面就安装成功
-
-
在Dos窗口中输入 mvn -version
-
(3)、测试Maven是否安装成功
-
-
(4)、配置阿里云镜像
-
为什么需要配置它?
- 因为:东西是外国的,我们要下载的话,就犹如:中间隔了很大的一堵墙,所以会很慢,因此:下载国内的,这样更快
-
为什么需要配置它?
-
(4)、配置阿里云镜像
-
-
- 找到刚刚解压的Maven文件,在conf中找到settings.xml文件,打开它
-
<mirror> <id>nexus-aliyun</id> <mirrorOf>*,!jeecg,!jeecg-snapshots</mirrorOf> <name>Nexus aliyun</name> <url>http://maven.aliyun.com/nexus/content/groups/public</url> </mirror>
- 配置好了记得保存
-
-
-
(5)、配置本地仓库
-
①、在Maven目录中新建一个maven-repo repo就是repository的缩写
-
①、在Maven目录中新建一个maven-repo repo就是repository的缩写
-
(5)、配置本地仓库
-
-
-
②、一样的,打开刚刚的settings.xml文件,找到settings标签下的localRepository标签
-
一样的,改好记得保存
- 这样之后Maven就真的弄好的,接下来把它集成到IDEA中去
-
-
②、一样的,打开刚刚的settings.xml文件,找到settings标签下的localRepository标签
-
-
-
(6)、打开IDEA的这个页面( 开着项目的,那就直接选择File -----> close project就可以了
-
(6)、打开IDEA的这个页面( 开着项目的,那就直接选择File -----> close project就可以了
-
-
(7)、开始下载数据、添加插件、给本地仓库中存放东西
-
①、新建一个干净的Maven项目
-
①、新建一个干净的Maven项目
-
(7)、开始下载数据、添加插件、给本地仓库中存放东西
-
-
-
(8)、对项目的说明
-
有些创建完子项目之后,main下只有一个webapp,如:和我前面一样
-
那么:
-
-
那么:
-
有些创建完子项目之后,main下只有一个webapp,如:和我前面一样
-
(8)、对项目的说明
-
-
-
-
-
-
(9)、对maven核心文件 pom.xml的解读
-
这里记住一句话:Maven中约定大于配置 —— 这个很重要很重要,有一大坑儿在里面,后续会说明
- 即:Maven中是硬性要求的,所以配置东西时,会出现问题很正常,这些坑儿后续慢慢说明
-
-
(9)、对maven核心文件 pom.xml的解读
-
-
-
-
-
-
-
-
-
补充一个小问题:
-
-
补充一个小问题:
-
-
-
-
4、玩儿Maven仓库
-
Maven仓库网址:Maven Repository: Search/Browse/Explore (mvnrepository.com)
-
-
需要什么jar,直接在上面哪里搜索即可
-
如:需要servlet的jar包、mysql-connection-java、dbcp-commons、dbcp-pool,所以:我们玩一下
-
-
如:需要servlet的jar包、mysql-connection-java、dbcp-commons、dbcp-pool,所以:我们玩一下
-
需要什么jar,直接在上面哪里搜索即可
5、开始玩儿Servlet
-
1)、准备工作,需要Servlet的jar包
-
直接在Maven仓库中找,就像弄JDBC的驱动一样,我的本地仓库中有,所以就直接使用
-
直接在Maven仓库中找,就像弄JDBC的驱动一样,我的本地仓库中有,所以就直接使用
-
2)、怎么发布javaweb应用,即:Servlet程序
- ①、编写一个java类
- ②、让这个类 extends 继承HttpServlet
- ③、重写doGet() 和 doPost() 方法
- ④、配置web.xml
-
3)、操作一手
-
①、编写java实体类、继承HttpServlet、重写doGet()、doPost()
-
-
②、配置web.xml 即:Servlet映射 / 注册servlet ——— 这种方式很low,实际开发的时候,不会这么注册servlet,而是通过注解( 目前先用web.xml来注册,到servlet快结束时会使用注解来实现 ),但是:这种web.xml注册的方式很霸道
- 如:有多个servlet的时候,系统优先加载的是哪个servlet?这个在web.xml中就是代码的先后顺序来加载的( 前提是:没有对servlet进行设置<load-on-startup>参数</load-on-startup> 这个“参数”取值 > -1就行,这个数字就是代表的servlet加载的优先级,数字越大,优先级越大 ———— 注:这个配置很重要,甚至这种web.xml的方式也很重要( 虽然在实际开发中不会用这种方式注册servlet,但是:在springMVC框架中会用到这个web.xml 以及 <load-on-startup>
-
为什么需要映射?
- 因为我们编写的是java程序,想要浏览器来进行访问,浏览器需要连接web服务器,因此:我们需要在web服务中注册Servlet,并且给浏览器提供一个能够访问的路径
-
①、编写java实体类、继承HttpServlet、重写doGet()、doPost()
-
-
-
-
③、加入Tomcat服务器,开始发布
-
解决中文乱码
-
为什么会乱码?
-
因为:Servlet就是一个中转站,也就是浏览器中发起请求之后,会去web容器中( 也就是前面配置的web.xml )找寻servlet( 在示例中web.xml中是指向的oneServlet ),所以浏览器就会到oneServlet中获取响应信息,最后把响应信息通过url-pattern路径 返回到浏览器中的该路径下。
-
因此:从浏览器到servlet,再从serlvet转回到浏览器,这中间是经过两次编码的,即:浏览器 到 servlet一次,servlet到浏览器一次,这不就把编码格式改了吗,不统一了,因此:想要解决乱码问题,那么只需要做一件事情即可:servlet 到 浏览器,我指定它是什么编码就可以了
-
附:servlet的执行原理
-
-
-
-
-
-
-
-
-
延伸:在WEB-INF有一个web.xml,在tomcat的conf中也有一个web.xml( 即:我前面说的在tomcat的web.xml中拷贝那个信息到WEB-INF中去,那么:这两个web.xml有什么联系?
-
很简单:WEB-INF中的web.xml处理的是动态资源的配置文件,也就是我们写的后端代码;而tomcat中的web.xml处理的是静态资源的配置文件,也就是前端的代码。
-
后端需要的前端资源是怎么拿到的?就是通过这个tomcat中的web.xml配置文件,把前端写的东西 通过 “文件流”的形式 写入后端 并 做了一件事情,就是把前端写的东西转成了一个servlet,这样后端就可以拿到前端的东西了涩,并且还成了一个servlet ———— 这个知识点很重要
-
这就是为什么在WEB-INF的web.xml中注册servlet时,那个<url-pattern>不可以用 /* 的原因,因为:这个会把静态资源( 即:前端写的东西 )也给拦截了,会对前端的东西造成影响
-
另外:后续需要玩过滤器( 即:filter ),这个也是过滤器中那个过滤的请求路径不能乱整的原因
-
而想要解决这种影响前端 以及 过滤器的事情( 即:不对这两个造成影响 ,如:设置乱码时,后台可能好了,但是:前端乱码了 ),这种就需要做一件事情,改变tomcat中的web.xml配置,这个也很简单
-
-
-
延伸:在WEB-INF有一个web.xml,在tomcat的conf中也有一个web.xml( 即:我前面说的在tomcat的web.xml中拷贝那个信息到WEB-INF中去,那么:这两个web.xml有什么联系?
-
-
4)、ServletContext对象 ———— 一定需要知道的一个点,这个对象是servlet的三大作用域之一,简称:全局域 / application域
-
(1)、这个对象是用来干嘛的?
-
可以干的事情很多,但是:最核心的是 存数据,这个对象凌驾于所有的servlet之上 —— web容器在启动的时候,会为每个servlet都开启一个servletContext对象( 开启的本质其实都是同一个,来个图理解一下 ),换言之:这个全局域的作用域范围是 —— 服务器级别,只要服务器没关,那么:就可以在任何一个servlet中拿到数据。( 后续会把三大作用域单独弄出来总结一下,这里还要牵扯到另一个知识点cookie和session )
-
可以干的事情很多,但是:最核心的是 存数据,这个对象凌驾于所有的servlet之上 —— web容器在启动的时候,会为每个servlet都开启一个servletContext对象( 开启的本质其实都是同一个,来个图理解一下 ),换言之:这个全局域的作用域范围是 —— 服务器级别,只要服务器没关,那么:就可以在任何一个servlet中拿到数据。( 后续会把三大作用域单独弄出来总结一下,这里还要牵扯到另一个知识点cookie和session )
-
(1)、这个对象是用来干嘛的?
-
-
(2)、来玩一下ServletContext这个对象 —— 第一个作用存数据 这是存在全局中的,哪个servlet都可以拿到
-
第一个servlet 存数据
-
第一个servlet 存数据
-
(2)、来玩一下ServletContext这个对象 —— 第一个作用存数据 这是存在全局中的,哪个servlet都可以拿到
-
-
-
第二个servlet 取数据
-
-
第二个servlet 取数据
-
-
-
②、servletContext对象第二个作用 —— 获取初始化参数 这个东西:一般人开发一辈子都不会用到,但是有时候会用
-
这个初始化参数是在web.xml容器中的servlet注册中配置的,这配置出来的也是一个全局参数( 同时这个参数其实也是可以通过注解来配置的,这个知识点可以当做了解即可的东西,一般都不会用的 )
-
这个初始化参数是在web.xml容器中的servlet注册中配置的,这配置出来的也是一个全局参数( 同时这个参数其实也是可以通过注解来配置的,这个知识点可以当做了解即可的东西,一般都不会用的 )
-
②、servletContext对象第二个作用 —— 获取初始化参数 这个东西:一般人开发一辈子都不会用到,但是有时候会用
-
-
③、servletContext对象的第三个作用 —— 请求转发 —— 一般这种请求转发不会用,而是会用httpServletRequest对象来做请求转发,所以:这个知识点也可以当做了解即可( 但是:还是原话,有时是需要用到的 )
-
先提前知道一下:请求转发 和 重定向 的理论知识
-
请求转发:好比 老衲想知道一个东西,就去找了A,A把我想知道的东西告诉我了 ———— 即:换成网页来看就是:一个页面M请求跳转到下一个页面N,在M中的数据 会携带到 N页面中( 所以:需要携带数据到下一个请求就是请求转发 )
- 请求转发 页面跳转是在当前页面进行跳转,即:url地址是在当前页面的基础上进行跳转的 ( 和前端超链接a的target属性差不多 —— 这个可以指定值为:_self嘛,就是在当前页面进行跳转的,只是效果一样,但是里面的门道不一样 )
-
请求转发:好比 老衲想知道一个东西,就去找了A,A把我想知道的东西告诉我了 ———— 即:换成网页来看就是:一个页面M请求跳转到下一个页面N,在M中的数据 会携带到 N页面中( 所以:需要携带数据到下一个请求就是请求转发 )
-
先提前知道一下:请求转发 和 重定向 的理论知识
-
③、servletContext对象的第三个作用 —— 请求转发 —— 一般这种请求转发不会用,而是会用httpServletRequest对象来做请求转发,所以:这个知识点也可以当做了解即可( 但是:还是原话,有时是需要用到的 )
-
-
-
-
重定向:好比 老衲找A借钱,A跟我说:没钱,但是C有,所以:老衲就去找了C借钱 换成网页中来就是:通过一个新的url地址进行页面跳转( 一样的和超链接a的target属性的 _blank值差不多,这个属性值就是在新标签页打开页面嘛,有点类似,但是门道还是不一样啊 ),这个在httpServletResponse对象时会进行说明。
-
重定向:好比 老衲找A借钱,A跟我说:没钱,但是C有,所以:老衲就去找了C借钱 换成网页中来就是:通过一个新的url地址进行页面跳转( 一样的和超链接a的target属性的 _blank值差不多,这个属性值就是在新标签页打开页面嘛,有点类似,但是门道还是不一样啊 ),这个在httpServletResponse对象时会进行说明。
-
-
-
-
-
来玩一下servletContext请求转发
-
写一个网页页面 还没开始玩jsp,简单说一下:jsp就是前端的html,只是更灵活,这是另外一条编写路线
- 这条路线为: 即:后台 <-------- EL 、JSTL表达式 <----------- JSP ( 后续玩jsp时会进行说明 ,这里就当是html来玩即可 )
- 当然:html的写法也有一条路线 即: 后台 <--------- ajax异步请求 <-------------html( 前端 )
- 这两条路线需要记住:这也告知了 这两条路线的重点知识是什么了
-
-
写一个网页页面 还没开始玩jsp,简单说一下:jsp就是前端的html,只是更灵活,这是另外一条编写路线
-
来玩一下servletContext请求转发
-
-
-
④、ServletContext对象的第四个作用 —— 获取资源文件 其实这个用处很大的,但是:还是需要看自己的情况来,有可能自己真的从不需要用
-
先写个资源文件嘛
-
先写个资源文件嘛
-
④、ServletContext对象的第四个作用 —— 获取资源文件 其实这个用处很大的,但是:还是需要看自己的情况来,有可能自己真的从不需要用
-
5)、HttpServletResponse对象 —— 很重要,响应嘛
- web服务器接收到浏览器的请求后,会针对这个请求,分别创建一个代表请求的HttpServletRequest对象、和代表响应的HttpServletResponse对象。如果要获取客户端请求过来的信息,就找HttpServletRequest;如果要响应客户端信息,就找HttpServletResponse ———— 这个在说明servlet的原理时已经在图中说明过了,怎么做到的就是通过service()方法做到的,service()也是servlet的生命周期之一,即:服务环节( 后续会单独说明servlet的生命周期 )
-
-
先来看一下这个东西的源码,看看可以找到什么好玩的( 没提到的自己看源码,如:第二个图中的那些数字,就是状态码,也就是前面http中说的响应码 )
-
-
向刘浏览器发送数据的方法( 就是上图父类中需要关注的两个方法 ):
-
ServletOutputStream getOutputStream() throws IOException; 用流发送就用这个 PrintWriter getWriter() throws IOException; 发送中文就用这个( "javaSE中说的流技术的打印流嘛" )
-
-
-
先来看一下这个东西的源码,看看可以找到什么好玩的( 没提到的自己看源码,如:第二个图中的那些数字,就是状态码,也就是前面http中说的响应码 )
-
-
-
设置响应头的一些方法( 去HttpServletResponse中找嘛 ) ——— 至于响应头的组成是什么,跟着前面一开始用百度抓包哪里进去看一下就知道了 —— 请求就是request 、 响应就是response
-
设置响应头的一些方法( 去HttpServletResponse中找嘛 ) ——— 至于响应头的组成是什么,跟着前面一开始用百度抓包哪里进去看一下就知道了 —— 请求就是request 、 响应就是response
-
-
-
(1)、HttpServletResponse对象的应用
- 前面这些使用web.xml注册servlet( 这个是为了springMVC做个准备而已,所以玩一下web.xml ) 和 使用maven加载jar包也玩的差不多了,那么:现在使用注解来注册servlet 和 手动加载jar包 ,涨涨见识嘛
- 另外:为了以防带偏了,所以:前端不再通过jsp写页面,而是回归原始的html来写,这样顺便引申出ajax异步请求的事
- 注意:这里不用maven不是说maven不重要啊,实际开发用的就是maven( 所以maven很重要的 ),然后集成各种框架,这里是为了演示另外一种开发模式
-
(1)、HttpServletResponse对象的应用
-
-
-
①、重定向 ———— 也是httpServletResponse对象应用得最多的一个点
-
准备工作:新建模板,不再建maven项目
-
创建成功之后如下:
-
-
准备工作:新建模板,不再建maven项目
-
①、重定向 ———— 也是httpServletResponse对象应用得最多的一个点
-
-
-
-
-
现在来开始玩httpServletResponse的重定向 —— 其实很简单,就一句话而已
-
整两个html页面
-
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>登录页面</title> <link rel="stylesheet" href="/css/login.css"> </head> <body> <div class="box"> <h2>登录</h2> <form action="users/users.do" method="post" > <div class="inputBox"> <input type="text" name="username" required=""> <label>用户名</label> </div> <div class="inputBox"> <input type="password" name="password" required=""> <label>密码</label> </div> <input type="submit" value="登录" > </form> </div> </body> </html>
-
body { margin:0; padding: 0; font-family: sans-serif; background: url("/img/loginbg.png"); background-size: cover; } .box { position: absolute; top:50%; left: 50%; transform: translate(-50%,-50%); width:400px; padding: 40px; background: rgba(0,0,0,.8); box-sizing : border-box; box-shadow: 0 15px 25px rgba(0,0,0,.5); border-radius: 10px; } .box h2 { margin:0 0 30px; padding: 0; color: #fff; text-align: center; } .box .inputBox { position: relative; } .box .inputBox input { width:100%; padding: 10px 0; font-size: 16px; color: #fff; letter-spacing: 1px; margin-bottom: 30px; border: none; border-bottom: 1px solid #fff; outline: none; background: transparent; } .box .inputBox label { position: absolute; top:0; left: 0; padding: 10px 0; letter-spacing: 1px; font-size: 16px; color: #fff; pointer-events: none; transition: .5s; } .box .inputBox input:focus ~ label, .box .inputBox input:valid ~ label { top:-18px; left:0; color:#03a9f4; font-size: 12px; } .box input[type="submit"] { background: transparent; border: none; outline:none; color: #fff; background: #03a9f4; padding: 10px 20px; cursor:pointer; border-radius: 5px; }
-
-
整两个html页面
-
现在来开始玩httpServletResponse的重定向 —— 其实很简单,就一句话而已
-
-
-
-
-
-
-
-
package cn.xieGongZi.sendRedirect; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; /* @WebServlet("/users/users.do") 这个注解就是注册servlet,而:/users/users.do 就是以前配置的<url-pattern> 也就是:前端所需要的接口名( 这里是login.html中的那个action路径 , 这个接口名字就是前端和后台连在一起的接口 ) 所以:这个servlet层也叫控制层 / 接口层 这个会在后续的MVC三层架构中进行说明 */ @WebServlet("/users/users.do") public class sendRedirectServlet extends HttpServlet { // 前端的那个form表单是用的post提交,所以:这里只需要重写dopost()方法即可 @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 一来就设置乱码的问题 req.setCharacterEncoding("utf-8"); resp.setCharacterEncoding("utf-8"); resp.setContentType("text/html;charset=utf-8"); // 这个设置就是当要响应给浏览器的页面是一个html时, // 那么就需要告知浏览器,这个文本内容是一个html格式,字符编码为:utf-8 // 所以:一般servlet都需要配置这个三个 System.out.println( "进入到重定向的servlet中来了"); // 获取前端传过来的参数 大多数时候都是如下的方法获取,有例外的,就是input type = "file"时,这个的获取不一样,后续会进行说明 String username = req.getParameter("username"); // 这个参数名必须和前端的name名一样 String password = req.getParameter("password"); if ( username.equals("admin") && password.equals("123456") ){ // 重定向 httpServletResponse.sendRedirect("/项目名/要进行重定向的url") resp.sendRedirect( "/responseContent.html"); }else { // 给浏览器发送信息 中文是getWriter() 流是getOutputStream() resp.getWriter().print("找不到页面"); // 这也是httpServletResponse的其中一个应用 } } }
-
配置tomcat
-
-
-
-
-
-
-
-
-
-
-
-
说明一个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"> <!-- <welcome-file-list>就是设置服务器启动之后,在浏览器中打开的第一个页面是什么页面 --> <welcome-file-list> <welcome-file>login.html</welcome-file> </welcome-file-list> </web-app>
-
-
运行效果如下:
-
输入admin和123456如下:
-
-
说明一个web.xml中的小配置
-
-
-
-
-
-
-
-
②、下载文件 —— 这个东西很有用哦
- 这个下载文件别理解错了,是说的:把服务器上的文件传到浏览器中,然后别人访问指定路径的时候,就可以出现文件下载的操作
-
②、下载文件 —— 这个东西很有用哦
-
-
-
-
-
-
-
思路:
- 1、得知道服务器中的文件资源在什么地方涩
- 2、需要告知浏览器,要下载的文件名是什么涩
- 3、让浏览器支持文件下载 —— 这一步就需要用到httpServletResponse的知识
-
4、把服务器中的文件输出到浏览器中 —— 本质是:javaSE中说的流技术的三板斧:创建流管道、读 / 写数据、关闭流管道
- (1)、创建缓冲区
- (2)、获取输入、输出流对象
- (3)、输出文件
- (4)、关闭流管道
-
思路:
-
-
-
-
-
-
-
-
实操一下:
-
package cn.xieGongZi.servlet; import javax.servlet.ServletException; import javax.servlet.ServletOutputStream; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.FileInputStream; import java.io.IOException; import java.net.URLEncoder; @WebServlet("/downFile") public class downFileInClientServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doPost(req, resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 1、获取让浏览器下载的文件路径 String FileRealPath = "D:\\JavaTrainStudy\\servlet\\out\\production\\study06-httpServletResponse\\loginbg.png"; // 2、告知浏览器要下载的文件名是什么? String fileName = FileRealPath.substring( FileRealPath.lastIndexOf("\\") + 1 ); // 3、让浏览器支持文件下载 ———— 这个记不住没关系,直接百度:response设置头信息 // Content-Disposition这个就是让浏览器支持文件下载 // URLEncoder.encode( String s , String enc ) 是为了以防文件名是中文名,这样就设置编码格式了,让浏览器能够解析这个中文文件名 resp.setHeader("Content-Disposition" , "attachment ; filename=" + URLEncoder.encode(fileName , "utf-8")); // 4、获取输入、输出流对象 并 把服务器中的文件输出到浏览器上 FileInputStream fis = new FileInputStream( FileRealPath ); ServletOutputStream os = resp.getOutputStream(); // 创建缓冲区 —— 输出流技术的基础知识 固定流程 int len = 0 ; byte[] buffer = new byte[1024]; while ( ( len = fis.read( buffer ) ) > 0 ){ os.write( buffer , 0 , len); } // 5、关闭流管道 —— 倒着关闭 if ( os != null ){ os.close(); } if ( fis != null ){ fis.close(); } } }
-
-
-
实操一下:
-
-
-
-
6)、cookie和session ———— 很重要,特别是session,用的最多,而cookie是session的原理
-
①、cookie 和 session是什么意思 —— 会话
-
(1)、怎么理解cookie?
- 好比:老衲去一个皮包骨公司,前提是第一次去啊,去的时候皮包骨公司的负责人肯定不认识我涩,但是啊,有一就有二了嘛,所以我第一次去的时候,皮包骨公司的负责人在他们那边帮我注册了一个身份验证号码,那么:我下一次去的时候,只需要告知皮包骨公司那边的人这个身份验证码,我就可以进去了
-
(1)、怎么理解cookie?
-
①、cookie 和 session是什么意思 —— 会话
-
-
-
(2)、cookie和session的本质是会话,那么会话是什么意思?
- 好比:用户打开浏览器,点了很多超链接,中间进行了很多次的页面跳转,最后关闭浏览器,这整个过程就是一个会话
-
(2)、cookie和session的本质是会话,那么会话是什么意思?
-
-
-
-
- 有状态会话:就是前面理解cookie中举的例子
-
-
-
-
-
(2)、怎么理解session?
- 好比:贫僧去飘香楼,准备找一个叫小桃红的头牌,但是老衲可能倒了血霉,飘香楼不让我进去,而飘香楼的负责人是我的好朋友,因此她把我带进去了,同时给了老衲一份信件,信件里面是一张卡( 这张卡可以刷门禁嘛 —— 即:有身份识别的号码涩 ),然后我下一次来的时候,只需要带上这张卡就可以进去了涩( 因为:这张卡本身就有身份识别号码嘛 —— 换言之:这个身份识别号码就是一个cookie涩 )
-
(2)、怎么理解session?
-
-
-
- 因此:通过上述的说明,就可以知道 cookie就是session的底层原理咯
-
-
-
②、扯了那么多,还是来玩一下cookie和session吧
-
(1)、cookie
-
package cn.xieGongZi.servlet; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; @WebServlet("/cookie.do") public class CookieServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { req.setCharacterEncoding("utf-8"); resp.setCharacterEncoding("utf-8"); // 创建一个Cookie Cookie cookie = new Cookie("name", "紫邪情"); // 保存cookie resp.addCookie( cookie ); // 取cookie的中存的值 resp.getWriter().print( cookie.getValue() ); // cookie就是一个普通的类而已,所以其他的东西可以点源码看一下,也就是什么get 和 set方法而已 } }
-
-
(1)、cookie
-
②、扯了那么多,还是来玩一下cookie和session吧
-
-
-
-
知识延伸:
-
(1)、怎么删除cookie?
- 不设置有效期,关闭浏览器就没了
-
设置有效期为0
-
cookie.setMaxAge(0);
-
-
(1)、怎么删除cookie?
-
知识延伸:
-
-
-
-
-
-
-
(2)、cookie被保存在什么地方?
- 在本地用户的appdata中,也就是在盘符中搜这个就可以找到
-
在浏览器中怎么看cookie?
-
(2)、cookie被保存在什么地方?
-
-
-
-
-
-
-
-
(3)、关于cookie的一些小细节
- 一个web站点可以给浏览器发送很多个cookie,但是一个web站点只能存放20个cookie
- 一个cookie只能存放一个信息( key-value的形式存储的 )
- 一个浏览器最多存放300个cookie
-
(3)、关于cookie的一些小细节
-
-
-
-
-
-
(2)、session —— 很重要很重要 特别是:下面实例中用的三个方法:获取session、给session添加数据、取session中的数据。另外:这是servlet三大作用域的另一个作用域,简称:会话域
-
package cn.xieGongZi.servlet; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import java.io.IOException; @WebServlet("/session.do") public class SessionServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { req.setCharacterEncoding("utf-8"); resp.setCharacterEncoding("utf-8"); // 获取session HttpSession session = req.getSession(); // 给session存放东西 session.setAttribute("地点" , "到怡红院汇合"); session.setAttribute("名字" , "大保健"); // 获取session中保存的信息 resp.getWriter().print( session.getAttribute("地点")); // 删除session session.removeAttribute("名字"); // 其他的方法 通过 session. 就可以看到了 } }
-
-
(2)、session —— 很重要很重要 特别是:下面实例中用的三个方法:获取session、给session添加数据、取session中的数据。另外:这是servlet三大作用域的另一个作用域,简称:会话域
-
-
-
-
-
什么地方会用Session?
- 做登录页面的时候,保证必须登录成功才可以进行操作,不能直接通过输入url地址,然后进到相应的页面去( 即:跳过了登录页面 )
- 购物车信息
- 网站经常使用的数据,保存到session中
-
什么地方会用Session?
-
-
-
7)、httpServletRequest对象 —— 请求对象 很重要很重要( 虽然用的不多,实际开发中用得最多的是httpServletResponse对象 ),但是:这个httpServletRequest对象是servlet三大作用域的另一个作用域,简称:请求域
-
(1)、和httpServletResponse对象一样的老规矩,去看一下这个的源码,看能得到什么信息
-
-
(1)、和httpServletResponse对象一样的老规矩,去看一下这个的源码,看能得到什么信息
-
-
(2)、httpServletRequest对象的应用
-
请求转发 —— 在一个请求中想要携带数据到下一个请求中就可以使用这个请求转发
-
和ServletContxnt对象的请求转发是一样的,还是一句代码搞定,只不过把对象名从servletContext换成httpServletRequest对象而已( 简称:req ),所以:这里就不演示了,只弄出语法
-
req.getRequestDispatcher("/要跳转的url地址").forward( req,resp );
-
-
和ServletContxnt对象的请求转发是一样的,还是一句代码搞定,只不过把对象名从servletContext换成httpServletRequest对象而已( 简称:req ),所以:这里就不演示了,只弄出语法
-
请求转发 —— 在一个请求中想要携带数据到下一个请求中就可以使用这个请求转发
-
(2)、httpServletRequest对象的应用
-
8)、前面一直说到servlet的三大作用域,都已经说明完了,现在来总结一下有哪些 ———— 很重要,学servlet其实就三大作用域、三大组件而已,其他的都是给自己增加墨水罢了
-
从小到大为:
- (1)、httpServletRequest 请求域
- (2)、httpSession 会话域
- (3)、servletContext 全局域
-
从小到大为:
-
-
- 这三个存、取、移除数据的方法都是一样的:setAttribute() 、getAttribute() 、 removeAttribute()
-
-
-
这个从小到大具体是个什么意思?
- 请求域 即:只能在请求中有效,也就是换一个请求之后就拿不到数据了
- 会话域 即:在一个会话中有效,也就是浏览器级别的,在不同的浏览器中拿不到数据
- 全局域 即:全局有效,前提是没有关服务器,因此:这就是服务器级别的,只要服务器是开着的,那么在什么地方访问这个服务器中的servlet都可以拿到数据
- 演示:就直接跳过了,可以自行构思一下,然后实现出来( 百度视频一下也可以 )
-
这个从小到大具体是个什么意思?
-
9)、聊聊servlet的生命周期和其线程安全问题
-
①、servlet的生命周期
- 指的就是servlet从创建到销毁的一个过程嘛,而这个过程是怎么做的呢?也很简单,方法一说就知道了。
- (1)、创建 通过构造器来创建 即:继承httpServlet的当前类 的构造器就可以创建了
- (2)、初始化 调用了init()方法进行初始化servlet
- (3)、服务 调用的是service()方法 —— 这个方法中我们做的最多的方法就是doGet() 和 doPost()
- (4)、销毁 调用了destroy()方法
- 就不演示了,可以自行继承了httpServlet之后重写一下这几个方法测试一下
-
①、servlet的生命周期
-
-
②、servlet的线程安全问题
- 首先直接告知答案:servlet是线程不安全的
-
为什么?
- 试想一下:N多人登录一个系统,但是在后台登录操作都是用的一个servlet涩 —— 这个联想到什么?说明servlet是开了多线程的,即:每一个人登录都是在单独的一条线程中进行的
- 但是:这么多人虽然登录都是在不同的线程中,可是:它们还是属于同一个servlet涩( 可以理解为:把这个servlet拷贝了N多份,然后每有一个用户来进行登录请求操作,就开启一条线程,然后这个线程中的servlet就是拷贝出来的这一份 ) —— 这里不要有人出现:他们都是用的同一个servlet,那为什么可以出现N多人同时登录都得行,不应该是一个登录之后才可以出现另一个人登录吗? 出现这个问题的话,那他喵的多线程就白学了 —— 宏观来看:多线程是同步执行的,但是本质是有先后顺序的( 即:一个线程执行一会另一个线程执行一会 ,是交替执行的 )
-
由第二点其实就知道了处理这个servlet的安全问题应该怎么解决了
- servlet是拷贝了N多份,那怎么保证别人用的servlet都是同一个呢?首先联想到的就是单例模式呗,而这个在java中封装好了,只需要实现singleThreadModul就可以了
- 当然还有一种实现方式:不得不吐槽,这种方式不知道是谁整出来的,真心不推荐,了解即可。这种解决方法就是把servlet弄成一个实例变量( 当然:个人建议,把这个实例变量使用ThreadLocal封装起来 —— 这个ThreadLocal已经在JDBC中说过了 )
-
②、servlet的线程安全问题
-
10)、servlet的三大组件
- ①、servlet 第一个组件就是servlet本身,前面已经玩得差不多了
- ②、filter 过滤器
- ③、listener 监听器
-
-
(2)、filter 过滤器
-
filter是什么?
-
很简单,在浏览器中发起请求,然后进到后台不是需要经过一层servlet吗,所以filter就是在servlet的前面加了一层,先过滤一些东西之后再进入到servlet中去,最后从后台到浏览器的时候,再次经过过滤器,从而到达浏览器。来个图理解一下:
-
-
很简单,在浏览器中发起请求,然后进到后台不是需要经过一层servlet吗,所以filter就是在servlet的前面加了一层,先过滤一些东西之后再进入到servlet中去,最后从后台到浏览器的时候,再次经过过滤器,从而到达浏览器。来个图理解一下:
-
filter是怎么玩的? 也很简单
- (1)、编写一个java普通类( 当然最好见名知意,即:让人知道你这过滤器是用来干嘛的 )
- (2)、让这个类实现filter接口就行( 这个filter是javax.servlet包下的 )
- (3)、重写init()、doFilter()、destroy()方法 ( 当然:有些人的集成开发环境中只需要重写doFilter就可以了,但有些是必须重写这三个才行 , 我的是只需要重写doFilter() , 因此:我的演示也只重写这一个 )
- (4)、配置要过滤的是哪些请求( 这个也可以通过web.xml 和 注解来实现 , 示例中使用注解,要玩web.xml的面向百度 )
-
filter是什么?
-
(2)、filter 过滤器
-
-
-
实操玩一下
-
package cn.xieGongZi.servlet; import javax.servlet.*; import javax.servlet.annotation.WebFilter; import java.io.IOException; /* * @WebFilter() 这个注解就是设置过滤的条件,* 代表所有,即:本示例中为 过滤所有以 do结尾 的请求 * */ @WebFilter("*.do") public class Filter implements Filter { @Override public void doFilter(ServletRequest req, ServletResponse resp, FilterChain filterChain) throws IOException, ServletException { // 以前每写一个servlet不是都需要配置请求和响应编码格式吗,那么把那个格式设置放在这个过滤器中来 req.setCharacterEncoding("utf-8"); resp.setCharacterEncoding("utf-8"); resp.setContentType("text/html;charset = utf-8"); // 对request 和 response对象进行放行 // 为什么需要进行放行, 过滤器是在servlet层的前面,不放行的话,那么这两个对象就无法到达servlet层了嘛 // 这样就会导致在servlet层中没有这两个对象了 filterChain.doFilter(req,resp); } }
-
package cn.xieGongZi.servlet; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; @WebServlet("/test/testFilter.do") public class TestFilterServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doPost(req, resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 以前是在这里设置了请求 和 响应的编码格式 有了过滤器就不用了 resp.getWriter().print("你要整哪样?"); // 有了过滤器,这个中文绝对不乱码 } }
-
效果如下:
-
实操玩一下
-
-
-
(3)、listener监听器 —— 了解即可
- 这个玩意儿就和前端中学的绑定事件是一样的道理,所以了解即可
-
(3)、listener监听器 —— 了解即可
-
-
- 实际意义:这个玩意儿就是对三大作用域的生命周期、域中的数据变化起到监控作用
-
-
-
-
没什么好玩的,要对什么域进行监听,就让编写的类实现这种域的监听器就可以了,然后加上 @webListener注解 即可
-
@WebListener public class MySessionListener implements HttpSessionListener, HttpSessionAttributeListener { // 监听Session 创建 @Override public void sessionCreated(HttpSessionEvent httpSessionEvent) { System.out.println("session 创建了"); } @Override public void sessionDestroyed(HttpSessionEvent httpSessionEvent) { System.out.println("session 销毁了"); } @Override public void attributeAdded(HttpSessionBindingEvent httpSessionBindingEvent) { System.out.println("添加数据"); } @Override public void attributeRemoved(HttpSessionBindingEvent httpSessionBindingEvent) { System.out.println("移除数据"); } @Override public void attributeReplaced(HttpSessionBindingEvent httpSessionBindingEvent) { System.out.println("修改数据"); } }
-
-
没什么好玩的,要对什么域进行监听,就让编写的类实现这种域的监听器就可以了,然后加上 @webListener注解 即可
-
至此:javaWeb的一部分知识已完毕
接下来就是ajax、jsp( 重点:EL、JSTL表达式 )
作者:紫邪情
出 处:
https://www.cnblogs.com/xiegongzi/p/15302060.html