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服务器软件
-  下载:Apache Tomcat® - Welcome! 
-  安装:解压压缩包即可,注意:安装目录建议不要有中文和空格 
-  启动:运行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项目 
-  导入依赖 
-  <dependency> 
 <groupId>javax.servlet</groupId>
 <artifactId>javax.servlet-api</artifactId>
 <version>4.0.1</version>
 </dependency>
-  定义一个类,实现Servlet接口 
-  public class ServletDemo1 extends HttpServlet 
-  实现抽象类中的抽象方法 
-  public class ServletDemo1 extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("前端发送了一个get请求"); } }在web.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>访问方式 
-  http://localhost:8080/Test_war_exploded/ServletDemo1 
1.6 Servlet3.0
-  好处: 
支持注解配置。可以不需要配置web.xml了
-  步骤: 
-  创建JavaEE项目 
-  定义一个类,实现Servlet接口 
-  重写方法 
-  在类上使用@WebServlet注解,进行配置 
代码示例:
@WebServlet(urlPatterns = "/demo1")
 @WebServlet(value = "/demo2")
 @WebServlet(name = "/demo3")
 @WebServlet("/demo4")
http://localhost:8080/Http_Demo_war_exploded/servletDemo1
 http://localhost:8080
 /Http_Demo_war_exploded -- 虚拟路径  实际开发中我们会将虚拟路径配置成/
 /servletDemo1    -- 资源路径 -- 资源路径是工作类的首字母小写
 修改之后的路径是:
 http://localhost:8080/servletDemo1

1.7 前端发送请求
<!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>@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: 扩展名匹配 
 
-  
 
-  
代码示例:
@WebServlet({"/d2", "/dd2", "/ddd2"})//都可以访问到
 @WebServlet("/demo2/user") //多层路径
 @WebServlet("/demo2/*") //通配符,  *任意字符
 @WebServlet("*.do") // 任意字符.do 访问
2.0 Http
2.1 TCP与UDP
-  网络分层模型  
-  32 42 点分十进制 00000000 00000000 00000000 00000000 0-255. 37 38. 5.6。20。代理 2 128 十六进制 110.242.68.4。DNS 域名服务商 Byte.0 255 
-  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 -  告诉服务器,我(当前请求)从哪里来 
 
-  
-  演示 
-  @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请求消息的请求参数的 
-  username: zs 
 password: 123
-  注意:username=123 请求体 ,只有post请求才可以查看到,get请求是没有的,get请求参数是在url中。 
请求消息数据格式:
字符串格式:
 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对象继承体系结构:
ServletRequest        --    父接口
             ⬆️    
 HttpServletRequest    -- 子接口        
request功能
1.获取请求行数据
GET /day02/demo1?name=zhangsan HTTP/1.1
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()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.12.获取请求头数据
-  方法: -  String getHeader(String name):通过请求头的名称获取请求头的值 
-  Enumeration< String > getHeaderNames():获取所有的请求头名称 
 
-  
代码示例:
//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 介绍,判断客户端是哪个浏览器
//获取请求头数据  user - agent
String agent = req.getHeader("user-agent");//不区分大小写
//判断浏览器版本
if (agent.contains("Chrome")) {
      //处理兼容性问题
    System.out.println("谷歌浏览器");
} else if (agent.contains("Firefox")) {
    System.out.println("火狐浏览器");
}3.获取请求参数:
演示:
<!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"); 
 
-  
 
-  
 /**
 * 获取请求参数通用方式
 */
@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):通过键移除键值对 
  
-  
代码示例:
/**
 * 请求转发:一种在服务器内部的资源跳转方式
 * 服务器内部资源跳转
 * 从一个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.get("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域(多次请求,会话期间)
@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对象, 
-  作用范围:所有的用户都可以取得此信息,此信息在整个服务器上被保留。 
-  属性范围值:只要设置一次,则所有的网页窗口都可以取得数据。 
-  方法: 
-  ServletContext 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
2.6 Response
响应消息
-  请求消息:客户端发送给服务器端的数据 -  数据格式: -  请求行 
-  请求头 
-  请求空行 
-  请求体 
 
-  
 
-  
-  响应消息:服务器端发送给客户端的数据 -  数据格式: -  响应行 
-  响应头 
-  响应空行 
-  响应体 
 
-  
 -  响应行 -  组成:协议/版本 响应状态码 状态码描述 HTTP/1.1 200 OK 
-  响应状态码:服务器告诉客户端浏览器本次请求和响应的一个状态。 -  状态码都是3位数字 
-  分类: 1xx:试探性请求,服务器接收客户端消息,没接受完成,等待一段时间后,发送1xx状态码 100: 请求者应当继续提出请求。 服务器返回此代码表示已收到请求的第一部分,正在等待其余部分 2xx:成功。代表:200 服务器已经成功处理了请求 3xx:重定向。代表:302(重定向),304(访问缓存) 4xx:客户端错误。 代表: 404(请求路径没有对应的资源) 405:比如请求方式 没有对应的doXxx方法 5xx:服务器端错误。代表:500(服务器内部出现异常) ,比如运算错误 
 
-  
 
-  
-  响应头: -  格式: 
-  头名称 : 值 
-  常见的响应头: 
-  /* Content-Type:服务器告诉客户端本次响应体数据格式以及编码格式 
 /* text/html;charset=utf-8
 协议 域 名端口 同源
 跨域请求
 只会限制ajax
 
-  
-  响应空行 -  响应体 传输给前端的数据 响应字符串格式 
-  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@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"); 
 代码示例: 
-  
-  /** * @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域中的数据 










