1. HTTP协议
在网络上传输html时的协议,用于B-C的通信
http1.0:一次只能获得一个Web资源,获取后就断开链接
http1.1:持久连接,可以获得多个web资源
浏览器请求过程:
-
与服务器建立TCP连接(80端口)
-
发送HTTP请求
-
收取HTTP响应,然后把网页在浏览器中显示出来
https:443端口
浏览器发送的HTTP:
GET / HTTP/1.1 Host: www.sina.com.cn User-Agent: Mozilla/5.0 xxx Accept: */* Accept-Language: zh-CN,zh;q=0.9,en-US;q=0.8
其中,第一行表示使用GET请求获取路径为/的资源,并使用HTTP/1.1协议,从第二行开始,每行都是以Header: Value形式表示的HTTP头,比较常用的HTTP Header包括:
-
Host: 表示请求的主机名,因为一个服务器上可能运行着多个网站,因此,Host表示浏览器正在请求的域名;
-
User-Agent: 标识客户端本身,例如Chrome浏览器的标识类似
Mozilla/5.0 ... Chrome/79,IE浏览器的标识类似Mozilla/5.0 (Windows NT ...) like Gecko; -
Accept:表示浏览器能接收的资源类型,如
text/*,image/*或者*/*表示所有; -
Accept-Language:表示浏览器偏好的语言,服务器可以据此返回不同语言的网页;
-
Accept-Encoding:表示浏览器可以支持的压缩类型,例如
gzip, deflate, br。
Get方法:能够携带参数少,不安全(URL中会携带参数),但是高效
Post方法:携带的参数无限制,安全但不高效
服务器的响应:
HTTP/1.1 200 OK Content-Type: text/html Content-Length: 21932 Content-Encoding: gzip Cache-Control: max-age=300 <html>...网页数据...
服务器响应的第一行总是版本号+空格+数字+空格+文本,数字表示响应代码,其中2xx表示成功,3xx表示重定向,4xx表示客户端引发的错误,5xx表示服务器端引发的错误。数字是给程序识别,文本则是给开发者调试使用的。常见的响应代码有:
-
200 OK:表示成功;
-
301 Moved Permanently:表示该URL已经永久重定向;
-
302 Found:表示该URL需要临时重定向;
-
304 Not Modified:表示该资源没有修改,客户端可以使用本地缓存的版本;
-
400 Bad Request:表示客户端发送了一个错误的请求,例如参数无效;
-
401 Unauthorized:表示客户端因为身份未验证而不允许访问该URL;
-
403 Forbidden:表示服务器因为权限问题拒绝了客户端的请求;
-
404 Not Found:表示客户端请求了一个不存在的资源;
-
500 Internal Server Error:表示服务器处理时内部出错,例如因为无法连接数据库;
-
503 Service Unavailable:表示服务器此刻暂时无法处理请求。
从第二行开始,服务器每一行均返回一个HTTP头。服务器经常返回的HTTP Header包括:
-
Content-Type:表示该响应内容的类型,例如
text/html,image/jpeg; -
Content-Length:表示该响应内容的长度(字节数);
-
Content-Encoding:表示该响应压缩算法,例如
gzip; -
Cache-Control:指示客户端应如何缓存,例如
max-age=300表示可以最多缓存300秒。
HTTP请求和响应都由HTTP Header和HTTP Body构成,其中HTTP Header每行都以\r\n结束。如果遇到两个连续的\r\n,那么后面就是HTTP Body。浏览器读取HTTP Body,并根据Header信息中指示的Content-Type、Content-Encoding等解压后显示网页、图像或其他内容。
通常浏览器获取的第一个资源是HTML网页,在网页中,如果嵌入了JavaScript、CSS、图片、视频等其他资源,浏览器会根据资源的URL再次向服务器请求对应的资源。
使用TCP多线程编程服务器框架
package com.wang.web;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
public class Server {
public static void main(String[] args) throws IOException {
//监听指定接口
ServerSocket ss = new ServerSocket(8080);
System.out.println("server is running...");
for (; ; ) {
Socket socket = ss.accept();
System.out.println("connnection from" + socket.getRemoteSocketAddress());
Thread thread = new Handler(socket);
thread.start();
}
}
}
class Handler extends Thread{
Socket socket;
public Handler(Socket socket){
this.socket = socket;
}
public void run(){
try(InputStream inputStream = this.socket.getInputStream()){
try(OutputStream outputStream = this.socket.getOutputStream()){
handle(inputStream,outputStream);
}
}catch (Exception e){
try{
this.socket.close();
}catch (IOException ioe){
}
System.out.println("client disconnected");
}
}
private void handle(InputStream inputStream,OutputStream outputStream)throws IOException{
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(outputStream,StandardCharsets.UTF_8));
//处理HTTP请求
}
}
HTTP目前有多个版本,1.0是早期版本,浏览器每次建立TCP连接后,只发送一个HTTP请求并接收一个HTTP响应,然后就关闭TCP连接。由于创建TCP连接本身就需要消耗一定的时间,因此,HTTP 1.1允许浏览器和服务器在同一个TCP连接上反复发送、接收多个HTTP请求和响应,这样就大大提高了传输效率。
我们注意到HTTP协议是一个请求-响应协议,它总是发送一个请求,然后接收一个响应。能不能一次性发送多个请求,然后再接收多个响应呢?HTTP 2.0可以支持浏览器同时发出多个请求,但每个请求需要唯一标识,服务器可以不按请求的顺序返回多个响应,由浏览器自己把收到的响应和请求对应起来。可见,HTTP 2.0进一步提高了传输效率,因为浏览器发出一个请求后,不必等待响应,就可以继续发下一个请求。
HTTP 3.0为了进一步提高速度,将抛弃TCP协议,改为使用无需创建连接的UDP协议,目前HTTP 3.0仍然处于实验阶段。
2. Tomcat服务器
开启服务器后才可以访问webapp中的项目
3. Servlet
开发动态web的一门技术
-
编写一个类实现Servlet接口
-
把开发好的Java类部署到web服务器中
把实现了Servlet接口的java程序叫做Servlet
用户携带的参数不同,显示的界面也不同
3.1 HelloServlet
-
继承HttpServlet类
-
实现Post和Get方法(其他方法暂时不用)

