狂神说JavaWeb详细笔记

概念

前言

静态Web:

. 提供给所有人看数据不会发生变化!
. HTML,CSS

动态Web:

.有数据交互,登录账号密码,网站访问人数等

. 技术栈:Servlet/JSP,ASP,PHP

在Java中,动态web资源开发的技术统称为JavaWeb;

WEB应用程序

Web 应用程序:可以提供浏览器访问的程序;

这个统一的web资源会被放在同一个文件夹下,Web 应用程序 —> Tomcat:服务器
一个 Web 应用由多部分组成(静态Web、动态Web)

HTML,CSS,JavaScript
JSP,Servlet
Java 程序
jar 包
配置文件 (Properties)

Web 应用程序编写完毕后,若想提供给外界访问:需要一个服务器来统一管理;

动态WEB的访问过程

在这里插入图片描述
浏览器发送 HTTP 请求,服务器 Tomcat 接收请求,Servlet 容器从磁盘加载 Servlet 程序处理请求 request ,处理结束返回 response。

WEB服务器

技术讲解

PHP:

作为开发速度很快,功能很强大,跨平台
无法承载大访问量的情况

JSP/Servlet:

基于 Java 语言

Tomcat是Apache 软件基金会(Apache Software Foundation)的Jakarta 项目中的一个核心项目。

Tomcat 技术先进、性能稳定,而且免费。

Tomcat

安装tomcat

安装的地址:
http://tomcat.apache.org/
在这里插入图片描述
在这里插入图片描述## tomcat的启动和配置
在这里插入图片描述启动和关闭tomcat
在这里插入图片描述注意:
1.Java 环境变量没有配置导致闪退。
2.乱码问题,可在配置文件中配置。

配置

servlet的核心配置配置如下:
在这里插入图片描述可以配置启动的端口号
tomcat的默认端口号为:8080
mysql:3306
http:80
https:443

<Connector port="8081" protocol="HTTP/1.1"
           connectionTimeout="20000"
           redirectPort="8443" />

可配置主机名称

默认的主机名为:localhost->127.0.0.1
默认网站应用存放的位置为:webapps

  <Host name="www.zty.com"  appBase="webapps"
        unpackWARs="true" autoDeploy="true">

往年面试题:请你谈谈网站是如何进行访问的!
在浏览器输入一个域名,回车;

本机查看 C:\Windows\System32\drivers\etc\hosts 配置文件是否有相应域名的映射。

case1: 若有,则直接映射到对应的 IP 地址,进行访问。

case2: 若无,则去 DNS 服务器上查找对应的 IP ,找到就返回相应的 IP,找不到就不返回。

在这里插入图片描述

在这里插入图片描述

发布一个WEB网站

网站程序的结构:

--webapps :Tomcat服务器的web目录
	-ROOT
	-study :网站的目录名
		- WEB-INF
			-classes : java程序
			-lib:web应用所依赖的jar包
			-web.xml :网站配置文件
		- index.html 默认的首页
		- static 
            -css
            	-style.css
            -js
            -img
         -.....

HTTP

什么是HTTP

HTTP(hypertext transport protocol) 超文本传输协议。

文本 :HTML,字符串…
超文本:图片,音乐,视频,定位,地图…
80 端口

HTTPS(Hyper Text Transfer Protocol over SecureSocket Layer):是以安全为目标的 HTTP 通道,在 HTTP 的基础上通过传输加密和身份认证保证了传输过程的安全性。HTTPS 在HTTP 的基础下加入SSL 层,HTTPS 的安全基础是 SSL。

443 端口

HTTP的两个时代

HTTP 1.0:

HTTP/1.0:客户端与 Web 服务器连接后,只能获得一个Wen 资源,然后就断开连接,加入某个页面有多个图片资源需要加载,那么需要连接多次,影响服务器和客户端的性能。

HTTP 2.0:

HTTP/1.1:客户端可以与web服务器连接后,可以获得多个web资源。

HTTP请求

客户端 -> 发送请求(Request)->服务器

Request URL:https://www.baidu.com/   请求地址
Request Method:GET    get方法/post方法
Status Code:200 OK    状态码:200
Remote(远程) Address:14.215.177.39:443
1234
Accept:text/html  
Accept-Encoding:gzip, deflate, br
Accept-Language:zh-CN,zh;q=0.9    语言
Cache-Control:max-age=0
Connection:keep-alive

请求行

请求行中的请求方式:GET
请求方式:Get,Post,HEAD,DELETE,PUT,TRACT…

