1. web
1.1 web相关概念
软件架构
-
C /S:客户端/服务器端
- 需要安装客户端应用
-
B/S:浏览器/服务器端
- 不需要安装客户端应用,对于用户来说只需要记住域名访问就可以,高效,客户端零维护
资源分类
-
静态资源:所有用户访问后,得到的结果都是一样的,称为静态资源.静态资源可以直接被浏览器解析
- 如: html、css,、JavaScript
-
动态资源:每个用户访问相同资源后,得到的结果可能不一样。称为动态资源。动态资源被访问后,需要先转换为静态资源,在返回给浏览器,(浏览器内部含有静态资源解析引擎)
- 如:servlet/jsp、php、asp....
1.2 web服务器软件
相关概念
-
服务器:安装了服务器软件的计算机 ,比如之前电脑安装了mysql软件,那么你的电脑就是一台mysql服务器,
根据ip地址就可以让其它主机访问到你的mysql服务器,并访问到相应的数据。
-
服务器软件:接收用户的请求,处理请求,做出响应
-
web服务器软件:接收用户的请求,处理请求,做出响应。
-
在web服务器软件中,可以部署web项目,让用户通过浏览器来访问这些项目,也称之为web容器
-
-
常见的java相关的web服务器软件:
webLogic:oracle公司,大型的JavaEE服务器,支持所有的JavaEE规范,收费的。
webSphere:IBM公司,大型的JavaEE服务器,支持所有的JavaEE规范,收费的。
JBOSS:JBOSS公司的,大型的JavaEE服务器,支持所有的JavaEE规范,收费的。
Tomcat:Apache基金组织,中小型JavaEE服务器,仅支持少量的JavaEE规范servlet/jsp。开源,免费。
JavaEE:Java语言在企业级开发中使用的技术规范的总和,一共规定了13项大的规范
Tomcat:web服务器软件
-
安装:解压压缩包即可,注意:安装目录建议不要有中文和空格
-
启动:运行startup.bat/startup.sh
-
停止:运行shutdown.bat/shutdown.sh
1.3 Tomcat集成IDEA
概述:
将Tomcat集成到IDEA中,并且创建JavaEE的项目,部署项目。
1.4 Servlet
概念:
-
server applet ,运行在服务器端的小程序
-
Servlet就是一个接口,定义了Java类被浏览器访问到(tomcat识别)的规则。
-
将来我们自定义一个类,实现Servlet接口,复写方法。
1.5 快速入门:
-
创建JavaEE项目
-
导入依赖
XML<dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>4.0.1</version> </dependency>
-
定义一个类,实现Servlet接口
javapublic class ServletDemo1 extends HttpServlet
-
实现抽象类中的抽象方法
javapublic class ServletDemo1 extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("前端发送了一个get请求"); } }
-
在web.xml中配置:
XML<web-app> <display-name>Archetype Created Web Application</display-name> <servlet> <servlet-name>servlet</servlet-name> <servlet-class>com.codingfuture.ServletDemo1</servlet-class> </servlet> <servlet-mapping> <servlet-name>servlet</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> </web-app>
6.访问方式
XML
http://localhost:8080/Test_war_exploded/ServletDemo1
1.6 Servlet3.0
- 好处:
支持注解配置。可以不需要配置web.xml了
- 步骤:
-
创建JavaEE项目
-
定义一个类,实现Servlet接口
-
重写方法
-
在类上使用@WebServlet注解,进行配置
代码示例:
java
@WebServlet(urlPatterns = "/demo1")
@WebServlet(value = "/demo2")
@WebServlet(name = "/demo3")
@WebServlet("/demo4")
java
http://localhost:8080/Http_Demo_war_exploded/servletDemo1
http://localhost:8080
/Http_Demo_war_exploded -- 虚拟路径 实际开发中我们会将虚拟路径配置成/
/servletDemo1 -- 资源路径 -- 资源路径是工作类的首字母小写
修改之后的路径是:
http://localhost:8080/servletDemo1
1.7 前端发送请求
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="/servletDemo1" method="post">
<p>账户:
<input name="username" type="text">
</p>
<p>
密码: <input name="password" type="password">
</p>
<input type="submit" value="提交">
</form>
</body>
</html>
java
@WebServlet("/servletDemo1")
public class ServletDemo1 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("前端发送了一个get请求");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("前端发送了一个post请求");
}
}
1.8 Servlet相关配置
-
urlpartten:Servlet访问路径
-
一个Servlet可以定义多个访问路径 : @WebServlet({"/d4","/dd4","/ddd4"})
-
路径定义规则:
-
/xxx:路径匹配
-
/xxx/xxx:多层路径,目录结构
-
*.do: 扩展名匹配
-
-
代码示例:
java
@WebServlet({"/d2", "/dd2", "/ddd2"})//都可以访问到
@WebServlet("/demo2/user") //多层路径
@WebServlet("/demo2/*") //通配符, *任意字符
@WebServlet("*.do") // 任意字符.do 访问
2.0 Http
2.1 TCP与UDP
-
网络分层模型
-
IP IPv4 与IPv6
-
TCP (基于连接) 打电话 电话接通 互相通话 结束挂断
-
如何实现连接: 三次握手 传输确认 四次挥手
-
优点:传输稳定性强,适用于对网络通讯要求较高的场景 比如传输文件,发送邮件,浏览网页等等
-
-
UDP (基于非连接) 写信 对方是否收到,内容是否完整,顺序是否正确
- 优点: 速度快,但是可能产生丢包,适用于对实时性要求比较高,对少量丢包没有太大要求,如语音通话,视频直播等
-
无状态
-
会话技术
-
Cookie
-
Session
-
-
2.2 Http超文本传输协议
Hyper Text Transfer Protocol (http)超文本传输协议 ,定义了,客户端和服务器端通信时,发送数据的格式
特点
-
基于TCP/IP的高级协议,安全
-
默认端口号:80
-
基于请求/响应模型的:一次请求对应一次响应
-
无状态的:每次请求之间相互独立,不能交互数据
2.3 HTTPS
-
HTTPS是HTTP协议的安全版本,HTTP协议的数据传输是明文的,是不安全的,HTTPS使用了 SSL/TLS 非对称加密协议进行了加密处理。
-
HTTP和HTTPS使用连接方式不同,默认端口也不一样,HTTP是80,HTTPS是443。
-
对称加密与非对称加密(CA)
2.4 请求
请求行
请求方式 请求url 请求协议/版本 GET /login.html HTTP/1.1
请求方式:
HTTP协议有多种请求方式,常用的有2种
-
GET:
-
请求参数在请求行中,在url后。
-
请求的url长度有限制的
-
不太安全
-
-
POST:
-
请求参数在请求体中
-
请求的url长度没有限制的
-
相对安全
-
请求头
请求头:客户端浏览器告诉服务器一些信息 请求头名称: 请求头值 一种键值对形式
-
常见的请求头:
-
User-Agent:浏览器告诉服务器,我访问你使用的浏览器版本信息
- 可以在服务器端获取该头的信息,解决浏览器的兼容性问题
-
-
Referer:http://localhost/login.html
- 告诉服务器,我(当前请求)从哪里来
-
演示
java
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("前端发送了一个post请求");
String header = req.getHeader("User-Agent");
if (header.contains("Chrome")) {
System.out.println("用户当前使用的是谷歌浏览器");
}
}
请求空行
空行,就是用于分割POST请求的请求头,和请求体的。
请求体(正文):
-
封装POST请求消息的请求参数的
java
username: zs
password: 123
**注意:**username=123 请求体 ,只有post请求才可以查看到,get请求是没有的,get请求参数是在url中。
请求消息数据格式:
bash
字符串格式:
POST /login.html HTTP/1.1
Host: localhost
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:60.0) Gecko/20100101 Firefox/60.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Referer: http://localhost/login.html
Connection: keep-alive
Upgrade-Insecure-Requests:1
username: zs
password: 123
2.5 Request
体系结构
request对象继承体系结构:
java
ServletRequest -- 父接口
⬆️
HttpServletRequest -- 子接口
request功能
1.获取请求行数据
GET /day02/demo1?name=zhangsan HTTP/1.1
java
1.获取请求方式 :GET
* String getMethod()
2.获取虚拟目录:/day02
* String getContextPath()
3.获取Servlet资源路径: /demo1
* String getServletPath()
4.获取get方式请求参数:name=zhangsan
* String getQueryString()
5.获取请求URI:/day02/demo1
* String getRequestURI(): /day02/demo1
* StringBuffer getRequestURL() :http://localhost/day02/demo1
* URI:统一资源标识符 : demo01/loginServlet 范围大 共和国
* URL: 统一资源定位符 : http://localhost/demo01/loginServlet 中华人民共和国
6.获取协议及版本:HTTP/1.1
* String getProtocol()
代码示例:
java
System.out.println(req.getMethod());//1.获取请求方式 :GET/POST
System.out.println(req.getContextPath());//2.获取虚拟目录:
System.out.println(req.getServletPath());//3.获取Servlet资源路径: /demo3
System.out.println(req.getQueryString());//4.获取get方式请求参数:username=zs
System.out.println(req.getRequestURI());//5.URI:统一资源标识符 :/虚拟目录/demo3
System.out.println(req.getRequestURL());//6.URL:统一资源定位符http://localhost:8080/demo3
System.out.println(req.getProtocol());//7.获取协议及版本:HTTP/1.1HTTP/1.1
2.获取请求头数据
-
方法:
-
String getHeader(String name):通过请求头的名称获取请求头的值
-
Enumeration< String > getHeaderNames():获取所有的请求头名称
-
代码示例:
java
//1.获取所有请求头的值
Enumeration<String> headernames = request.getHeaderNames();
//2.遍历
while (headernames.hasMoreElements()) {
String name = headernames.nextElement();
//3.根据名称获取头的值
String value = request.getHeader(name);
System.out.println(name + "-----" + value);
}
getHeader 介绍,判断客户端是哪个浏览器
java
//获取请求头数据 user - agent
String agent = req.getHeader("user-agent");//不区分大小写
//判断浏览器版本
if (agent.contains("Chrome")) {
//处理兼容性问题
System.out.println("谷歌浏览器");
} else if (agent.contains("Firefox")) {
System.out.println("火狐浏览器");
}
3.获取请求参数:
演示:
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="/servletDemo2" method="post">
<p>账户:
<input name="username" type="text">
</p>
<p>
密码: <input name="password" type="password">
</p>
<p>
<input type="checkbox" name="hobby" value="coding"> coding
<input type="checkbox" name="hobby" value="football"> football
<input type="checkbox" name="hobby" value="basketball"> basketball
</p>
<input type="submit" value="注册">
</form>
</body>
</html>
-
获取请求参数通用方式:不论get还是post请求方式都可以使用下列方法来获取请求参数
-
String getParameter(String name):根据参数名称获取参数值 username=zs&password=123
-
String[] getParameterValues(String name):根据参数名称获取参数值的数组 hobby=study&hobby=game
-
中文乱码问题:
-
get方式:tomcat8 已经将get方式乱码问题解决了
-
post方式:会乱码
解决:在获取参数前,设置request的编码request.setCharacterEncoding("utf-8");
-
-
java
/**
* 获取请求参数通用方式
*/
@WebServlet("/servletDemo2")
public class ServletDemo2 extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//解决post乱码问题 get请求中英文都可以
//req.setCharacterEncoding("utf-8");
System.out.println("前端发送了一个post请求");
//1.根据参数名称获取参数值
String username = req.getParameter("username");
String password = req.getParameter("password");
System.out.println(username);
System.out.println(password);
//2.根据参数名称获取参数值的数组 //String[] getParameterValues(String name)
String[] hobbys = req.getParameterValues("hobby");
for (String hobby : hobbys) {
System.out.println(hobby);
}
}
}
4.请求转发(考点)
请求转发:一种在服务器内部的资源跳转方式
-
步骤:
-
通过request对象获取请求转发器对象:
RequestDispatcher getRequestDispatcher(String path)
-
使用RequestDispatcher对象来进行转发:
forward(ServletRequest request, ServletResponse response)
-
-
特点:
-
浏览器地址栏路径不发生变化
-
只能转发到当前服务器内部资源中。
-
转发是一次请求
-
5. 共享数据
-
域对象:一个有作用范围的对象,可以在范围内共享数据
-
request域:代表一次请求的范围,一般用于请求转发的多个资源中共享数据
-
方法:
-
void setAttribute(String name,Object obj):存储数据
-
Object getAttitude(String name):通过键获取值
-
void removeAttribute(String name):通过键移除键值对
-
代码示例:
java
/**
* 请求转发:一种在服务器内部的资源跳转方式
* 服务器内部资源跳转
* 从一个Servlet跳转到另一个Servlet中
* 这里是servletDemo1 跳转到servletDemo2中
*/
@WebServlet("/servletDemo1")
public class ServletDemo1 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String usernameValue = req.getParameter("username");
// request 域
req.setAttribute("username", usernameValue);
// 请求转发
RequestDispatcher requestDispatcher = req.getRequestDispatcher("/servletDemo2");
// RequestDispatcher requestDispatcher = req.getRequestDispatcher("/http://www.baidu.com");
requestDispatcher.forward(req, resp);
}
}
@WebServlet("/servletDemo2")
public class ServletDemo2 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Object usernameValue = req.getAttribute("username");
System.out.println(usernameValue);
}
}
-
session域(多次请求,会话期间)
java@WebServlet("/servletDemo1") public class ServletDemo1 extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String usernameValue = req.getParameter("username"); // session 域 HttpSession session = req.getSession(); session.setAttribute("username", usernameValue); try { Thread.sleep(5000); // 除此此外,浏览器主动关闭,session域中的数据也会销毁 session.removeAttribute("username"); } catch (InterruptedException e) { e.printStackTrace(); } } } @WebServlet("/servletDemo2") public class ServletDemo2 extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { HttpSession session = req.getSession(); Object username = session.getAttribute("username"); System.out.println(username); } }
获取ServletContext(Application域)
Servlet三大域对象: request、session、ServletContext。
ServletContext就是三大域对象之一。
-
ServletContext是一个全局的储存信息的空间,在服务器启动时创建,在服务器关闭时销毁,
-
一个JavaWeb应用只创建一个ServletContext对象,
-
作用范围:所有的用户都可以取得此信息,此信息在整个服务器上被保留。
-
属性范围值:只要设置一次,则所有的网页窗口都可以取得数据。
-
方法:
javaServletContext servletContext = req.getServletContext(); ServletContext servletContext = this.getServletContext(); servletContext.setAttribute("username","zhangsan");
-
-
request,一个用户可有多个。
-
reques:表示一个请求,只要发出一个请求就会创建一个request,它的作用域:仅在当前请求中有效。
-
用处:常用于服务器间同一请求不同页面之间的参数传递
-
方法:request.setAttribute();
-
-
session,一个用户一个。
-
会话:用户打开浏览器会话开始,直到关闭浏览器会话才会结束。一次会话期间只会创建一个session对象。
-
用处:常用于web开发中的登陆验证界面(当用户登录成功后浏览器分配其一个session键值对)。
-
方法:session.setAttribute();
-
三大域对象在使用上一样,只是三者作用域范围大小不一样。从小到到范围依次是:request < session < ServletContext
代码示例:
java
@WebServlet("/servletDemo1")
public class ServletDemo1 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String usernameValue = req.getParameter("username");
//ServletContext
ServletContext servletContext = req.getServletContext();
servletContext.setAttribute("username", usernameValue);
}
}
java
@WebServlet("/servletDemo2")
public class ServletDemo2 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext servletContext = this.getServletContext();
Object username = servletContext.getAttribute("username");
System.out.println(username);
}
}
2.6 Response
响应消息
-
请求消息:客户端发送给服务器端的数据
-
数据格式:
-
请求行
-
请求头
-
请求空行
-
请求体
-
-
-
响应消息:服务器端发送给客户端的数据
-
数据格式:
-
响应行
-
响应头
-
响应空行
-
响应体
-
-
响应行
-
组成:协议/版本 响应状态码 状态码描述
HTTP/1.1 200 OK
-
响应状态码:服务器告诉客户端浏览器本次请求和响应的一个状态。
-
状态码都是3位数字
-
分类:
1xx:试探性请求,服务器接收客户端消息,没接受完成,等待一段时间后,发送1xx状态码
100: 请求者应当继续提出请求。 服务器返回此代码表示已收到请求的第一部分,正在等待其余部分
2xx:成功。代表:200 服务器已经成功处理了请求
3xx:重定向。代表:302(重定向),304(访问缓存)
4xx:客户端错误。
代表:
404(请求路径没有对应的资源)
405:比如请求方式 没有对应的doXxx方法
5xx:服务器端错误。代表:500(服务器内部出现异常) ,比如运算错误
-
-
-
响应头:
-
格式:
java头名称 : 值
-
常见的响应头:
java/* Content-Type:服务器告诉客户端本次响应体数据格式以及编码格式 /* text/html;charset=utf-8
-
-
响应空行
-
响应体
传输给前端的数据
响应字符串格式
-
java
HTTP/1.1 200 OK
Content-Type: text/html;charset=UTF-8
Content-Length: 101 字节个数
Date: Thu, 17 Sep 2020 02:59:05 GMT
Location: /servletB
我是response
java
@WebServlet("/servletDemo3")
public class ServletDemo3 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
try {
// resp.setCharacterEncoding("utf-8");
// Content-Type:服务器告诉客户端本次响应体数据格式以及编码格式
// text/html;charset=utf-8
resp.setContentType("text/html;charset=utf-8");
int i = 5 / 0;
} catch (ArithmeticException e) {
System.out.println(e.getMessage());
resp.getWriter().println("<h1>服务器正在维护。。。see you later</h1>");
}
}
}
2.7 重定向
-
重定向:资源跳转的方式
代码实现:
-
设置状态码为302
response.setStatus(302);
-
设置响应头location
response.setHeader("location","/responseServlet02");
-
简单的重定向方法
response.sendRedirect("/responseServlet02");
代码示例:
-
java
/**
* @author Petrel
*/
@WebServlet("/responseServlet01")
public class ResponseServlet01 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("访问了responseServlet01");
// 访问 /responseServlet01 会跳转到 /responseServlet02资源
// 方法一
// 1.设置状态码为302
// resp.setStatus(302);
// 2.置响应头location
// resp.setHeader("location", "/responseServlet02");
// 方法二
// 3.简单的重定向方法
// resp.sendRedirect("/responseServlet02");
// resp.sendRedirect("http://www.baidu.com");
}
}
@WebServlet("/responseServlet02")
public class ResponseServlet02 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("访问了responseServlet02");
}
}
forward 和 redirect 区别
-
重定向的特点:redirect
-
地址栏发生变化
-
重定向可以访问其它站点(服务器)的资源
-
重定向是两次请求。不能使用request对象来共享数据
-
-
转发的特点:forward
-
转发地址栏路径不变
-
转发只能访问当前服务器下的资源
-
转发是一次请求,可以使用request对象来共享数据
-
-
注意:
不能使用重定向来访问request域中的数据