编写实现类
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
public class TestServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
PrintWriter writer = resp.getWriter();
writer.print("Hello,Servlet");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
}
}
-
编写Servlet的映射
-
Java程序要通过浏览器访问,而浏览器需要访问服务器
-
所以,要在web服务中注册我们所写的Servlet,还要交
-
给他一个浏览器能够访问的路径
-
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="https://jakarta.ee/xml/ns/jakartaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd" version="5.0"> <!--注册Servlet--> <servlet> <servlet-name>hello</servlet-name> <servlet-class>com.wang.ServletTest.TestServlet</servlet-class> </servlet> <!--servlet映射的地址--> <servlet-mapping> <servlet-name>hello</servlet-name> <url-pattern>/hello</url-pattern> </servlet-mapping> </web-app>
-
配置Tomcat

配置项目路径
-
启动测试
3.2 执行流程


Servlet对象由tomcat服务器创建,并且service方法由tomcat调用
3.3 生命周期

-
加载和实例化
-
初始化
-
一个Servlet只会创建一次
-
package com.wang.servletTest;
import javax.servlet.*;
import javax.servlet.annotation.WebServlet;
import java.io.IOException;
@WebServlet(urlPatterns = "/demo2",loadOnStartup = 1)
public class ServletDemo2 implements Servlet {
//初始化方法
//调用时机:默认情况下Servlet被第一次访问时调用
//调用次数:1
@Override
public void init(ServletConfig servletConfig) throws ServletException {
System.out.println("Init....................");
}
//开始服务
//调用时机:每一次servlet被访问时
//调用次数:n
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println("service-...........................");
}
//结束服务-销毁
//调用时机:服务器关闭或内存释放
//调用次数:1
@Override
public void destroy() {
System.out.println("destory.......................");
}
@Override
public ServletConfig getServletConfig() {
return null;
}
@Override
public String getServletInfo() {
return null;
}
}
3.4 Servlet方法
package com.wang.servletTest;
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(urlPatterns = "/demo3")
public class ServletDemo3 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.........");
}
}
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <form action="/tomcat_demo2_war/demo3" method="post"> <input name="username"><input type="submit"> </form> 点击提交之后,就会调用demo3中的Servlet,且是dopost的方法 </body> </html>
针对不同的提交方式,Servlet中的service方法都需要编写一下代码
//根据请求方式的不同get/post 需要进行不同的解析服务方式
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
//根据方式不同,进行分别处理
//1.获取请求方式-------servletRequest对象可以提供请求方式
HttpServletRequest request = (HttpServletRequest) servletRequest;
String method = request.getMethod();
//2.根据不同的请求方式编写不同的逻辑代码
if ("GET".equals(method)){
//get的处理逻辑
}else if("POST".equals(method)){
//post的处理逻辑
}
}
3.5 urlPattern
-
Servlet要想被访问,必须配置其访问路径(urlPattern)
-
一个Servlet,可以配置多个urlPattern
-
@WebServlet(urlPatterns = {"/demo1","/demo2"})
-
-
urlPattern配置规则
-
精确匹配
-
目录匹配
-
扩展名匹配
-
任意匹配
-
-
-
当一个路径满足多种匹配规则时,越精确的被调用
-
DefaultServlet是Tomcat用于处理静态资源的servlet,如果被覆盖掉那么将无法调用静态资源(比如 html)
3.6 XML编写
不使用注解,使用XML配置的方式
<!--Servlet全类名-->
<servlet>
<servlet-name>demo4</servlet-name>
<servlet-class>com.wang.servletTest.ServletDemo4</servlet-class>
</servlet>
<!--Servlet路径映射-->
<servlet-mapping>
<servlet-name>demo4</servlet-name>
<url-pattern>/demo4</url-pattern>
</servlet-mapping>
4. Request 和 Response
-
Request 获取请求数据
-
Response 设置响应的数据
package com.wang.servletTest;
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("/demo5")
public class ServletDemo5 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//使用request对象获得请求数据
String name = req.getParameter("name");
//使用response对象设置响应数据
resp.setHeader("content-type","text/html;charset=utf-8");
resp.getWriter().write("h1"+name+"欢迎!</h1>");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//使用request对象获得请求数据
String name = req.getParameter("name");
//使用response对象设置响应数据
resp.setHeader("content-type","text/html;charset=utf-8");
resp.getWriter().write("<h1>"+name+"欢迎!</h1>");
}
}
4.1 Request对象
4.1.1继承体系