get:请求能够携带的参数比较少,大小有限制,会在浏览器的URL地址栏显示数据内容,不安全,但高效

post:请求能够携带的参数没有限制,大小没有限制,不会在浏览器的URL地址栏显示数据内容,安全,但不高效。

消息头:

Accept:告诉浏览器,它所支持的数据类型
Accept-Encoding:支持哪种编码格式  GBK   UTF-8   GB2312  ISO8859-1
Accept-Language:告诉浏览器,它的语言环境
Cache-Control:缓存控制
Connection:告诉浏览器,请求完成是断开还是保持连接
HOST:主机..../.

HTTP请求

服务器 -> 响应(response) ->客户端

Cache-Control:private    缓存控制
Connection:Keep-Alive    连接
Content-Encoding:gzip    编码
Content-Type:text/html   类型

响应体

Accept:告诉浏览器,它所支持的数据类型
Accept-Encoding:支持哪种编码格式  GBK   UTF-8   GB2312  ISO8859-1
Accept-Language:告诉浏览器,它的语言环境
Cache-Control:缓存控制
Connection:告诉浏览器,请求完成是断开还是保持连接
HOST:主机..../.
Refresh:告诉客户端,多久刷新一次;
Location:让网页重新定位;

响应状态码

200:请求响应成功 200

3xx:请求重定向

重定向:你重新到我给你新位置去;

4xx:找不到资源 404

5xx:服务器代码错误 500 502:网关错误

注意:
常见的面试题:
当你的浏览器中地址栏输入地址并回车的一瞬间到页面能够展示回来,经历了什么?

Maven

在 JavaWeb 开发中,需要使用大量的 jar 包,我们手动去导入;
如何能够让一个东西自动帮我导入和配置这个jar包。
由此,Maven诞生了!

Maven项目架构管理工具

Maven 的核心思想:约定大于配置

有约束,不要去违反。
Maven 会规定好你该如何去编写我们的 Java 代码,必须要按照这个规范来;

在IDEA里面使用Maven

1、启动 IDEA
2、 创建一个 MavenWeb 项目
3、等待项目初始化完毕
4、观察 maven 仓库中多了什么东西?
5、 IDEA 中的 Maven 设置
注意:IDEA 项目创建成功后,看一眼 Maven 的配置
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

创建一个普通的Maven项目

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

标记文件夹功能

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在IDEA中配置tomcat
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
Maven 由于他的约定大于配置,我们之后可以能遇到我们写的配置文件,无法被导出或者生效的问题,解决方案:

<!--在build中配置resources,来防止我们资源导出失败的问题--><build>   
 <resources>  
       <resource>          
         <directory>src/main/resources</directory>            <includes>                <include>**/*.properties</include>                <include>**/*.xml</include>         
            </includes>            <filtering>true</filtering>  
                  </resource> 
                         <resource>            <directory>src/main/java</directory>            <includes>  
                                       <include>**/*.properties</include> 
                                                      <include>**/*.xml</include>   
                          
                                  
                               </includes>            <filtering>true</filtering>    
                                      </resource>    </resources>
                                      </build>

在这里插入图片描述在这里插入图片描述

解决遇到的问题

Maven 3.6.2
解决方法:降级为 3.6.1
Tomcat 闪退
IDEA中每次都要重复配置Maven
在IDEA中的全局默认配置中去配置
在这里插入图片描述
在这里插入图片描述
Maven 默认 Web 项目中的 web.xml 版本问题
在这里插入图片描述
替换为 webapp4.0 版本和 Tomcat 一致

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
                      http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0"
         metadata-complete="true">



</web-app>
1234567891011

Servlet简介

Servlet 就是 Sun 公司开发动态 Web 的一门技术

Sun 在这些 API (Application Programming Interface,应用程序接口)中提供一个接口叫做:Servlet,如果你想开发一个Servlet程序,只需要完成两个小步骤:

编写一个类,实现Servlet接口。
把开发好的Java类部署到web服务器中。

把实现了 Servlet 接口的 Java 程序叫做,Servlet

HelloServlet

Serlvet 接口 Sun 公司有两个默认的实现类:HttpServlet,GenericServlet

构建一个普通的Maven项目,删掉里面的src目录,以后我们的学习就在这个项目里面建立Moudel;这个空的工程就是Maven主工程(建一个WebApp Maven项目,勾选模板);

关于Maven父子工程的理解:

