javaWeb
Servlet到底是什么(非常透彻) (biancheng.net)
1.基本概念
1.1前言
web开发:
- web,网页的意思,www.baidu.com 
- 静态web - html,css
- 提供给所有人看的数据不会变化
 
- 动态web - 淘宝,几乎所有的网站
- 每个人看的数据会变化,不同时间,不同地点看到的都不同
- 技术栈:Servlet/JSP,ASP,PHP
 - 在java中,动态web资源开发的技术统称为javaWeb 
1.2web应用程序
web应用程序:可以提供浏览器访问的程序;(a.html、b.html…)
- URL 
- 这个统一的web资源会放在同一个文件夹下,web应用程序—>Tomcat:服务器 
- 一个web应用由多个部分组成(静态web,动态web) - html, css, js
- jsp, servlet
- java程序
- jar包
- 配置文件(Properties)
 - web应用程序编写完成后,若想提供给外界访问;需要一个服务器来统一管理 
1.3静态web
- *.htm, *.html, 都是网页后缀,如果服务器上一直存在这些,就可以直接访问

- 静态web存在的缺点- Web页面无法更新,所有用户看到的都是一样的内容- 轮播图,点击特效:伪动态
- JavaScript[实际开发,它用的多]
- VBScript(微软用)
 
- 它无法和数据库交互(数据无法持久化,用户无法交互)
 
- Web页面无法更新,所有用户看到的都是一样的内容
1.4动态web
页面可以动态展示,“Web的页面展示效果因人而异”

缺点
- 加入服务器的动态web资源出现错误,需要重新编写后台程序,然后发布- 停机维护
 
优点
- web页面可以动态更新,所有用户看到的页面不一样
- 可以和数据库交互(数据持久化:注册,商品信息..)
2.web服务器
2.1技术讲解
ASP:
- 微软:国内最早流行的就是ASP
- 在HTML中嵌入VB脚本,ASP+COM
- 在ASP开发中,基本一个页面都有上千行的业务代码,页面及其混乱
- 维护成本高!
- C#
- IIS
| 1 | <h1> | 
PHP:
- PHP开发速度很快,功能很强大,跨平台,代码很简单
- 无法承载大访问量的情况(局限性)
JSP/Servlet:
B/S:浏览器和服务器
C/S:客户端和服务端
- sun公司主推的B/S架构
- 基于Java语言的(所有的大公司,或者一些开源的组件,都用)
- 可以承载三高问题带来的影响:高并发,高可用,高性能
- 语法像ASP,加强市场强度
2.2web服务器
服务器是一种被动的操作,用来处理用户的一些请求和给用户一些响应信息
IIS
微软的;ASP…,Windows中自带的
Tomcat

Tomcat是Apache 软件基金会(Apache Software Foundation)的Jakarta 项目中的一个核心项目,最新的Servlet 和JSP 规范总是能在Tomcat 中得到体现,因为Tomcat 技术先进、性能稳定,而且免费,因而深受Java 爱好者的喜爱并得到了部分软件开发商的认可,成为比较流行的Web 应用服务器。
Tomcat 服务器是一个免费的开放源代码的Web 应用服务器,属于轻量级应用服务器,在中小型系统和并发访问用户不是很多的场合下被普遍使用,是开发和调试JSP 程序的首选。对于一个初学javaWeb的人来说,是最佳选择
Tomcat和IIS等Web服务器一样,Tomcat最新版本为10.0.5。
工作3-5年,手写Tomcat
PS
java的添加机制:jdk–>jre–>lib–>rt.jar (jar包就是压缩包)
预览下可看到类:如String

3.Tomcat
3.1Tomcat启动和配置
进入Tomcat文件夹下:


/bin 文件下:

