Web基础(Java前端基础)

1、Javaweb

1.1 基本概念

    web开发:

web,代表网页(网站)的意思,

    静态web:

列如静态web页面设计使用的:html,css。

静态web性质:提供给所有人看的数据始终不会发生变化。

    动态web

比如:淘宝、网易云、几乎所有的网站都使用动态web。

它提供给所有人看到的数据始终会发生变化,每个人在不同的时间,不同的地点看到的信息各不相同。

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

在Java中,动态web资源开发的技术称为Javaweb。

1.2 web应用程序

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

    a.html、b.html.....多个web资源,这些web资源可以被外界访问,对外界提供服务。 我们所访问的任何一个页面或者资源,都存在这个世界的某一个角落的计算机上。 URL:在WWW上,每一信息资源都有统一的且在网上唯一的地址。地址就叫URL。 这个统一的web资源会被放在同一个文件夹下,web应用程序—>Tomcat:服务器 一个web应用由多部份组成(比如:静态web,动态web)

Web组成:

前端:html,css,js

技术:jsp,servlet

Java程序

jar包

配置文件(Properties)

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

1.3 静态web

*.htm,*html,这些都是网页的后缀,如果服务器上一直存在这些东西,我们就可以直接进行读取,通络。

概念图:

静态web存在的缺点:

1、web页面无法动态的更新,所有用户看到的都是同一个页面。

2、它无法和数据库交互(数据库无法持久化,用户无法交互)

Javascript:

    Javascript中的轮播图,点击特效:就是伪动态页面。 Javascript:在实际开发中,它用的最多。 SBScript

1.4 动态web

页面会动态的展示:web的页面展示的效果因人而异。

概念图:

客户端连接到服务器:服务器中有一个专门处理的web,这个web可以动态的连接资源(这个资源是连接到数据库的)这个动态web资源在连接到一个WebServer(Server连接着我们的硬盘:比如

C盘、D盘也叫做文件系统)通过Server响应我们的客户端。

动态web缺点:

加入服务器的动态web资源如果出现了错误,我们需要重新编写我们的后台程序,重新发布。(就是常见的:停机维护)

优点:

1、web页面可以动态更新,所有用户看到的不是同一个页面。

2、它可以与用户交互(数据持久化:注册,商品信息,用户信息...)

2、web服务器

Web服务器一般指网站服务器,是指驻留于因特网上某种类型计算机的程序,可以处理浏览器等Web客户端的请求并返回相应响应,也可以放置网站文件,让全世界浏览;可以放置数据文件,让全世界下载。目前最主流的三个Web服务器是Apache、 Nginx 、IIS。

2.1 技术讲解

1、ASP:(动态服务器页面)

ASP它是微软的:ASP也是国内最早流行的。

它在HTML中嵌入了VB的脚本,ASP+COM。

在ASP开发中,基本一个页面都有几千行业务代码,页面及其让人眼花缭乱。

ASP的维护成本高。

2、PHP:(超文本预处理器)

PHP专门开发web(前端)的软件。

优点:

开发速度很快,功能很强大,可以跨平台操作,代码也很简单。(在我国70%的都是中小型网站,WP是一个开源的博客引擎,也可以去做一些网站)

缺点:

无法乘载大访问量的情况(有局限性)

3、JSP/Servlet:

B/S:Browser/Server,浏览器和服务器模式。

C/S:Client-Server,客户端和服务器。

sun公司主推的B/S架构。

基于Java语言的(所有的大公司,或者一些开源的组件,都是用Java写的)

它的语法像ASP:而学ASP的人就可以方便的转JSP。(加强市场的竞争度)

优点:

可以乘载三高问题带来的影响。(三高:高并发,高可用,高性能)

2.2 web服务器

服务器就是一种被动的操作,用来处理用户的一些请求和给用户一些响应信息。

1、IIS:

IIS是微软的:ASP是本土的,也是Windows中自带的服务。

2、Tomcat

图片:

面向百度了解Tomcat:

Tomcat是Apache 软件基金会(Apache Software Foundation)的Jakarta 项目中的一个核心项目,最新的Servlet 和JSP 规范总是能在Tomcat 中得到体现,因为Tomcat 技术先进、性能稳定,而且免费,因而深受Java 爱好者的喜爱并得到了部分软件开发商的认可,成为比较流行的Web 应用服务器。