父项目中会有:

    <modules>
        <module>servlet-01</module>
    </modules>

子项目会有:

    <parent>
        <artifactId>javaweb-02-servlet</artifactId>
        <groupId>com.lt</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>

父项目的java子项目也可以用

 son extends father

Maven环境优化

修改web.xml为最新的

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
         http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0"
         metadata-complete="true">
</web-app>

编写一个Servlet程序
在这里插入图片描述编写一个不同的类 继承HttpServelt

public class HelloServlet extends HttpServlet {
    //由于get或者post只是请求实现的方式不同,可以相互调用,业务逻辑都一样!
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //ServletOutputStream outputStream = response.getOutputStream();
        PrintWriter writer = response.getWriter();//响应流
        writer.println("Hello Servlet");
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }
}


编写Servlet映射:
为什么需要映射:我们写的是 Java 程序,但是要通过浏览器访问,而浏览器需要连接 Web 服务器,所以我们需要在Web 服务中注册我们写的 Servlet,还需给他一个浏览器能够访问的路径;

<!--注册Servlet-->
    <servlet>
        <servlet-name>hello</servlet-name>
        <servlet-class>com.lt.servlet.HelloServlet</servlet-class>
    </servlet>
    <!--Servlet的请求路径-->
    <servlet-mapping>
        <servlet-name>hello</servlet-name>
        <url-pattern>/hello</url-pattern>
    </servlet-mapping>

Servlet原理

Servlet 是由 Web 服务器调用,Web 服务器在收到浏览器请求之后,
在这里插入图片描述

Mapping的问题

一个Servlet可以指定一个映射路径

    <servlet-mapping>
        <servlet-name>hello</servlet-name>
        <url-pattern>/hello</url-pattern>
    </servlet-mapping>

一个Servlet可以指定多个映射路径

    <servlet-mapping>
        <servlet-name>hello</servlet-name>
        <url-pattern>/hello</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>hello</servlet-name>
        <url-pattern>/hello2</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>hello</servlet-name>
        <url-pattern>/hello3</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>hello</servlet-name>
        <url-pattern>/hello4</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>hello</servlet-name>
        <url-pattern>/hello5</url-pattern>
    </servlet-mapping>