3.2配置
配置启动端口号(进入server.xml):
- Tomcat默认启动端口:8080
- mysql:3306
- http:80
- https:443
| 1 | <Connector port="8081" protocol="HTTP/1.1" | 
配置主机名称:
- 默认的主机名:localhost->127.0.0.1
- 默认网站应用存放的位置:webapps
| 1 | <Host name="www.liuchang.com" appBase="webapps" | 
高难度面试题
请你谈谈网站是如何访问的!
- 输入域名;回车 
- (访问域名后检查客户端的host配置文件)检查本机的 C:\Windows\System32\drivers\etc\hosts 配置文件下有没有这个域名映射 - 有:直接返回对应的ip地址,这个地址中,有我们需要访问的web程序,可以直接访问
 - 1 - 127.0.0.1 www.liuchang.com - 没有:去DNS服务器找,找到的话就返回,找不到就返回找不到;
 


4.HTTP
4.1什么是HTTP
超文本传输协议(HTTP)是一个简单的请求-响应协议,它通常运行在TCP之上。
- 文本:html,字符串。~…
- 超文本:图片,音乐,视频,定位
4.2两个时代
- http1.0- HTTP/1.0:客户端可以与服务器连接,但只能获得一个web资源,就断开连接
 
- http2.0- HTTP/1.1:客户端可以与服务器连接,获得多个web资源
 
4.3HTTP请求
- 客户端—-发请求(Request)—-服务器
百度:
| 1 | 1.请求行 | 
| 1 | 2.请求头 | 
- 请求行- 请求行中的请求方式:GET
- 请求方式:GET,POST,HEAD,DELETE,PUT,TRACT…- get:请求能携带的参数比较少,大小有限制,会在浏览器的URL地址栏显示数据内容,不安全,但高效
- post:请求能携带的参数没有限制,大小没有限制,不会在浏览器的URL地址栏显示数据内容,安全,但不高效
 
 
- 消息头
| 1 | Accept:告诉浏览器,所支持的数据类型 | 
4.4HTTP响应
- 服务器—-响应—-客户端
百度:
| 1 | Cache-Control: private 缓存控制 | 
- 响应体
| 1 | Accept:告诉浏览器,所支持的数据类型 | 
- 响应状态码 - 200:响应成功 - 3xx:请求重定向 - 重定向:重新到我规定的新的位置
 - 4xx:找不到资源 404 - 资源不存在
 - 5xx:服务器代码错误 500 502:网关错误 
常见面试题:
当你的浏览器中地址栏输入地址并回车的一瞬间到页面能够展示回来,经历了什么?
5.Maven
我问什么要学习这个技术?
- 在Javaweb开发中,需要使用大量的jar包,我们手动去导入 
- 如何能够让一个东西自动帮我们导入和配置jar包 - Maven诞生了 
5.1Maven项目架构管理工具
目前用来就是方便导入jar包
Maven的核心思想:约定大于配置
- 有约束,不要去违反
Maven会规定好如何去编写Java代码,按照这个规范来
小建议:电脑上所有环境放在同一个文件夹中
5.2Maven下载安装

| 1 | bin //执行文件 | 
5.3配置环境变量
在系统环境变量中配置:
- M2_HOME maven目录下的bin目录
- MAVEN_HOME maven的目录
- 在系统变来那个PATH中配置%MAVEN_HOME%\bin
5.4阿里云镜像
镜像(mirrors):方便下载使用;国内建议使用阿里云
     Maven国外的,国内有墙,我们访问外网会很慢; 翻墙:VPN
| 1 | <mirror> | 
5.5本地仓库
在本地的仓库,远程仓库:
建立一个本地仓库:localRepository
Maven下新建一个文件夹,settings.xml中改仓库地址
| 1 | <localRepository>D:\Maven\apache-maven-3.8.3\maven-repo</localRepository> | 


5.6在IDEA中使用Maven
- 创建一个MavenWeb项目   


- 等待Maven安装完毕  
- IDEA中的Maven设置 - 注意:IDEA项目创建成功后,看一眼Maven配置  

- 到这里,Maven在IDEA中的配置和使用就OK了
5.7创建一个普通的Maven项目


这个只有在web应用下才会有:

5.8标记文件夹功能(2选1)




5.9在IDEA中配置Tomcat


解决警告问题
必须要的配置:为什么会有这个问题:我们访问一个网站,需要指定一个文件夹名字;