Tomcat 服务器是一个免费的开放源代码的Web 应用服务器,属于轻量级应用,在中小型系统和并发访问用户不是很多的场合下被普遍使用,是开发和调试JSP 程序的首选。对于一个Java初学web的人来说,它是最佳的选择。

而Tomcat 实际上运行JSP 页面和Servlet。Tomcat最新版本为10.0.5

2.3 下载模板

适用于所有下载软件。

列如下载tmocat模板:

1、安装 or 解压。

2、了解配置文件及目录结构。

3、了解下载的这个东西的作用。

3、Tomcat

3.1 Tomcat安装

tomcat官网:

下载:

3.2 Tomcat启动和配置

文件夹作用:

3.3 启动和关闭Tomcat

1、进入bin文件找到startup.bat开启:

Tomcat默认端口号:

2、配置环境变量(可选)

4、Http

超文本传输协议(Hyper Text Transfer Protocol,HTTP)是一个简单的请求-响应协议,它通常运行在TCP(协议)之上。

4.1 什么是HTTP

HTTP(超文本传输协议)是一个简单的请求-响应协议,通常运行在TCP之上。

常见的文本:html,字符串,....

常见的超文本:图片、音乐、视频、定位、地球......

http端口:80

Https:是安全的

Https端口:443

4.2 Http的两个时代

http1.0:

HTTP/1.0:客户端可以与web服务器连接后,只能获得一个web资源。在请求过程中,请求不到就会断开连接。

http2.0:

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

4.3 Http请求

请求过程:

客户端—>发请求(Request)—>服务器—>百度—控制台-网络:

1、请求行

请求行中的请求方式:GET

请求方式:Get,Post,列如hml中的:HEAD,DELETE,PUT,TRACT...

Get:

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

Post:

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

2、消息头

Accept:text/html
Accept-Encoding:gzip,deflate,br
Accept-Language:zh-CN,zh:q=0.9   语言
Cache-Control:max-age=0
Connection:keep-alive
Accept:   // 告诉浏览器,它所支持的数据类型
Accept-Encoding:   // 支持哪种编码格式  列如:GBK,UTF-8,GB2312,ISO8859-1
Accept-Language:   // 告诉浏览器,它的语言环境
Cache-Control:   // 缓存控制
Connection:   // 告诉浏览器,请求完成是断开还是保持连接
Host:   // 主机

4.4 Http响应

响应过程:

服务器—>响应—>客户端—>百度—>控制台—>网络:

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

1、响应体

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

2、响应状态码

200:请求响应成功。 常见的:200

3xx:请求重定向。

重定向的意思是:重新定位到我给你设置的位置上。

4xx:找不到资源。 常见的:404

意思是资源不存在,找不到该资源。

5xx:服务器代码错误。 常见的:500 502:网关错误。

5、Maven

我为什么要学这个技术?

1、在Javaweb开发中,需要使用大量的jar包,而这个jar包需要我们手动去导入。

2、如何能够让一个东西自动帮我导入和配置这个jar包。

Maven可以:由此,Maven诞生了!

5.1 Maven(项目架构管理工具)

我们目前就是用Maven来方便导入jar包的。

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

什么意思呢?

maven中有约束,你不要去违反它的约束。

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

5.2 下载安装Maven

官网:

我下载的是Mavne3.6.3版本

下载后解压即可。

5.3 配置环境变量

在我们的系统环境变量中进行如下配置:

M2_HOME :maven目录下的bin目录

MAVEN_HOME:maven的目录

在系统的path中配置:%MAVEN_HOME%in

最后在命令提示符中输入mvn -version

测试Maven是否成功安装成功。保证必须确定配置完毕。

5.4 阿里云镜像

在apache-maven-3.6.3conf目录下的setting.xml中配置阿里云镜像代码。

镜像:mirrors

作用:加速我们的下载。

国内建议使用阿里云的镜像。

代码:

<mirror>
  <id>alimaven</id>
  <mirrorof>central</mirrorof>
  <name>aliyun maven</name>
<url>http://maven.aliyun.com/nexus/content/groups/public</url>
</mirror>

5.5本地仓库

1、在本地的仓库。

2、远程的仓库。