一个Servlet可以指定用的的普通路径

    <servlet-mapping>
        <servlet-name>hello</servlet-name>
        <url-pattern>/hello/*</url-pattern>
    </servlet-mapping>

默认的请求路径

    <!--默认请求路径-->
    <servlet-mapping>
        <servlet-name>hello</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>

一些前缀后缀

<!--可以自定义后缀实现请求映射
    注意点,*前面不能加项目映射的路径
    hello/sajdlkajda.zty
    -->
<servlet-mapping>
    <servlet-name>hello</servlet-name>
    <url-pattern>*.zty</url-pattern>
</servlet-mapping>

优先级问题
指定了固有的映射路径优先级最高,如果找不到就会走默认的处理请求

<!--404-->
<servlet>
    <servlet-name>error</servlet-name>
    <servlet-class>com.lt.servlet.ErrorServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>error</servlet-name>
    <url-pattern>/*</url-pattern>
</servlet-mapping>

ServletContext

Web 容器在启动的时候,它会为每个 Web 程序都创建一个对应的 ServletContext 对象,它代表了当前的 Web 应用;

共享数据

在一个servelet保存数据可以在另一个servlet里面拿到

package com.lt.servlet;

import javax.servlet.*;
import javax.servlet.http.*;
import java.io.IOException;

public class HelloServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
        //this.getInitParameter()   初始化参数
        //this.getServletConfig()   Servlet配置
        //this.getServletContext()  Servlet上下文
        ServletContext context = this.getServletContext();

        String username = "林滔"; //数据
        context.setAttribute("username",username); //将一个数据保存在了ServletContext中,名字为:username 。值 username
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {

    }
}

package com.lt.servlet;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class GetServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext context = this.getServletContext();
        String username = (String) context.getAttribute("username");

        resp.setContentType("text/html");
        resp.setCharacterEncoding("utf-8");
        resp.getWriter().print("名字"+username);

    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

测试结果。

    <!--注册Servlet-->
    <servlet>
        <servlet-name>hello</servlet-name>
        <servlet-class>com.lt.servlet.HelloServlet</servlet-class>
    </servlet>
    <!--Servlet的请求路径-->
    <servlet-mapping>
        <servlet-name>hello</servlet-name>
        <url-pattern>/hello</url-pattern>
    </servlet-mapping>

    <servlet>
        <servlet-name>getc</servlet-name>
        <servlet-class>com.lt.servlet.GetServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>getc</servlet-name>
        <url-pattern>/getc</url-pattern>
    </servlet-mapping>
    <!--注册Servlet-->
    <servlet>
        <servlet-name>hello</servlet-name>
        <servlet-class>com.zty.servlet.HelloServlet</servlet-class>
    </servlet>
    <!--Servlet的请求路径-->
    <servlet-mapping>
        <servlet-name>hello</servlet-name>
        <url-pattern>/hello</url-pattern>
    </servlet-mapping>

    <servlet>
        <servlet-name>getc</servlet-name>
        <servlet-class>com.zty.servlet.GetServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>getc</servlet-name>
        <url-pattern>/getc</url-pattern>
    </servlet-mapping>

获取初始化参数

    <!--配置一些web应用初始化参数-->
    <context-param>
        <param-name>url</param-name>
        <param-value>jdbc:mysql://localhost:3306/mybatis</param-value>
    </context-param>
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    ServletContext context = this.getServletContext();
    String url = context.getInitParameter("url");
    resp.getWriter().print(url);
}

请求转发

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    ServletContext context = this.getServletContext();
    System.out.println("进入了ServletDemo04");
    //RequestDispatcher requestDispatcher = context.getRequestDispatcher("/gp"); //转发的请求路径
    //requestDispatcher.forward(req,resp); //调用forward实现请求转发;
    context.getRequestDispatcher("/gp").forward(req,resp);
}

请求转发和重定向的图解
在这里插入图片描述

读取资源文件

Properties

在 java 目录下新建 properties
在 resources 目录下新建 properties

发现:都被打包到了同一个路径下:classes,我们俗称这个路径为classpath:

思路:需要一个文件流;

username=lt
password=123456
public class ServletDemo05 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        InputStream is = this.getServletContext().getResourceAsStream("/WEB-INF/classes/db.properties");

        Properties prop = new Properties();
        prop.load(is);
        String user = prop.getProperty("username");
        String pwd = prop.getProperty("password");

        resp.getWriter().print(user+":"+pwd);

    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

HttpServletResponse

Web 服务器接收到客户端的 http 请求,针对这个请求,分别创建一个代表请求的 HttpServletRequest 对象,代表响应的一个 HttpServletResponse;

如果想要获取客户端请求过来的参数:找 HttpServletRequest
如果要给客户端响应一些信息:找 HttpServletResponse

简单分类

负责向浏览器发送数据方法

ServletOutputStream getOutputStream() throws IOException;
PrintWriter getWriter() throws IOException;

负责想浏览器发送数据响应头

    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);

响应状态码

 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.获取 OutputStream 对象
7.将 FileOutputStream 写入到 buffer缓冲区
8.使用 OutputStream 将缓冲区中的数据输出到客户端

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    // 1. 要获取下载文件的路径
    String realPath = "F:\\班级管理\\西开【19525】\\2、代码\\JavaWeb\\javaweb-02-servlet\\response\\target\\classes\\张天泳.png";
    System.out.println("下载文件的路径:"+realPath);
    // 2. 下载的文件名是啥?
    String fileName = realPath.substring(realPath.lastIndexOf("\\") + 1);
    // 3. 设置想办法让浏览器能够支持(Content-Disposition)下载我们需要的东西,中文文件名URLEncoder.encode编码,否则有可能乱码
    resp.setHeader("Content-Disposition","attachment;filename="+URLEncoder.encode(fileName,"UTF-8"));
    // 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);
    }

    in.close();
    out.close();
}

实现重定向

在这里插入图片描述
Web 资源 B 收到客户端 A 请求后,通知 A 访问另一个 Web 资源 C ,这个过程叫做重定向

常见场景:
用户登录

void sendRedirect(String var1) throws IOException;
1
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

    /*
        resp.setHeader("Location","/r/img");
        resp.setStatus(302);
         */
    resp.sendRedirect("/r/img");//重定向
}

面试题:重定向和请求转发的区别
相同点:

页面都会实现跳转
不同点:
请求转发的时候,URL 不会发生变化
重定向时候,URL 地址栏会发生变化

在这里插入图片描述

简单实现登录重定向

<%--这里提交的路径,需要寻找到项目的路径--%>
<%--${pageContext.request.contextPath}代表当前的项目--%>