5.10 pom文件

| 1 | 
 | 

maven由于他的约定大于配置,我们之后可能会遇到我们写的配置文件无法到处或生效的问题(mybatis中会遇到),解决方案:
| 1 | <!-- 在build中配置resources,来防止我们资源导出失败的问题--> | 
5.11 IDEA操作

5.12 解决遇到的问题
- Mavne默认web项目中 web.xml 的版本问题  
- 替换成Tomcat中web.xml的版本(保证和Tomcat一致)  
| 1 | <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" | 
6.Servlet
6.1Servlet简介
- Servlet就是sun公司开发动态web的一门技术
- sun公司在这些API中提供一个接口叫做:Servlet,如果想开发一个Servlet程序没只需要完成两个步骤- 编写一个类,实现Servlet接口
- 把开发好的java类部署到web服务器中
 
把实现Servlet接口的Java程序叫做,Servlet
6.2 HelloServlet
Servlet接口Sun公司有两个默认的实现类:HttpServlet,
- 构建一个普通的Maven项目,删掉里面的src目录,以后我们的学习就在这个项目里建立Model; - 这个空的工程就是Maven主工程 

- 关于Maven父子工程的理解: - 父项目中有: - 1 
 2
 3- <modules> 
 <module>servlet-01</module>
 </modules>- 子项目中有: - 1 
 2
 3
 4
 5-  <parent> 
 <artifactId>javaweb-02-servlet</artifactId>
 <groupId>org.example</groupId>
 <version>1.0-SNAPSHOT</version>
 </parent>- 父项目中的Java子项目可以直接使用 - 1 - son extends father 

- Maven环境优化- 修改web.xml为最新的
- 将maven的结构搭建完整
 
- 编写一个Servlet程序- 编写一个普通类
- 实现Servlet接口,这里直接继承HttpServlet
 