在apache-maven-3.8.4conf下的setting.xml中建立一个本地仓库:localRepository。

<localRepository>C:UsersleiDesktopjavaapache-maven-3.6.3maven-repo</localRepository>

rs用户Desktopjavaapache-maven-3.8.4maven-repo

5.6 在IDEA中使用Maven

1、可选设置

5.7 创建一个普通的Maven项目

项目结构:

使用Web应用如果没有以下两个文件夹就新建两个文件夹-Java和resources。

5.8 在idea中标记文件夹功能

方法一:

方法二:

5.9 在IDEA中配置Tomcat

解决错误:

5.10 pom文件

pom.xml是Maven的核心配置文件。

pom.xml介绍(代码介绍):

<?xml version="1.0" encoding="UTF-8"?>
<!--Maven版本的头文件-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
<!--这里就是我们配置的GAV-->
  <groupId>org.example</groupId>
  <artifactId>maven01</artifactId>
  <version>1.0-SNAPSHOT</version>
<!--  package:项目的打包方式
jar:Java应用
war:Javaweb应用
-->
  <packaging>war</packaging>

<!--  名称  -->
  <name>maven01 Maven Webapp</name>
  <!-- FIXME change it to the projects website -->
  <url>http://www.example.com</url>
<!--配置-->
  <properties>
<!--    项目的默认构建编码-->
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<!--    编译版本-->
    <maven.compiler.source>1.7</maven.compiler.source>
    <maven.compiler.target>1.7</maven.compiler.target>
  </properties>
<!--项目依赖-->
  <dependencies>
<!--    具体依赖的jar包配置文件-->
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
<!--构建项目用的东西-->
  <build>
  </build>
</project>

导入jar包

maven由于它的约定大于配置,我们之后可能遇到我们写的配置文件,无法被导出或者生效的问题。

解决方案:

在build中配置resources,来防止我们资源导出失败的问题。

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

5.11 IDEA操作

1、maven仓库的使用

地址:

在maven目录的lib下找到这两个jar包,在地址中去搜索(搜索到的:一般用人数使用最多的那个)

 6、Servlet

写servlet前简单说下Servlet的生命周期。

servlet的生命周期就是从创建到毁灭的过程:

    Servlet 初始化后调用 init () 方法。 Servlet 调用 service() 方法来处理客户端的请求。 Servlet 销毁前调用 destroy() 方法。 最后,Servlet 是由 JVM 的垃圾回收器进行垃圾回收的。

我们目前最新的xml:

<?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"
         metadata-complete="true"> 

</web-app>

6.1 Servlet简介

Servlet就是sun公司开发动态web的一门技术。

Sun在这些API中提供一个接口叫做:Servlet,如果你下开发一个Servlet程序,只需要完成两个小步骤:

1、编写一个类,实现Servlet接口。

2、把开发好的Java类部署到web服务器中。

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

6.2 HelloServlet

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

1、构建一个普通的Maven项目,删掉里面的src目录,我们的学习就在这个项目里面建立Moudel:这个空的工程就是Maven主工程。

2、关于Maven父子工程的理解:

父项目中会有:

<modules>
        <module>servlet-02</module>
    </modules>

子项目中会有:

<parent>
    <artifactId>javaweb-03-maven</artifactId>
    <groupId>org.example</groupId>
    <version>1.0-SNAPSHOT</version>
  </parent>

父项目中的Java子项目可以直接使用:

相当于子项目继承了父项目所有,比如导入的依赖。

3、Maven环境优化

1.修改web.xml为最新标签。

2.将maven的结构搭建完整

4、编写一个Servlet程序

1.编写一个普通类。

2.实现Servlet接口,这里我们直接继承HttpServlet。

public class HelloServlet extends HttpServlet{
    // 由于get,post只是请求实现的不同的方式,可以相互调用,因为业务逻辑都一样。
    @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 {
        doGet(req, resp);
    }
}

5、编写Servlet的映射

为什么需要映射?

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

<!--注册servlet-->
    <servlet>
        <servlet-name>hello</servlet-name>
        <servlet-class>com.lei.servlet.HelloServlet</servlet-class>
    </servlet>
<!--    servlet注册路径(或请求路径)-->
    <servlet-mapping>
        <servlet-name>hello</servlet-name>
        <url-pattern>hello</url-pattern>
    </servlet-mapping>