<form action="${pageContext.request.contextPath}/login" method="get">
    用户名:<input type="text" name="username"> <br>
    密码:<input type="password" name="password"> <br>
    <input type="submit">
</form>
12345678
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //处理请求
        String username = req.getParameter("username");
        String password = req.getParameter("password");

        System.out.println(username+":"+password);

        //重定向时候一定要注意,路径问题,否则404;
        resp.sendRedirect("/r/success.jsp");
    }
123456789101112
  <servlet>
    <servlet-name>requset</servlet-name>
    <servlet-class>com.lt.servlet.RequestTest</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>requset</servlet-name>
    <url-pattern>/login</url-pattern>
  </servlet-mapping>
12345678
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>

<h1>Success</h1>

</body>
</html>

HttpServletRequest 获取参数,请求转发

HttpServletRequest 代表客户端的请求,用户通过 HTTP 协议访问服务器,HTTP 请求中的所有信息会被封装到 HttpServletRequest ,通过这个HttpServletRequest 的方法,获得客户端的所有信息;

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

    req.setCharacterEncoding("utf-8");
    resp.setCharacterEncoding("utf-8");

    String username = req.getParameter("username");
    String password = req.getParameter("password");
    String[] hobbys = req.getParameterValues("hobbys");
    System.out.println("=============================");
    //后台接收中文乱码问题
    System.out.println(username);
    System.out.println(password);
    System.out.println(Arrays.toString(hobbys));
    System.out.println("=============================");


    System.out.println(req.getContextPath());
    //通过请求转发
    //这里的 / 代表当前的web应用
    req.getRequestDispatcher("/success.jsp").forward(req,resp);

}

Cookie、Session

会话

话:用户打开一个浏览器,点击了很多超链接,访问多个 Web 资源,关闭浏览器,这个过程可以称之为会话;

有状态会话:一个同学来过教室,下次再来教室,我们会知道这个同学,曾经来过,称之为有状态会话;

你能怎么证明你是学生?
你 学校
发票 学校开的发票
学校登记 校牌
你 学校
发票 学校开的发票
学校的登记 学校给你的校牌

一个网站,怎么证明你来过?
客户端 服务端
服务端给客户端一个 信件,客户端下次访问服务端带上信件就可以了; cookie

客户端 : 服务端给客户端一个 信件,客户端下次访问服务端带上信件就可以了; cookie
服务端:服务器登记你来过了,下次你来的时候我来匹配你; seesion

保存会话的两种技术

cookie:
客户端技术(响应,请求)
session:
服务器技术,利用这个技术,可以保存用户的会话信息?可将信息或数据放在 session 中

Cookie

在这里插入图片描述
从请求中拿到cookie
服务器响应给客户端cookie

Cookie[] cookies = req.getCookies(); //获得Cookie
cookie.getName(); //获得cookie中的key
cookie.getValue(); //获得cookie中的vlaue
new Cookie("lastLoginTime", System.currentTimeMillis()+""); //新建一个cookie
cookie.setMaxAge(24*60*60); //设置cookie的有效期
resp.addCookie(cookie); //响应给客户端一个cookie

cookie:
一般会保存在本地的用户目录下 appdata ;
一个 Web 站点可以给浏览器发送多个 Cookie,最多存放 20 个 cookie;
cookie 大小有限制 4kb;
300 个 cookie 浏览器上限

删除 Cookie:

不设置有效期,关闭浏览器,自动失效;
设置有效期为 0;

编码解码

URLEncoder.encode("林滔","utf-8")
URLDecoder.decode(cookie.getValue(),"UTF-8")

在这里插入图片描述
什么是 Session ?

服务器会给每一个用户(浏览器)创建一个 Session 对象;
一个 Session 独占一个浏览器,只要浏览器没有关闭,这个 Session 就存在;
用户登录之后,整个网站它都可以访问!-> 保存用户的信息;保存购物车的信息…

在这里插入图片描述
Session 和 cookie 的区别:
Cookie是把用户的数据写给用户的浏览器,浏览器保存 (可以保存多个)
Session把用户的数据写到用户独占Session中,服务器端保存 (保存重要的信息,减少服务器资源的浪费)
Session 对象由服务创建;

使用场景:
保存一个登录用户的信息;
购物车信息;
在整个网站中经常会使用的数据,我们将它保存在 Session 中;

package com.zty.servlet;

import com.lt.pojo.Person;

import javax.servlet.ServletException;
import javax.servlet.http.*;
import java.io.IOException;