| 1 | public class HelloServlet extends HttpServlet { | 
- 编写Servlet的映射 - 为什么需要映射:我们写的是Java程序,但是要通过浏览器访问,而浏览器需要链接web服务器,所以我们需要在web服务中注册我们写的Servlet,还需给他一个浏览器能够访问的路径 
| 1 | <!-- 注册Servlet--> | 
- 配置Tomcat 
- 启动测试 
6.3 注意的问题:
- 两处申请名字要一致


- 代理抛出异常(端口1099被占用)


- 运行之前要maven clean-package;更新target文件
6.4 查看日志


6.5 Servlet运行原理
Servlet是由Web服务器调用,Web浏览器在收到浏览器请求后,会:

6.6 Mapping问题
- 一个Servlet请求可以指定一个映射路径 - 1 
 2
 3
 4- <servlet-mapping> 
 <servlet-name>hello</servlet-name>
 <url-pattern>/chang</url-pattern>
 </servlet-mapping>
- 一个Servlet请求可以指定多个映射路径 - 1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12- <servlet-mapping> 
 <servlet-name>hello</servlet-name>
 <url-pattern>/chang</url-pattern>
 </servlet-mapping>
 <servlet-mapping>
 <servlet-name>hello</servlet-name>
 <url-pattern>/chang1</url-pattern>
 </servlet-mapping>
 <servlet-mapping>
 <servlet-name>hello</servlet-name>
 <url-pattern>/chang2</url-pattern>
 </servlet-mapping>
- 一个Servlet请求可以指定通用映射路径 - 1 
 2
 3
 4- <servlet-mapping> 
 <servlet-name>hello</servlet-name>
 <url-pattern>/chang/*</url-pattern>
 </servlet-mapping>
- 默认请求路径 - 1 
 2
 3
 4
 5- <!--使用这个会将首页覆盖掉--> 
 <servlet-mapping>
 <servlet-name>hello</servlet-name>
 <url-pattern>/*</url-pattern>
 </servlet-mapping>
- 指定一些后缀或者前缀 - 1 
 2
 3
 4
 5
 6
 7- <!--可以自定义后缀实现请求映射 
 注意:*前面不能加项目映射的路径
 hello/asdfsf.do-->
 <servlet-mapping>
 <servlet-name>hello</servlet-name>
 <url-pattern>*.do</url-pattern>
 </servlet-mapping>
- 优先级问题 - 指定了固有的映射路径优先级最高(在搜索框中输入),找不到就走默认的路径 
6.7 ServletContext
了解一些重点的
| 1 | 
 | 
| 1 | <!-- 只做了解,估计用不上--> | 
web容器在启动的时候,它会为每个web程序都创建一个对应的ServletContext对象,它代表了当前的web应用;(起到中间商的作用)
- 数据共享
我在这个Servlet中保存的数据,可以在另外一个Servlet中拿到;

1.文件结构

| 1 | //HelloServlet | 
| 1 | //GetServlet | 
| 1 | <!--web.xml--> | 

- 获取初始化参数
| 1 | <!-- 配置一些web应用初始化参数--> | 
| 1 | public class ServletDemo03 extends HttpServlet { | 

- 请求转发(留意后续有重定向的变化)
| 1 | 
 | 

- 读取资源文件 - properties - 在Java目录下新建properties
- 在resources目录下新建properties
 - 发现都打包到了同一路径下:classes。我们俗称这个路径为classpath(类路径) - 思路:需要一个文件流  
| 1 | username=root | 
| 1 | public class ServletDemo05 extends HttpServlet { | 
| 1 | <!--做映射--> | 


6.8HttpServletResponse
web服务器接收到客户端的http请求,针对这个请求,分别创建一个代表请求的HttpServletRequest对象,代表响应的一个HttpServletResponse;
- 如果要获取客户端请求过来的参数:找HttpServletRequest
- 如果要给客户端响应一些信息:找HttpServletResponse
源码分析:
- 简单分类 - 负责向浏览器发送数据的方法 - ```java
 ServletOutputStream getOutputStream() throws IOException;
 //一般流用它
 PrintWriter getWriter() throws IOException;
 //中文用它1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 负责向浏览器发送响应头的方法
 * ```java
 void setCharacterEncoding(String var1);
 
 void setContentLength(int var1);
 
 void setContentLengthLong(long var1);
 
 void setContentType(String var1);
 
 void setDateHeader(String var1, long var2);
 
 void addDateHeader(String var1, long var2);
 
 void setHeader(String var1, String var2);
 
 void addHeader(String var1, String var2);
 
 void setIntHeader(String var1, int var2);
 
 void addIntHeader(String var1, int var2);
 - 响应状态码 - ```java
 //常量int SC_CONTINUE = 100; int SC_SWITCHING_PROTOCOLS = 101; int SC_OK = 200; int SC_CREATED = 201; int SC_ACCEPTED = 202; int SC_NON_AUTHORITATIVE_INFORMATION = 203; int SC_NO_CONTENT = 204; int SC_RESET_CONTENT = 205; int SC_PARTIAL_CONTENT = 206; int SC_MULTIPLE_CHOICES = 300; int SC_MOVED_PERMANENTLY = 301; int SC_MOVED_TEMPORARILY = 302; int SC_FOUND = 302; int SC_SEE_OTHER = 303; int SC_NOT_MODIFIED = 304; int SC_USE_PROXY = 305; int SC_TEMPORARY_REDIRECT = 307; int SC_BAD_REQUEST = 400; int SC_UNAUTHORIZED = 401; int SC_PAYMENT_REQUIRED = 402; int SC_FORBIDDEN = 403; int SC_NOT_FOUND = 404; int SC_METHOD_NOT_ALLOWED = 405; int SC_NOT_ACCEPTABLE = 406; int SC_PROXY_AUTHENTICATION_REQUIRED = 407; int SC_REQUEST_TIMEOUT = 408; int SC_CONFLICT = 409; int SC_GONE = 410; int SC_LENGTH_REQUIRED = 411; int SC_PRECONDITION_FAILED = 412; int SC_REQUEST_ENTITY_TOO_LARGE = 413; int SC_REQUEST_URI_TOO_LONG = 414; int SC_UNSUPPORTED_MEDIA_TYPE = 415; int SC_REQUESTED_RANGE_NOT_SATISFIABLE = 416; int SC_EXPECTATION_FAILED = 417; int SC_INTERNAL_SERVER_ERROR = 500; int SC_NOT_IMPLEMENTED = 501; int SC_BAD_GATEWAY = 502; int SC_SERVICE_UNAVAILABLE = 503; int SC_GATEWAY_TIMEOUT = 504; int SC_HTTP_VERSION_NOT_SUPPORTED = 505;1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 2. **常见应用**
 1. 向浏览器输出消息(前头一直在讲)
 2. 下载文件
 1. 获取下载文件的路径
 2. 获取下载文件名
 3. 使浏览器支持我们的下载
 4. 获取下载文件的输入流
 5. 创建缓冲区
 6. 获取OutputStream对象
 7. 将FileOutputStream流写入到buffer缓冲区
 8. 使用OutputStream将缓冲区的数据输出到客户端
 ```java
 @Override
 protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
 //1. 获取下载文件的路径
 String realPath = "D:\\IDEA\\Maven\\javaweb-02-servlet\\response\\src\\main\\resources\\1.jpg";
 System.out.println("下载的文件路径:"+realPath);
 //2. 获取下载文件名
 String filename = realPath.substring(realPath.lastIndexOf("//") + 1);//让它识别斜杠后面的文件名;双斜杠用于转义斜杠
 //3. 使浏览器支持(Content-disposition)我们的下载
 resp.setHeader("Content-disposition","attachment;filename="+filename);
 //4. 获取下载文件的输入流
 FileInputStream in = new FileInputStream(realPath);
 //5. 创建缓冲区
 int len = 0;
 byte[] buffer = new byte[1024];
 //6. 获取OutputStream对象
 ServletOutputStream out = resp.getOutputStream();
 //7. 将FileOutputStream流写入到buffer缓冲区,使用OutputStream将缓冲区的数据输出到客户端
 while ((len=in.read(buffer))>0){
 out.write(buffer,0,len);
 }
 //8.关闭流
 in.close();
 out.close();
 
 //如何让浏览器3秒自动刷新一次
 //resp.setHeader("refresh","3");
 }
 
- ```java
- 验证码功能(了解一下原理) - 怎么验证; - 前端实现
- 后端实现,需要用到Java的图片类,生产一个图片
 
- 实现重定向(需要掌握) 
一个web资源收到客户端请求,他会通知客户端去访问另外一个web资源
常见场景:
- 用户登录,登录成功后访问另一个页面
| 1 | void sendRedirect(String var1) throws IOException; | 
测试:
| 1 | 
 | 
面试题:重定向和转发的区别
相同点
- 页面都会实实现跳转
不同点
- 请求转发的时候,url不会产生变化
- 重定向的时候,url地址栏会发生变化

| 1 | <%--index.jsp--%> | 
| 1 | <%--success.jsp--%> | 
| 1 | //RequestTest | 

6.9HttpServletRequest
HttpServletRequest代表客户端的请求,用户通过HTTP协议访问服务器,HTTP请求中的所有信息会被封装到HttpServletRequest,通过这个HttpServletRequest的方法,获得客户端的所有信息
获取前端传递参数,请求转发

一个返回string,一个返回数组;多个和单个
| 1 | 
 | 
7.Cookie、Session
7.1 会话
会话:用户打开一个浏览器,点击了很多超链接,访问多个web资源,关闭浏览器,这个过程叫会话
有状态会话:一个同学来过教室,下次再来,我们会知道这个同学,曾经来过
你怎么正面你是清华的学生?
对象: 你 清华
- 发票 清华给你发票
- 学校登记 清华标记你来过了
一个网站,怎么证明你来过
客户端 服务端
- 服务端给客户端一个信件,客户端下次访问客户端带上信件就可以了;cookie
- 服务器登记你来过了,下次你来的时候我匹配你;session
7.2 保存会话的两种技术
cookie
- 客户端技术(响应,请求)
session
- 服务器技术,利用这个技术,可以保存用户的会话信息,可以把信息或数据放在 session 中
常见场景:网站登录之后,下次不用登录,直接登上去
7.3 Cookie
- 从请求中拿到cookie信息
- 服务器响应给客户端cookie
| 1 | Cookie[] cookies = req.getCookies();//获得Cookie | 
cookie:一般会保存在本地的用户目录下 appdata;(不好,因为不安全)
一个网站cookie是否存在上限!细节问题
- 一个Cookie只能保存一个信息
- 一个web站点可以给浏览器发送多个Cookie,每个站点最多存放20个Cookie
- Cookie大小有限制4kb
- 300个Cookie,浏览器上限
删除Cookie:
- 不设置有效期,关闭浏览器,自动失效
- 设置有效期为0
编码解码:
| 1 | URLEncoder.encode("刘畅","utf-8");//编码 | 
7.4 Session(重点)
什么是Session:
- 服务器会给每一个用户(浏览器)创建一个Session对象
- 一个Session独占一个浏览器,只要浏览器没有关闭,这个Session就存在
- 用户登录之后,整个网站都可以访问,与网页无关 –>保存用户的信息;保存购物车信息…(长久保存的信息)
Session和Cookie的区别
- Cookie是把用户的数据写给用户的浏览器,浏览器保存(可以保存多个)
- Session是把用户的数据写到用户独占Session中,服务器保存(保存重要信息,减少服务器资源的浪费;一台浏览器对应一个Session)
- Session对象由服务器创建
使用场景:
- 保存一个登录用户的信息
- 购物车信息
- 在整个网站中经常会使用的数据,将保存在Session中
使用Session
| 1 | //实体类(Person) | 
| 1 | //SessionDemo01 | 
| 1 | //SessionDemo02 | 
| 1 | //SessionDemo03 | 
记得要在web.xml中映射地址
web.xml自动注销
| 1 | <!-- 设置Session默认的失效时间--> | 
8. JSP(老技术了,看懂就行)
8.1 什么是JSP
为了简化Servlet的前端语言
Java Server Pages: Java服务器页面,也和Servlet一样,用于动态web技术
8.2 JSP原理
思路:JSP是怎么执行的
- 代码没有问题
- 服务器内部工作- Tomcat有一个 work 目录
 
- 浏览器向服务器发送请求,不管访问什么资源,其实都是在访问Servlet
- JSP最终会被转换为一个Java类
JSP本质就是Servlet
我的源码地址:只有编译的时候会产生work文件夹,中的/ROOT,包含index.jsp页面和新建的
| 1 | C:\Users\帝轩王\AppData\Local\JetBrains\IntelliJIdea2020.1\tomcat\Unnamed_javaweb-02-servlet_13 | 
| 1 | //初始化 | 
- 判断请求 
- 内置一些对象 - 1 
 2
 3
 4
 5
 6
 7
 8- final javax.servlet.jsp.PageContext pageContext; //页面上下文 
 javax.servlet.http.HttpSession session = null; //session
 final javax.servlet.ServletContext application; //application
 final javax.servlet.ServletConfig config; //配置
 javax.servlet.jsp.JspWriter out = null; //输出对象
 final java.lang.Object page = this; //当前页
 HttpServletRequest request //请求
 HttpServletResponse response //响应
- 输出页面增加的代码 

8.3 JSP基础语法
耦合性太高(牵一发而动全身)
高聚合,低耦合是开发的追求
HSP是Java技术的一些应用,拥有一些扩充给语法(了解);Java所有语法都支持
**JSP表达式 **
| 1 | <%--JSP表达式 | 
JSP脚本片段
| 1 | <%--JSP脚本--%> | 
脚本片段的再实现
| 1 | <% | 
JSP声明
| 1 | <%! | 
JSP声明:会被编译到JSP生成的Java类中!其他的,就会被生成到_jspService方法中
在JSP嵌入Java
| 1 | ${} 取值用的,或在里头编辑 | 
8.4 JSP指令
| 1 | <%@ page ... %> 定义网页依赖属性,比如脚本语言、error页面、缓存需求等等 |