前四节为JavaWeb需要的前置知识和必要的环境配置,第五节Maven用于导入和管理jar包,可以跳过。
1. 基础概念
Javaweb:在Java中动态web资源开发的技术。
静态网页:提供给所有人看的数据都不会发生变化。
动态网页:数据会随不同人,不同时间,不同地点而改变。
web应用程序:可以提供浏览器访问的程序。
1.1 静态web
静态网页访问过程:
静态web缺点:
- web页面无法动态更新,所以用户看到的都是一个页面
- 无法和数据库交互
1.2 动态web
动态网页访问过程:
动态web缺点:
- 加入服务器的动态web资源出现错误,需要重新编写后台程序,重新发布。
- 停机维护
动态web优点:
- web页面可以动态更新:所有用户看到都不是同一个里面,例如淘宝
- 可以与数据库交互(数据持久化:注册,商品信息,用户信息)
1.3 web应用程序
- a.html、b.html…多个web资源,这些web资源可以被外界访问,对外界提供服务;
- web资源被放在同一个文件夹下,web应用程序---->Tomcat:服务器
- URL
- 一个web应用由多部分组成(静态web,动态web)
* HTML、CSS、JS
* JSP、Servlet
* Java程序
* Jar包
* 配置文件(Properties) - web应用程序编写完毕后,若想提供给外界访问:需要一个服务器来统一管理。
2. web服务器
2.1 技术原理
ASP:
- 微软:国内最早流行的就是ASP语言;
- 在HTML中嵌入了VB的脚本,ASP+COM;
- 在ASP开发中,基于一个页面都有几千行的业务代码,页面极其混乱,维护成本高;
- C#
<html>
<head>
</head>
<body>
<%
System.out.println("hello");
%>
</body>
</html>
PHP:
- PHP开发速度很快,功能很强大,跨平台、代码很简单
- 无法承载大访问量的情况(局限性)
JSP/Servlet:
- sun公司主推的BS架构(B/S:浏览器-服务器C/S:客户端-服务器)
- 基于Java语言的(所有的大公司,或者开源的组件,都是用Java写的)
- 可以继承三高(高并发,高可用,高性能)问题带来的影响
- 语法像ASP,ASP–>ISP,加强市场强度
2.2 web服务器
服务器是一种被动的操作,用来处理用户的一些请求和给用户的一些响应信息;
IIS: 微软开发的,是Windows中自带的服务器,采用ASP语言
Tomcat: 一个免费的开放源代码的Web 应用服务器,可利用它响应HTML(标准通用标记语言下的一个应用)页面的访问请求,是开发和调试JSP 程序的首选。
3. HTTP
什么是HTTP
- HTTP(超文本传输协议)是一个简单的请求-响应协议,通常运行在TCP之上。
- HTTPS:安全的security。
两个时代
- http1.0
- HTTP/1.0:浏览器与服务器只保持短暂的连接,每次请求都需要与服务器建立一个TCP连接
- http2.0
- HTTP/1.1:默认支持长连接,即在一个TCP连接上可以传送多个HTTP请求和响应,减少了建立和关闭连接的消耗和延迟,建立一次连接,多次请求均由这个连接完成
HTTP请求
- 客户端—发请求(Request)—服务器
百度(General:请求响应都会包含):
Request URL: https://www.baidu.com/ 请求地址
Request Method: GET get方法/post方法
Status Code: 200 OK 状态码:200
Remote Address: 39.156.66.18:443 远程地址(百度的地址+端口)
1.请求行
- 请求行中的请求方式:GET
- 请求方式:GET、Post 、HEAD、DELETE、PUT、TRACT…
- get:请求能携带的参数比较少,大小有限制,会在浏览器的URL地址栏显示数据内容,不安全,但高效。
- post:请求能携带的参数没有限制,大小不会限制,不会在浏览器的URL地址栏显示数据内容,安全,但不高效。
2.消息头
Accept: 告诉浏览器,它所支持的数据类型
Accept-Encoding: 支持哪种编码格式 GBK、UTF-8、GB2312
Accept-Language:告诉浏览器它的语言环境
Cache-C:ontrol:缓存控制
Connection:告诉浏览器,请求完成是断开还是保持连接
HTTP响应
- 服务器—响应—客户端
百度:
Cache-Control: private 缓存控制
Connection: keep-alive 连接保持
Content-Encoding: gzip 编码
Content-Type: text/html;charset=utf-8 类型
1.响应体
2.状态码:
200:响应成功
3xx:请求重定向(重定向:重新定位到新位置去
)
4xx:找不到资源
5xx:服务器代码错误
4. Tomcat
Tomcat 是Web应用服务器,是一个Servlet/JSP容器。
Tomcat 作为Servlet容器,负责处理客户请求,把请求传送给Servlet,并将Servlet的响应传送回给客户
4.1 安装Tomcat
https://tomcat.apache.org/download-80.cgi
4.2 启动Tomcat
startup.bat启动
shutdown.bat关闭
访问测试:http://localhost:8080/
4.3 配置Tomcat
Tomcat文件作用:
bin:存放启动、停止等批处理脚本和Shell脚本
conf:配置文件
servel.xml:服务器核心配置文件
启动端口号(默认8080):
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
主机名称(默认:localhost->127.0.0.1):
<Host name="localhost" appBase="webapps"
unpackWARs="true" autoDeploy="true">
lib:库目录,包含依赖的jar包
logs:日志文件
webapps:默认的Web应用部署目录
网站是如何进行访问的
1.输入一个域名,回车
2.检查本机的C:\Windows\System32\drivers\etc\hosts配置文件下有没有这个域名映射;
- 有:直接返回对应的ip地址,在这个地址中,有需要访问的web程序,可以直接访问
- 没有:去DNS服务器找,找到返回,找不到返回找不到;
3.4 发布一个web网站
将自己写的网站,放到服务器(Tomcat)中指定的web文件夹(webapps)下,就可以访问了
网站该有的结构:
-- webapps:Tomcat的web目录
-Root
-Jaystudy:网站目录名
-WEB-INF
-classes:Java程序
-lib:web应用依赖的jar包
-web.xml:网站配置文件
-index.html:默认首页
-css、js
- img
...
5. Maven
javaweb开发需要大量的jar包,需要手动导入
Maven:自动导入和配置jar包。
5.1 Maven项目架构管理工具
Maven核心思想:约定大于配置
- 有约束,不要去违反
Maven会规定好你如何去编写Java代码,必须要按照这个规范来。
5.2 Maven配置
由于这部分篇幅较大,另写一篇专搞配置:
Maven的安装与配置
在IDEA里配置Maven
6. Servlet
6.1 Servlet简介
- Servlet是实现了Servlet接口的Java程序,是由sun公司开发动态web的一门技术,是一个统一的web应用规范
- 快速入门:
- 创建web项目,导入Servlet依赖包
- 编写一个类、,实现Servlet接口,重写接口的方法
- 配置:在类上使用@WebServlet注解(或在web.xml里配置),配置该Servlet的访问路径
- 访问:启动Tomcat,浏览器输入URL
6.2 Servlet原理
①:servlet容器会创建一个封装了HTTP请求的ServletRequest实例传递给servlet的service方法
②:ServletResponse则表示一个Servlet响应,其隐藏了将响应发给浏览器的复杂性
③:通过ServletRequest的方法你可以获取一些请求相关的参数,而ServletResponse则可以将设置一些返回参数信息,并且设置返回内容。
1.首先浏览器通过ip:port连接服务器,这时浏览器将请求的数据按照HTTP协议的标准封装成了一个数据包并发送给了服务器(TCP三次握手)。
2.服务器(Tomcat)创建两个对象:请求对象和响应对象,服务器在解析请求数据包后会将请求的数据放到请求对象中去,方便我们在servlet中使用。(注意:Servlet不会解析请求,这一步交给容器来做的。)这里的请求和响应的对象实际上就是HttpServletRequest和HttpServletResponse接口所对应的实现类。
3.根据请求的资源路径找到相应的servlet配置,通过反射创建一个servlet的实例,并调用service()方法,并将之前创建好的请求和响应的对象作为参数传递给service方法。
4.在servlet中编写我们自己的业务逻辑,并通过response设置响应给浏览器的数据。(需要我们自己开发)
5.服务器从Response中获取到我们写的响应数据,把他们根据HTTP协议封装成一个数据包(响应的数据包)发送给浏览器,关闭连接(TCP四次挥手)
6.浏览器解析响应的数据包,取出数据,渲染页面。在整个的流程中我们只需要编写过程4中的servlet的业务逻辑,其他的都由Tomcat容器和浏览器封装。
Servlet执行流程
Servlet由web服务器创建,Servlet方法由web服务器调用。
Servlet生命周期
生命周期:一个对象从被创建到被销毁的整个过程。
Servlet运行在Servlet容器(web服务器,即Tomcat)中,其生命周期由容器来管理,分为四个阶段:
- 加载和实例化: 默认当Servlet第一次被访问时,由容器创建这个对象
- 初始化: 容器调用Servlet的
init()
方法初始化这个对象(加载配置文件、创建连接等)。该方法只调用一次 - 请求处理: 每次请求Servlet时,Servlet容器都会调用Servlet的
service()
方法对请求进行处理 - 服务终止: 当需要释放内存或容器关闭时,容器就会调用
destroy()
方法完成资源的释放,该实例随后会被Java的垃圾收集器所回收 getServletInfo()
:获取Service信息getServletConfig()
:获取ServletCOnfig对象
Servlet体系结构
将来开发B/S架构的web项目,都是针对HTTP协议,所以我们定义Servlet,会继承HttpServlet
,重写里面的方法:
HttpServlet中为什么要根据请求方式的不同,调用不同方法?
- 不同请求方式的,请求参数的位置不同,post的请求参数在请求体里,而get的请求参数在请求行里
如何调用?
需要根据请求方式的不同,进行分别的处理
- 获取请求方式(只有在HTTP协议下才能获取出,所以需要强转类型)
HttpServletRequest request = (HttpServletRequest) req;
String method = req.getMethod();
- 判断
if("GEt".equals(method)){
//get方式的处理逻辑
}else if("POST".equals(method)){
//post方式的处理逻辑
}
6.3 配置访问路径
注解配置方式
Servlet要想被访问,必须配置其访问路径(URLPattern
)
一个Servlet,可以配置多个URLPattern
@WebServlet(urlPatterns = {"/demo1","/demo2"})
urlPattern配置规则:
①精确匹配
- 配置路径:
@WebServlet("/user/select")
- 访问路径:localhost:8080/项目名/user/select
②目录匹配
- 配置路径:
@WebServlet("/user/*")
- 访问路径:localhost:8080/项目名/user/xxx
③扩展名匹配
- 配置路径:
@WebServlet("*.do")
- 访问路径:localhost:8080/项目名/user/xxx.do
④任意匹配
- 配置路径:
@WebServlet("/")
或者@WebServlet("/*")
- 访问路径:localhost:8080/项目名/user/xxx
- 项目配置了“/”,会覆盖掉Tomcat中的DefaultServlet,当其他url-Pattern都匹配不上时都会走这个servlet
配置了“/”意味着匹配任意访问路径
优先级:精确路径–>目录路径–>扩展名路径–>/*–>/
xml配置方式
Servlet从3.0后才支持注解方法,之前都是通过xml方式来配置访问路径
mapping映射:用于指定URL映射路径:<url-pattern>URL</url-pattern>
name和name对应,class指定项目中该Servlet路径,url-pattern指定浏览器访问路径
<servlet>
<servlet-name>helloServlet</servlet-name>
<servlet-class>cn.jay.servlet.HelloServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>helloServlet</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
可以映射多个路径:创建多个mapping标签嵌套多个<url-pattern>
路径
通配符:* 可以指定通用映射路径
优先级:固有的映射路径优先级最高,如果找不到就会走默认的处理请求;
6.4 Request:获取请求数据
Request继承体系
- Tomcat需要解析请求数据,封装为request对象,并且创建request对象传递到service方法中
- 使用request对象,查阅JavaEE API文档的HttpServletRequest接口
Request获取请求数据
- 请求行
GET /request-demo/req1?username=jay&password=123 HTTP/1.1
String getMethod();//获取请求方式
String getContextPath();//获取虚拟目录(项目访问路径):/request-demo
StringBuffer getRequestURL();//获取URL(统一资源定位符):http://localhost:8080/request-demo/req1
String getRequestURI();//获取URI(统一资源标识符):/request-demo/req1
String getQueryString();//获取请求参数(get方式):username=jay&password=123
- 请求头
user-agent: Mozilla/5.0 Chrome/101.0.495
String getHeader(String name);//根据请求头名称,获取值(例如user-agent获取浏览器版本信息)
- 请求体
username=jay&password=123
(post方式)
ServletInputStream getInputStream();//获取字节输入流
BufferedReader getReader();//获取字符输入流
获取post 请求体:请求参数
//1.获取字符输入流
BufferedReader br = req.getReader();
//2.读取数据
String l = br.readLine();
System.out.println(l);
由上可知请求参数获取方式有
- GET方式:
String getQueryString()
- POST方式:
BufferredReader getReader()
通用方式获取请求参数:
Map<String, String[]> getParameterMap();//获取所以参数map集合
String[] getParameterValues(String name);//根据名称获取参数值
String getParameter(String name);//根据名称获取单个参数
中文乱码问题
post方式:设置输入流的编码req.setCharacterEncoding("utf-8");
get方式:
- URL编码
String s = URLEncoder.encode("utf-8");
System.out.println(s);
- URL解码
中文应该:String encode = URLEncoder.encode("utf-8");
而tomcat:String encode = URLEncoder.encode("ISO-8859-1");
所以出现报错,就是因为编码格式不匹配
- 把ISO-8859-1格式的字符串转换为字节数据
byte[] bytes = decode.getBytes("ISO-8859-1");
可以通过for打印每个字节:
for (byte b : bytes){
System.out.println(b+" ");
}
- 将字节数组转换为字符串
String s = new String(bytes, "utf-8");
通用方式解决乱码问题:
username = new String(username.getBytes(standCharsets.ISO_8859_1), StandardCharsets.UTF_8);
Request请求转发
请求转发(forward):一种在服务器内部的资源跳转方式
实现方式:
req.getRequestDispatcher("资源B路径").forward(req,resp);
请求转发资源间共享数据:使用Request对象
void setAttribute(String name,Object o);//存储对象到request域中
Object getAttribute(String name);//根据key获取值
void removeAttribute(String name);//根据key删除该键值对
请求转发特点:
- 浏览器地址栏路径不发生变化
- 只能转发到当前服务器内部资源
- 一次请求,可以在转发的资源间使用request共享数据
6.5 Response:获取响应数据
Response继承体系
Response设置响应数据
响应数据分为三部分:
- 响应行:HTTP/1.1 200 OK
void setStatus(int sc):设置响应状态码 - 响应头:Content-Type:text/html
void setHeader(String name,String value):设置响应头键值对 - 响应体:
PtintWriter getWriter():获取字符输出流
ServletOutputStream():获取字节输出流
Response完成重定向
-
重定向(Redirect):一种资源跳转方式 ,把资源跳转到另一个页面
-
状态码:302
-
要跳转到的位置:响应头Location:xxx
-
设置响应状态码302
response.setStatus(302);
-
设置响应头Location
response.setHeader(“Location”,“/request-demo/resp2”);
简化方式完成重定向:
response.sendRedirect(“Location”,"/request-demo/resp2");
重定向的特点:
- 浏览器地址栏路径发生变化
- 可以重定向到任意位置的资源(服务器内部,外部均可)
- 两次请求,不能在多个资源使用request共享数据
路径问题:
- 明确路径谁使用?
浏览器使用:需要加虚拟目录(项目访问路径),例如
<a href="路径">
等从浏览器发出请求的
服务端使用:不需要加虚拟目录,例如req.getRequestDispatcher(“路径”)
等从服务器发出请求的
Response响应字符数据
Response响应字节数据
7.JSP
JSP(JavaServer Pages,Java服务页面)
由于JSP技术几乎过时,因此另开一篇博文简单介绍。