public class SessionDemo01 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        
        //解决乱码问题
        req.setCharacterEncoding("UTF-8");
        resp.setCharacterEncoding("UTF-8");
        resp.setContentType("text/html;charset=utf-8");
        
        //得到Session
        HttpSession session = req.getSession();
        //给Session中存东西
        session.setAttribute("name",new Person("张天泳",1));
        //获取Session的ID
        String sessionId = session.getId();

        //判断Session是不是新创建
        if (session.isNew()){
            resp.getWriter().write("session创建成功,ID:"+sessionId);
        }else {
            resp.getWriter().write("session以及在服务器中存在了,ID:"+sessionId);
        }

        //Session创建的时候做了什么事情;
//        Cookie cookie = new Cookie("JSESSIONID",sessionId);
//        resp.addCookie(cookie);

    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

//得到Session
HttpSession session = req.getSession();

Person person = (Person) session.getAttribute("name");

System.out.println(person.toString());

HttpSession session = req.getSession();
session.removeAttribute("name");
//手动注销Session
session.invalidate();

会话自动过期:web.xml 配置

<!--设置Session默认的失效时间-->
<session-config>
    <!--15分钟后Session自动失效,以分钟为单位-->
    <session-timeout>15</session-timeout>
</session-config>

在这里插入图片描述

JSP

什么是JSP

Java Server Pages : Java服务器端页面,也和Servlet一样,用于动态Web技术!

最大的特点:

写JSP就像在写HTML

区别:

HTML只给用户提供静态的数据
JSP 页面中可以嵌入Java 代码,为用户提供动态数据;

JSP原理

服务器内部工作:
Tomcat 中有一个 work 工作目录;
IDEA 中使用 Tomcat 的会在 IDEA 中 Tomcat 中生产一个 work 目录

发现页面转变成了 Java 程序

在这里插入图片描述
浏览器向服务器发送请求,不管访问什么资源,起始都是在访问 Servlet !

JSP 最终也会被转换成一个 Java 类!
JSP 本质上就是一个 Servlet

//初始化
  public void _jspInit() {
      
  }
//销毁
  public void _jspDestroy() {
  }
//JSPService
  public void _jspService(.HttpServletRequest request,HttpServletResponse response)

final javax.servlet.jsp.PageContext pageContext;  //页面上下文
javax.servlet.http.HttpSession session = null;    //session
final javax.servlet.ServletContext application;   //applicationContext
final javax.servlet.ServletConfig config;         //config
javax.servlet.jsp.JspWriter out = null;           //out
final java.lang.Object page = this;               //page:当前
HttpServletRequest request                        //请求
HttpServletResponse response                      //响应

在这里插入图片描述
在JSP页面中;

只要是 JAVA代码就会原封不动的输出;

如果是HTML代码,就会被转换为:

out.write("<html>\r\n");

这样的代码输出到服务器中

JSP基础语法

  <%--JSP表达式
  作用:用来将程序的输出,输出到客户端
  <%= 变量或者表达式%>
  --%>
  <%= new java.util.Date()%>

JSP脚本片段

  <%--jsp脚本片段--%>
  <%
    int sum = 0;
    for (int i = 1; i <=100 ; i++) {
      sum+=i;
    }
    out.println("<h1>Sum="+sum+"</h1>");
  %>

脚本片段再实现

  <%
    int x = 10;
    out.println(x);
  %>
  <p>这是一个JSP文档</p>
  <%
    int y = 2;
    out.println(y);
  %>

  <hr>


  <%--在代码嵌入HTML元素--%>
  <%
    for (int i = 0; i < 5; i++) {
  %>
    <h1>Hello,World  <%=i%> </h1>
  <%
    }
  %>

JSP声明

  <%!
    static {
      System.out.println("Loading Servlet!");
    }

    private int globalVar = 0;

    public void lt(){
      System.out.println("进入了方法zty!");
    }
  %>

JSP 声明: 会被编译到 JSP 生成 Java 的类中! 其他的,就会被生成 _jspService 方法中!

<%%>
<%=%>
<%!%>

<%--注释--%>

JSP指令

<%@page args.... %>
<%@include file=""%>

<%--@include会将两个页面合二为一--%>

<%@include file="common/header.jsp"%>
<h1>网页主体</h1>

<%@include file="common/footer.jsp"%>

<hr>


<%--jSP标签
    jsp:include:拼接页面,本质还是三个
    --%>