6、配置Tomcat:

注意:配置项目发布的路径。

7、启动测试。

6.3 Servlet运行原理

Servlet是由web服务器调用,web服务器在接收浏览器请求后会:

6.4 mapping问题

1、1个Servlet可以指定一个映射路径。

<!--    servlet注册路径(或请求路径)-->
    <servlet-mapping>
        <servlet-name>hello</servlet-name>
        <url-pattern>/hello</url-pattern>
    </servlet-mapping>

2、1个Servlet可以指定多个映射路径。

<!--    servlet注册路径(或请求路径)-->
    <servlet-mapping>
        <servlet-name>hello</servlet-name>
        <url-pattern>/hello</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>hello</servlet-name>
        <url-pattern>/hello1</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>hello</servlet-name>
        <url-pattern>/hello2</url-pattern>
    </servlet-mapping>

3、1个Servlet可以指定通用映射路径。

<!--    servlet注册路径(或请求路径)-->
    <servlet-mapping>
        <servlet-name>hello</servlet-name>
        <url-pattern>/hello/*</url-pattern>
    </servlet-mapping>

4、默认请求。

<!--    servlet注册路径(或请求路径)-->
    <servlet-mapping>
        <servlet-name>hello</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>

5、可以指定一些后缀或前缀等等....

<!--    servlet注册路径(或请求路径)-->
    <servlet-mapping>
<!--        注意点:*前面不能加项目映射的路径-->
        <servlet-name>hello</servlet-name>
        <url-pattern>*.zhangsan</url-pattern>
    </servlet-mapping>

6、mapping优先级问题

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

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

6.5 ServletContext

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

    1、共享数据

我在这个Servlet中保存的数据,可以在另一个 Servlet中拿到。

解释:在文件中设置张三的名字,通过GetServlet拿到,并在其中设置编码格式和文本格式,访问hello,通过hello拿到username时,在去访问get,拿到hello结果,和打印出自己的结果。

public class HelloServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

//        this.getInitParameter();   初始化参数
//        this.getServletConfig();   Servlet配置
//        this.getServletContext();   Servlet上下文
        ServletContext context = this.getServletContext();
        String username = "张三";  // 数据
        context.setAttribute("username",username);  // 将一个数据保存在了ServletContext中,名字为:username,值为,username

        System.out.println("hello");
    }
}
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 {

    }
}

配置映射路径:

<servlet>
        <servlet-name>hello</servlet-name>
        <servlet-class>com.lei.servlet.HelloServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>hello</servlet-name>
        <url-pattern>/hello</url-pattern>
    </servlet-mapping>

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

测试访问结果。

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

        String url = context.getInitParameter("url");
        resp.getWriter().print(url);
    }

下面的是重定向过程。

    4、读取项目文件

Properties

1、在Java目录下新建Properties

2、在resources目录下新建Properties

发现:都被打包到了同一个路径下,这个路径就是class路径。我们俗称classpath。

思路:需要一个文件流。

测试返回结果:

通过类来找到文件,获取值。

username=root123123
password=123456asdadas
public class ServletDemo05 extends HelloServlet{

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        InputStream is = this.getServletContext().getResourceAsStream("/WEB-INF/classes/com/lei/servlet/aa.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 {
    }
}

访问测试结果ok。

6.6 HttpServletResponse

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

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

1、简单分类 下载文件

(1)负责向浏览器发送数据的方法。

(2)负责向浏览器发送响应头的方法。

(3)响应的状态码。

2、常见应用

向浏览器输出消息。

下载文件:

1.要获取下载文件的路径。

2.下载的文件名叫什么?

3.设置想办法让浏览器能够支持下载我们需要的东西。

4.获取下载文件的输入流。

5.创建缓冲区。

6.获取OutputStream。

7.将FileOutputStream流写入到buffer缓冲区。

8.使用OutputStream将缓冲区中的数据输出到客户端!

文件下载案例

public class FileServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//        1.要获取下载文件的路径。
        String realPath = "C:\Users\lei\IdeaProjects\javaweb-03-maven\respones\src\main\resources\张三.png";
        System.out.println("下载文件的路径:"+realPath);
//        2.下载的文件名叫什么?
        String fileName = realPath.substring(realPath.lastIndexOf("\") + 1);
//        3.设置想办法让浏览器能够支持下载我们需要的东西。中文文件名,让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();
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

    }
}

3、验证码功能

代码实例(通过映射,进入URL显示结果)

public class ImageServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 如何让浏览器五秒自动刷新一次
        resp.setHeader("refresh","3");

        // 在内存中创建图片
        BufferedImage image = new BufferedImage(80,20,BufferedImage.TYPE_INT_RGB);

        // 得到图片
        Graphics2D g = (Graphics2D)image.getGraphics(); // 笔
        // 设置图片的背景颜色
        g.setColor(Color.cyan);
        g.fillRect(0,0,80,20);
        // 给图片写数据
        g.setColor(Color.black);
        g.setFont(new Font(null,Font.BOLD,20));
        g.drawString(makeNum(),0,20);

        // 告诉浏览器这个请求用图片的方式打开
        resp.setContentType("image/png");
        // 网站存在缓存,不然浏览器缓存
        resp.setDateHeader("expires",1);
        resp.setHeader("Cache-Control","no-cache");
        resp.setHeader("Pragma","no-cache");

        // 把图片写给浏览器
        boolean write = ImageIO.write(image,"jpg", resp.getOutputStream());
    }
    // 生产随机数
    private String makeNum(){
        Random random = new Random();
        String num = random.nextInt(99999999) + "";
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i <7-num.length(); i++) {
            sb.append("0");
        }
        String s = sb.toString() + num;
        return num;
    }

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

    }
}

4、实现重定向

B一个web资源收到A客户端请求后,他会通知A客户端去访问另外一个web资源C,这个过程叫做重定向。

重定向方法:

void sendRedirect(String var1) throws IOException;

原理图:

重定向测试:

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

        resp.sendRedirect("/r/img");
    }

使用重定向的时候可能会404找不到资源问题:

解决404:

resp.sendRedirect(req.getContextPath()+"/index.jsp");  // 404解决方法,找不到路径

相同的一点:

页面都会实现跳转。

不同点:

重定向的时候,url地址栏会发生变化。

6.7 HttpServletRequest

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

一个返回字符串类型,一个返回数组类型。

7、Cookie、Session

7.1 Cookie、Session

Cookie、Session(英文翻译为:小饼干、会话)

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

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

列如:一个网站,怎么证明你来过?

客户端 服务端

1.服务端给客户端一个信件,客户端下次访问服务端带上信件就可以了:cookie

2.服务器知道你来过了,下次你来的时候我来匹配你:session

7.2 保存会话的两种技术

cookie:

客户端技术(响应,请求)

session:

服务器技术,利用这个技术,可以保存用户的会话信息,我们可以把信息或数据放在session中。

常见的:网站登录之后,你下次就不用再登录了,第二次访问直接就登上去了。

可能会遇到的Java错误:

7.3 Cookie

客户端可以使用多个请求,而这些请求都发往服务器,在服务器返回给客户端的时候会带上cookie。

1、从请求中拿到cookie信息。

2、服务器响应给客户端cookie。

用到的方法:

一个网站Cookie是否存在上线?

    一个Cookie只能保存一个信息。 一个web站点可以给浏览器发送多个Cookie,但是最多只能放20个Cookie。 Cookie大小有限制:4kb。 300个Cookie,浏览器上限。

删除Cookie:

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

设置Cookie为0代码:

@Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 创建一个Cookie,名字必须要和删除的名字一致
        Cookie cookie = new Cookie("LastLoginTime",System.currentTimeMillis()+"");
        // Cookie有效期为0
        cookie.setMaxAge(0);
        resp.addCookie(cookie);
    }

7.4 Session

Session用法一:

使用Session:客户端对服务器发送请求的时候,会有一个登记SessionID的,这个ID是唯一的,也是我们用户拿到的,而这个服务器中的Session可以存东西。

什么是Session?

    服务器会给每一个用户(浏览器)创建一个Session对象。 一个Session独占一个浏览器,只要浏览器没有关闭,这个Session就存在。 用户登录之后,整个网站它都可以访问。作用:保存用户的信息。列如:保存blbl的观看记录。

Session和Cookie的区别:

    Cookie是把用户的数据写给用户的浏览器,浏览器保存(可以存多个) Session把用户的数据写道用户独占Session中,服务器保存(保存重要的信息,减少服务器资源的浪费) Session对象由服务器创建

Session使用场景:

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

1. 使用Session:

public class SessionDemo01 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 解决乱码问题
        req.setCharacterEncoding("GBK");
        resp.setCharacterEncoding("GBK");
        resp.setContentType("text/html;charset=utf-8");

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

        // 给session中存东西
        session.setAttribute("name",new Person("张三",18));

        // 获取session的id
        String sessionid = session.getId();

        // 判断session是不是新创建的
        if (session.isNew()){
            resp.getWriter().write("session创建成功,ID为:"+sessionid);
        }else {
            resp.getWriter().write("session已经存在服务器中,ID为:"+sessionid);
        }
    }
}

2. 得到Session:

public class SessionDemo02 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 解决乱码问题
        req.setCharacterEncoding("GBK");
        resp.setCharacterEncoding("GBK");
        resp.setContentType("text/html;charset=utf-8");

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

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

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

    }
}

3. 注销Session:

public class SessionDemo03 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        HttpSession session = req.getSession();
        session.removeAttribute("name");
        // 手动注销Session
        session.invalidate();
    }
}

4. 设置会话自动过期:在web.xml中配置

Session用法二:

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

通过ServletContext对象获取信息。

8、JSP

JSP(全称JavaServer Pages)是由[Sun Microsystems]( Microsystems)公司主导创建的一种标准。

8.1 什么是JSP

JSP(全称JavaServer Pages):Java服务器端页面,也和servlet一样,用于动态web技术。

最大的特点:

    写JSP就像在写HTML

与HTML的区别:

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

8.2 JSP原理

思路:JSP到底怎么执行的

    代码层面没有任何问题。 服务器内部工作: tomcat中只有一个work目录。 IDEA中使用Tomcat的会在IDEA的tomcat中生产一个work目录。

JSP:

我的电脑地址:C:Users用户Desktopjavaapache-tomcat-10.0.14workCatalinalocalhostROOTorgapachejsp

会发现页面转变成了Java程序。

JSP原理:浏览器向服务器发送请求,不管访问什么资源,其实都是在访问Servlet

JSP最终也会被转化成一个Java类。

JSP本质上就是一个Servlet。

源码方法:

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

JSP原理图:

在JSP页面中:

只要是Java代码就会原封不动的输出。

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

out.write("</html>
");

这样的格式,输出到前端。

8.3 JSP基础语法

任何语言都有自己的语法,Java中有,JSP作为Java技术的一种应用,它有自己的扩充的语法。Java所有语法都支持。

EL表达式:${ }

作用:

1、获取数据

2、执行运算

3、获取web开发的常用对象

<%--使用EL表达式输出 ${}--%>
<h1>取出的值为:</h1>
<h3>${name1}</h3>
<h3>${name2}</h3>
<h3>${name3}</h3>
<h3>${name4}</h3>
<h3>${name5}</h3>

JSP表达式

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

jsp脚本片段

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

脚本片段的再实现

jsp声明

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

    private int globalVal = 0;
    public void lei(){
        System.out.println("进入了方法lei!");

    }
%>

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

在JSP,嵌入Java代码即可!

注释:

JSP的注释不会在客户端显示。

HTML的注释会在客户端显示。

JSP指令

拼接前端页面:

8.4 JSP九大内置对象

PageContext 作用:存东西

Request 作用:存东西

Response

Session 作用:存东西

Application [ ServletContext ] 作用:存东西

config [ ServletConfig ]

out

page

exception

存信息的四大内置对象:

pageContext.setAttribute("name1","张三1号"):

保存的数据只在一个页面中有效。

request.setAttribute("name2","张三2号"):

session.setAttribute("name3","张三3号"):

保存的数据只在一次会话中有效,从打开浏览器到关闭浏览器。 application.setAttribute("name4","张三4号"):

保存的数据只在服务器中有效,从打开服务器到关闭服务器。

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

使用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>

jsp标签:

JSTL表达式

使用前需要导入核心标签:

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

具体使用:

JSTL核心标签:

(1)<c:set方法代码实例:

<body>

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

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

(2)<c:foreach方法代码实例 :

<body>

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

<%--
    var:每一次遍历出来的变量
    items:要遍历的对象
    begin:从哪个下标开始
    end:到哪个下标结束
    step:步长,一次走几个元素
--%>
<c:forEach var="people" items="${list}">
    <c:out value="${people}"></c:out> <br>
</c:forEach>

</body>

JSTL标签库:

JSTL标签使用步骤:

1、引入对应的taglib核心标签。

2、使用其中的方法。

3、在tomcat中也需要导入jstl的包,否则会报错,jstl解析错误。

可能出现的问题:

在使用jstl核心标签的时候显示500错误。

解决方案,把jstl.jar包导入到tomcat当前版本的lib目录下,以及standard.jar包也用同样的方式导入到lib目录下。

9、JavaBean

它是一个实体类:

JavaBean有特定的写法:

    必须要有一个无参构造 属性必须私有化 必须有对应的get/set方法

它一般用来和数据库的字段做映射 ODM:

ORM:对象关系映射

sql表对应Java类

sql字段对应Java属性

sql行记录对应Java对象

10、MVC三层架构

经典MVC模式中,M是指业务模型,V是指用户界面,C则是控制器,使用MVC的目的是将M和V的实现分离,从而使同一个程序可以使用不同的表现形式。其中,View的定义比较清晰,就是用户界面。

什么是MVC:Model view Contorller 模型、视图、控制器

原理图:

用户直接访问控制层,可支持就可以直接操作数据库:

MVC这三层的作用:

Model:

1、业务处理:业务逻辑(Service)

2、数据持久化:CRUD(Dao)

view:

1、展示数据

2、提供链接发起Servlet请求(像css中的:a...form...img.....)

Controller:

1、接收用户的请求:(比如:req:请求参数、Session信息..)

2、交给业务层处理对应的代码

3、控制视图的跳转

具体流程:

用户登录-->接收用户的登录请求-->处理用户的请求-->交给业务层处理登录业务-->Dao层查询用户名和密码是否正确-->查询数据库

11、Filter过滤器

1. 我对过滤器的理解:

过滤器本质上是过滤一些没必要出现的数据,比起servlet,过滤器本身出现的场景更加方便。

比如:我要过滤到用户登录的信息,我可以在过滤器中加入,在用户登录的时候的字符编码格式统一,用户是否登录输入不能为空。相比于servlet,因为servlet实现这个作用也可以,但是要实现这些作用,一定要在每个servlet中写上这些判断,才能使用。而过滤器这时候就可以方便我们写下这些能作用的代码,将所有servlet下的类都过滤一遍,就不需要一次次的去servlet中写了。

2. 过滤器测试的代码:

路径原理:在web.xml中去走路径,在走路径的时候要去,pom中去寻找映射路径,找到在pom中的servlet路径,但找到servlet路径的时候,如果这时候有filter,那么就先走filter的路径,因为filter权限更高,在寻找完后,在走向servlet路径,最后实现。

<filter>
        <filter-name>CharacterEncodingFilter</filter-name>
        <filter-class>com.lei.filter.CharacterEncodingFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>CharacterEncodingFilter</filter-name>
        <!--所有路径都都拦截,走这个过滤器-->
        <url-pattern>/*</url-pattern>
    </filter-mapping>


    <filter>
        <filter-name>SysFilter</filter-name>
        <filter-class>com.lei.filter.SysFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>SysFilter</filter-name>
        <!--只要是/servlet下的所有请求都会经过这个过滤器-->
        <url-pattern>/auisdfulsgaduf/*</url-pattern>
    </filter-mapping>

3. 过滤器的作用:用来过滤网站的数据

一般用来:

1、处理中文乱码

2、登录验证

概念图:

4. Filter:开发步骤

1、导包

在pom.xml里面导入需要的依赖。

2、编写过滤器:

主要步骤:

编写过滤器代码:

public class CharacterEncodingFilter implements Filter {
    // 初始化:web服务器启动的时候就初始化了。
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("CharacterEncodingFilter初始化");
    }
    
    // chain:链
    // 1、过滤中的所有代码,在过滤特定请求的时候都会执行,随时等待过滤对象
    // 2、必须要让过滤器继续通行    chain.doFilter(request,response);
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        request.setCharacterEncoding("gbk");
        response.setCharacterEncoding("gbk");
        response.setContentType("text/html;charset=utf-8");

        System.out.println("CharacterEncodingFilter执行前...");
        chain.doFilter(request,response);// 让我们的请求继续走,如果不写,我们的程序到这里就会拦截停止
        System.out.println("CharacterEncodingFilter执行后...");
    }
    // 销毁
    @Override
    public void destroy() {
        System.out.println("CharacterEncodingFilter销毁");

    }
}

注意点:编写过滤器的时候导入的包是javax.servlet包Filter。

3、实现Filter接口,重写对应的方法即可。

4、在web.xml中配置Filter过滤器

<filter>
        <filter-name>CharacterEncodingFilter</filter-name>
        <filter-class>com.lei.filter.CharacterEncodingFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>CharacterEncodingFilter</filter-name>
        <!--只要是/servlet下的所有请求都会经过这个过滤器-->
        <url-pattern>/servlet/*</url-pattern>
    </filter-mapping>

12、监听器

实现一个监听器效果:

1、编写一个监听器。

2、实现监听器的接口。

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

    // 创建session监听
    // 一但创建一个session就会触发一次事件
    @Override
    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就会触发一次事件
    @Override
    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、手动销毁        se.getSession().invalidate();
    // 2、自动销毁

}

自动销毁Session实现:

在xml中设置Session销毁时间为一分钟即可。

<session-config>
        <session-timeout>1</session-timeout>
    </session-config>

3、web.xml中注册监听器

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

监听作用及实现场景:

列如:监听用户登录和下线的情况。

13、JDBC复习

概述:我们选用不同数据库的时候,连接会有不同的代码和驱动,这时候我们连接不同的数据库就要去区分不同数据库的代码,而解决的方案就是,在数据库上面在加上一层JDBC,让JDBC来处理连接不同数据库的这些事情,这样就很方便了。让不同数据库的代码,就走不同的数据库。

比如:我们学习的MySQL、Oracle。

复习JDBC:

六大步骤

1、配置数据库

2、加载驱动

3、连接数据库

4、向数据库发送sql的对象statement ,进行CURD

5、编写sql

6、关闭释放

package com.lei.test;

import java.sql.*;

public class TestJdbc {
    public static void main(String[] args) throws ClassNotFoundException, SQLException {

        // 配置数据库
        // 防止中文乱码useUnicode=true&characterEncoding=UTF-8
        String url = "jdbc:mysql://localhost:3306/user?useSSL=false&serverTimezone=Hongkong&characterEncoding=utf-8&autoReconnect=true";
        String username = "root";
        String password = "123456";

        // 加载驱动
        Class.forName("com.mysql.jdbc.Driver");
        // 连接数据库  connection代表数据库了
        Connection connection = DriverManager.getConnection(url, username, password);
        // 向数据库发送sql的对象Statement,进行CRUD
        Statement statement = connection.createStatement();
        // 编写sql
        String sql = "select * from user;";
        // 执行查询sql,返回一个resultSet结果集
        ResultSet resultSet = statement.executeQuery(sql);
        while (resultSet.next()){
            System.out.println("id="+resultSet.getObject("id"));
            System.out.println("name="+resultSet.getObject("name"));
            System.out.println("password="+resultSet.getObject("password"));
            System.out.println("email="+resultSet.getObject("email"));
            System.out.println("birthday="+resultSet.getObject("birthday"));
        }
        // 关闭连接,释放资源
        resultSet.close();
        statement.close();
        connection.close();


    }
}

试试预编译sql(prepareStatement)因为它比较安全:

JDBC事务:

connection.setAutoCommit(false); // 关闭自动提交
                        // 编写sQL
            String sql = "update test set money = money-100 where id =1";
            connection.prepareStatement(sql).executeUpdate(); // 执行更新
                        // 提交事务
            connection.commit();// 提交
            System.out.println("success");
            // 如果错误就回滚
            catch (SQLException e) {           
                connection.rollback();// 回滚         
                ex.printStackTrace();
            }            
            connection.close();// 关闭,释放资源

junit单元测试导入的包

<dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>

这个注解的作用:只要加了这个注解就可以不用写main方法了,就可以直接运行。

import org.junit.Test;  // 需要导入的包
   
   
    @Test  // 注解
    public void tedt(){
        System.out.println("你好呀!");
    }
经验分享 程序员 微信小程序 职场和发展