-
ServletRequest 是一个接口
-
HttpServletRequest 是对Http协议封装的request接口
-
Tomcat提供了实现类(Tomcat需要解析这些数据,所以需要提供实现类)
4.1.2 获取请求数据
请求数据分为三部分:
-
请求行
-
请求头
-
请求体

同一种方式获取不同请求的参数:
Request对象采取的方式:
-
建立一个Map
-
泛型为<String,String[]>
-
编写三个通用的调用参数的方法

4.1.3 请求转发
-
一种在服务器内部的资源跳转方式(forward)

4.2 Response对象
响应数据分为三部分:
-
响应行
-
响应头
-
响应体

4.2.1重定向
-
一种资源跳转方式
-
重定向是浏览器接收到302后自动的请求新地址的行为

-
@Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("resp1..................."); /*重定向 //1.设置响应状态码 resp.setStatus(302); //2.设置响应头 resp.setHeader("Location","/tomcat_demo2/resp2");*/ //简化方法 resp.sendRedirect("/tomcat_demo2/resp2"); }
-
重定向与请求转发的区别

4.2.2 响应体数据设置
响应字符数据:
-
通过Response对象获取字符输出流
PrintWriter writer = reps.getWriter();
-
写数据
writer.write("aaa")
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//设置支持utf-8
resp.setContentType("text/html;charset=utf-8");
//扫描并写入数据
PrintWriter writer = resp.getWriter();
writer.write("呵呵呵哒好玩的");
}
该流不需要关闭,response对象会被服务器销毁
响应字节数据(除字符外的文件类型):

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1.读取文件
FileInputStream stream = new FileInputStream("f://Anson Seabra - Keep You Head Up Princess.mp3");
//2.获取字节输出流
ServletOutputStream os = resp.getOutputStream();
/*3.完成流的复制 笨办法
byte[] buff = new byte[1024];
int len = 0;
while ((len=stream.read(buff))!=-1){
os.write(buff,0,len);
}*/
IOUtils.copy(stream,os);
stream.close();
}
5. 登录案例
5.1 用户注册
-
用户注册,发送给RegisterServlet
-
在RegisterServlet中使用MyBatis保存数据
-
保存前需要查重(查询用户名)
package com.itheima.web;
import com.itheima.mapper.UserMapper;
import com.itheima.pojo.User;
import com.itheima.util.SqlSessionFactoryUtils;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
import java.io.InputStream;
@WebServlet("/registerServlet")
public class RegisterServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1. 接收用户数据
String username = request.getParameter("username");
String password = request.getParameter("password");
//封装用户对象
User user = new User();
user.setUsername(username);
user.setPassword(password);
//2. 调用mapper 根据用户名查询用户对象
//2.1 获取SqlSessionFactory对象
/* String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);*/
SqlSessionFactory sqlSessionFactory = SqlSessionFactoryUtils.getSqlSessionFactory();
//2.2 获取SqlSession对象
SqlSession sqlSession = sqlSessionFactory.openSession();
//2.3 获取Mapper
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
//2.4 调用方法
User u = userMapper.selectByUsername(username);
//3. 判断用户对象释放为null
if( u == null){
// 用户名不存在,添加用户
userMapper.add(user);
// 提交事务
sqlSession.commit();
// 释放资源
sqlSession.close();
}else {
// 用户名存在,给出提示信息
response.setContentType("text/html;charset=utf-8");
response.getWriter().write("用户名已存在");
}
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doGet(request, response);
}
}
5.2 用户登录
-
用户登录,填写账号密码提交到LoginServlet
-
在LoginServlet使用MyBatis查询数据库,匹配账号和密码
-
错误则响应登录失败
package com.itheima.web;
import com.itheima.mapper.UserMapper;
import com.itheima.pojo.User;
import com.itheima.util.SqlSessionFactoryUtils;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
@WebServlet("/loginServlet")
public class LoginServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1. 接收用户名和密码
String username = request.getParameter("username");
String password = request.getParameter("password");
//2. 调用MyBatis完成查询
//2.1 获取SqlSessionFactory对象
/* String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);*/
SqlSessionFactory sqlSessionFactory = SqlSessionFactoryUtils.getSqlSessionFactory();
//2.2 获取SqlSession对象
SqlSession sqlSession = sqlSessionFactory.openSession();
//2.3 获取Mapper
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
//2.4 调用方法
User user = userMapper.select(username, password);
//2.5 释放资源
sqlSession.close();
//获取字符输出流,并设置content type
response.setContentType("text/html;charset=utf-8");
PrintWriter writer = response.getWriter();
//3. 判断user释放为null
if(user != null){
// 登陆成功
writer.write("登陆成功");
}else {
// 登陆失败
writer.write("登陆失败");
}
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doGet(request, response);
}
}
6. JSP
html和java语句可以放到同一个文档里,简化开发
Jsp脚本用于编写java代码
-
<%....%>
-
内容会直接放到jspService中去
-
-
<%=....%>
-
内容会放到out.print中去,作为out.print的参数
-
-
<%!....%>
-
内容会放到JSPService方法之外,被类直接包含(成员地位)
-
6.1 EL表达式
用于获取数据
${expression}

7. MVC和三层架构



8. 会话跟踪技术
-
会话是与浏览器绑定
-
会话跟踪是服务器识别多次请求是否来自同一浏览器发出的

8.1 Cookie
-
服务器setCookie 通过HTTP发送给浏览器
-
浏览器下次请求时就会携带上上次服务器发来的Cookie(可能会有很多Cookie)
-
按照键去查找需要的Cookie
-


8.2 Session
-
将会话数据保存到服务端
-
Session是基于Cookie的



8.3 对比
例如:验证码的实现就不能是Cookie,因为Cookie是保存在浏览器中的


26万+

被折叠的 条评论
为什么被折叠?