<jsp:include page="/common/header.jsp"/>
<h1>网页主体</h1>
<jsp:include page="/common/footer.jsp"/>

九大内置对象

1、 PageContext 存东西
2、 Request 存东西
3、 Response
4、 Session 存东西
5、 Application 【ServletContext】 存东西
6、 config 【ServletConfig】
7、 out
8、 page
9、 exception

pageContext.setAttribute("name1","1号"); //保存的数据只在一个页面中有效
request.setAttribute("name2","2号"); //保存的数据只在一次请求中有效,请求转发会携带这个数据
session.setAttribute("name3","3号"); //保存的数据只在一次会话中有效,从打开浏览器到关闭浏览器
application.setAttribute("name4","4号");  //保存的数据只在服务器中有效,从打开服务器到关闭服务器
1234

request:客户端向服务器发送请求,产生的数据,用户看完就没用了,比如:新闻,用户看完没用的!

session:客户端向服务器发送请求,产生的数据,用户用完一会还有用,比如:购物车;

application:客户端向服务器发送请求,产生的数据,一个用户用完了,其他用户还可能使用,比如:聊天数据;

JSP标签、JSTL标签、EL表达式

<!-- JSTL表达式的依赖 -->
<dependency>
    <groupId>javax.servlet.jsp.jstl</groupId>
    <artifactId>jstl-api</artifactId>
    <version>1.2</version>
</dependency>
<!-- standard标签库 -->
<dependency>
    <groupId>taglibs</groupId>
    <artifactId>standard</artifactId>
    <version>1.1.2</version>
</dependency>

EL 表达式: ${}

获取数据
执行运算
获取 Web 开发的常用对象

jsp标签:

<%--jsp:include--%>

<%--
http://localhost:8080/jsptag.jsp?name=ztyshen&age=12
--%>

<jsp:forward page="/jsptag2.jsp">
    <jsp:param name="name" value="ztyshen"></jsp:param>
    <jsp:param name="age" value="12"></jsp:param>
</jsp:forward>

JSTL表达式
JSTL 标签库的使用就是为了弥补 HTML 标签的不足;它自定义许多标签,可以供我们使用,标签的功能和 Java 代码一样!

格式化标签

SQL标签

XML 标签

核心标签 (掌握部分)
在这里插入图片描述

JSTL标签库使用步骤

引入对应的 taglib
使用其中的方法
在 Tomcat 也需要引入 JSTL 的包,否则会报错:JSTL 解析错误

c: if

<head>
    <title>Title</title>
</head>
<body>


<h4>if测试</h4>

<hr>

<form action="coreif.jsp" method="get">
    <%--
    EL表达式获取表单中的数据
    ${param.参数名}
    --%>
    <input type="text" name="username" value="${param.username}">
    <input type="submit" value="登录">
</form>

<%--判断如果提交的用户名是管理员,则登录成功--%>
<c:if test="${param.username=='admin'}" var="isAdmin">
    <c:out value="管理员欢迎您!"/>
</c:if>

<%--自闭合标签--%>
<c:out value="${isAdmin}"/>

</body>

<body>

<%--定义一个变量score,值为85--%>
<c:set var="score" value="55"/>

<c:choose>
    <c:when test="${score>=90}">
        你的成绩为优秀
    </c:when>
    <c:when test="${score>=80}">
        你的成绩为一般
    </c:when>
    <c:when test="${score>=70}">
        你的成绩为良好
    </c:when>
    <c:when test="${score<=60}">
        你的成绩为不及格
    </c:when>
</c:choose>

</body>

<%

    ArrayList<String> people = new ArrayList<>();
    people.add(0,"张三");
    people.add(1,"李四");
    people.add(2,"王五");
    people.add(3,"赵六");
    people.add(4,"田六");
    request.setAttribute("list",people);
%>


<%--
var , 每一次遍历出来的变量
items, 要遍历的对象
begin,   哪里开始
end,     到哪里
step,   步长
--%>
<c:forEach var="people" items="${list}">
    <c:out value="${people}"/> <br>
</c:forEach>

<hr>

<c:forEach var="people" items="${list}" begin="1" end="3" step="1" >
    <c:out value="${people}"/> <br>
</c:forEach>

JavaBean

实体类
JavaBean有特定的写法:
必须要有一个无参构造
属性必须私有化
必须有对应的get/set方法;

一般用来和数据库的字段做映射 ORM;

ORM :对象关系映射

表—>类
字段–>属性
行记录---->对象
在这里插入图片描述

class People{
    private int id;
    private String name;
    private int id;
    private String address;
}

class A{
    new People(1,"1号",3"西安");
    new People(2,"2号",3"西安");
    new People(3,"3号",3"西安");
}

MVC三层架构

什么是 MVC : Model View Controller 模型、视图、控制器
在这里插入图片描述
用户直接访问控制层,控制层就可以直接操作数据库;

servlet--CRUD-->数据库
弊端:程序十分臃肿,不利于维护  
servlet的代码中:处理请求、响应、视图跳转、处理JDBC、处理业务代码、处理逻辑代码

架构:没有什么是加一层解决不了的!
程序猿调用
|
JDBC
|
Mysql Oracle SqlServer ....

MVC三层架构

在这里插入图片描述
Model

业务处理:业务逻辑(Service)
数据持久层:CRUD

View

展示数据
提供链接发起 Servlet 请求(a,form,img…)

Controller (Servlet)

接收用户的请求:(req:请求参数、Session 信息…)
交给业务层处理对应的代码
控制试图的跳转

  登录--->接收用户的登录请求--->处理用户的请求(获取用户登录的参数,username,password)---->交给业务层处理登录业务(判断用户名密码是否正确:事务)--->Dao层查询用户名和密码是否正确-->数据库

Filter(重点)

Filter:过滤器,用来过滤网站的数据;

处理中文乱码
登录验证

在这里插入图片描述

lter 开发步骤:

导包
编写过滤器
导包不要错
在这里插入图片描述

public class CharacterEncodingFilter implements Filter {

    //初始化:web服务器启动,就以及初始化了,随时等待过滤对象出现!
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("CharacterEncodingFilter初始化");
    }

    //Chain : 链
    /*
    1. 过滤中的所有代码,在过滤特定请求的时候都会执行
    2. 必须要让过滤器继续同行
        chain.doFilter(request,response);
     */
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        request.setCharacterEncoding("utf-8");
        response.setCharacterEncoding("utf-8");
        response.setContentType("text/html;charset=UTF-8");

        System.out.println("CharacterEncodingFilter执行前....");
        chain.doFilter(request,response); //让我们的请求继续走,如果不写,程序到这里就被拦截停止!
        System.out.println("CharacterEncodingFilter执行后....");
    }

    //销毁:web服务器关闭的时候,过滤会销毁
    public void destroy() {
        System.out.println("CharacterEncodingFilter销毁");
    }
}

在web.xml中配置

<filter>
    <filter-name>CharacterEncodingFilter</filter-name>
    <filter-class>com.lt.filter.CharacterEncodingFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>CharacterEncodingFilter</filter-name>
    <!--只要是 /servlet的任何请求,会经过这个过滤器-->
    <url-pattern>/servlet/*</url-pattern>
    <!--<url-pattern>/*</url-pattern>-->
</filter-mapping>

监听器

实现一个监听器;

编写一个监听器
实现监听器的接口…

//统计网站在线人数 : 统计session
public class OnlineCountListener implements HttpSessionListener {

    //创建session监听: 看你的一举一动
    //一旦创建Session就会触发一次这个事件!
    public void sessionCreated(HttpSessionEvent se) {
        ServletContext ctx = se.getSession().getServletContext();

        System.out.println(se.getSession().getId());

        Integer onlineCount = (Integer) ctx.getAttribute("OnlineCount");

        if (onlineCount==null){
            onlineCount = new Integer(1);
        }else {
            int count = onlineCount.intValue();
            onlineCount = new Integer(count+1);
        }

        ctx.setAttribute("OnlineCount",onlineCount);

    }

    //销毁session监听
    //一旦销毁Session就会触发一次这个事件!
    public void sessionDestroyed(HttpSessionEvent se) {
        ServletContext ctx = se.getSession().getServletContext();

        Integer onlineCount = (Integer) ctx.getAttribute("OnlineCount");

        if (onlineCount==null){
            onlineCount = new Integer(0);
        }else {
            int count = onlineCount.intValue();
            onlineCount = new Integer(count-1);
        }

        ctx.setAttribute("OnlineCount",onlineCount);

    }


    /*
    Session销毁:
    1. 手动销毁  getSession().invalidate();
    2. 自动销毁
     */
}

在web.xml配置

<!--注册监听器-->
<listener>
    <listener-class>com.lt.listener.OnlineCountListener</listener-class>
</listener>


版权声明:本文为m0_64924660原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。