天天看点

JavaWeb

JavaWeb

java web

1、基本概念

1.1前言

web开发:

  • web,网页的意思 ,www.baidu.com
  • 静态web
    • html css
    • 提供给所有人看的数据始终不会发生变化!
  • 动态web
    • 提供给所有人看的数据始终会发生变化!每个人在不同时间不同地点看到的东西,各不相同。-
    • 淘宝 ,几乎所有的网站
    • 技术栈:servlet/JSP ASP PHP

在java中,动态资源开发的技术统称为Javaweb;

1.2web应用程序

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

  • a.html b.html....多个web资源,这些web资源可以被外界访问,对外界提供服务
  • 你们能访问到的任何一个页面或者资源,都存在于这个世界的某一个角落的计算机上
  • URL
  • 这个统一的web资源会被放在同一个文件夹下,web应用程序-->Tomcat:服务器
  • 一个web应用由多部分组成(静态web、动态web)
    • 。html, CSS, is
    • jsp, senvlet
    • Java程序
    • jar包
    • 配置文件(Properties)

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

1.3静态web

  • *.htm *html 这些都是网页的后缀,如果服务器上一直存在这些东西,我们就可以直接进行读取。
    JavaWeb
  • 静态web存在的缺点
    • web页面无法动态更新,所有用户看到的都是同一个页面
      • 轮播图,点击特效:微动态
      • JavaScript[实际开发中,他用的最多]
      • VBScript
    • 他无法与数据库交互(数据无法持久化,用户无法交互)

1.4动态web

页面回动态展示:“Web展示的效果因人而异”;

JavaWeb

缺点

  • 假如服务器的动态web资源出现了错误,我们需要重新编写我们的后台程序,重新发布;
    • 停机维护

优点:

  • web页面可以动态更新,所有用户看到的都不是同一个页面
  • 他可以与数据库交互(数据无法持久化,用户无法交互)
JavaWeb

2、web服务器

2.1技术讲解

ASP

  • 微软:国内最早流行的就是ASP
  • 在HTML中嵌入了VB的脚本,ASP + COM;
  • 在ASP开发中,基本上一个页面都有几千行的业务代码,页面机器混乱
    <h1>
        <h1>
            <h1>
                <% 
                   System.out.println("hello")
                %>
            </h1>
        </h1>
    </h1>
               
  • 维护成本高
  • c#

php

  • PHP开发速度很快,功能强大,跨平台,代码很简单(70%)
  • 无法承载大访问量的情况(局限性)

JSP(servlet):

  • sun公司主推的B/S架构
  • 基于java语言(所有的大公司,或者一些开源的组件都是用java写的)
  • 可以承载三高(高并发,高可用,高性能)带来的影响
  • 语法像ASP,方便让ASP转JSP,加强市场强度;

2.2 web服务器

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

lls

微软的;ASP...Windows中自带的

tomcat

面向百度编程

Tomcat是Apache 软件基金会(Apache Software Foundation)的Jakarta 项目中的一个核心项目,由Apache、Sun 和其他一些公司及个人共同开发而成。由于有了Sun 的参与和支持,最新的Servlet 和JSP 规范总是能在Tomcat 中得到体现,Tomcat 5支持最新的Servlet 2.4 和JSP 2.0 规范。因为Tomcat 技术先进、性能稳定,而且免费,因而深受Java 爱好者的喜爱并得到了部分软件开发商的认可,成为目前比较流行的Web 应用服务器。

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

Tomcat 实际上运行JSP 页面和Servlet。

......

工作3-5年之后,可以尝试手写tomcat

下载tomcat:

  1. 安装or解压
  2. 了解配置文件及目录结构
  3. 这个东西的作用

3、Tomcat

3.1安装tomcat

tomcat官网 :https://tomcat.apache.org/download-10.cgi

JavaWeb

解压安装

3.2Tomcat 启动和配置

文件夹作用:

JavaWeb

启动tomcat

JavaWeb

可能遇到的问题:

这里发现我之前电脑中有,所以删掉了原来的重新配置

JavaWeb

注意:要根据自己的JDK版本选择Tomcat的版本。

JavaWeb

新建系统环境变量:

CATALINA_HOME:D:\soft\apache-tomcat-10.0.10
           

在path中添加

%CATALINA_HOME%\bin;
           
JavaWeb

本文的解决方法是刚安装好tomcat后就无法正常运行的情况。不涉及项目

安装tomcat有两种方式,一个是解压缩版本,一个是安装版,当出现这个问题时一般为解压缩版本才出现

提示错误如下:localhost:8080 java.lang.IllegalStateException: No output folder

原因:没有读写的权限

解决方案:找到你tomcat的目录,右键“属性--->安全--->编辑”,找到Users,将“完全控制”选项“允许”打钩,应用。

然后http://localhost:8080/,这样就可以了。

JavaWeb

3.3配置

JavaWeb

可以配置启动的端口号

  • tomcat的默认端口号为: 8080
  • mysql: 3306
  • http: 80
  • https: 443
<Connector port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" />
           

可以配置主机的名称,或者访问的文件夹webapps

<Host name="localhost"  appBase="webapps"
            unpackWARs="true" autoDeploy="true">
           
  • 默认的主机名为:localhost-> 127.0.0.0
  • 默认网站应用的存放位置:webapps
  • 如果要改localhost还需要去C:\Windows\System32\drivers\etc这个文件夹下写一下
JavaWeb

高难度面试题:

请你谈谈网站是如何进行访问的!

  1. 输入一个域名;回车
  2. 检查本机的C:\Windows\System32\drivers\etc\hosts配置文件下有没有被这个域名映射;

    1.有:直接返回对应的ip地址,这个地址中,有我们需要访问的web程序,所以可以直接访问

    127.0.0.1 				www.qinjiang.com
               
    2.没有:去DNS服务器,找到就返回
    JavaWeb

3.4发布一个web网站

不会就先模仿

  • 将自己写的网站,放到服务器tomcat中指定的web 应用的文件夹(webapps)

网站应该有的结构

--webapps: tomcat服务器的web目录
   --root 
   --kuangstudy :网站的目录名
     - WEB-INF
    	-classes:java程序
    	-lib:web应用所依赖的jar包
    	-web.xml
  	 -index.html默认的首页
     - static
    	-css
    		-style.css
     	-js	
    	-image
     -......
           

4、http

4.1什么是http

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

  • 文本:html,字符串,...
  • 超文本:图片,音乐,视频,定位,地图......
  • 默认端口 80

Https:安全的

  • 端口443

4.2两个时代

  • http1.0
    • http/1.0:客户端可以与web服务器连接后,只能获得一个web资源,断开连接
  • http 2.0
    • http/1.1:客户端可以与web服务器连接后,只能获得多个web资源

4.3http请求

  • 客户端 -- 发请求--服务器

百度:

Request URL: https://www.baidu.com 请求地址
Request Method: GET get和post方法
Status Code: 200 OK (from memory cache)  状态码
Remote Address: 110.242.68.4:443 远程地址
           

1、请求行

  • 请求行中的请求方式:get
  • 请求方式get/post,head,delete,put
    • get :请求能够携带的参数比较少,大小有限制,会在浏览器的URL地址栏显示数据内容,不安全,但高效
    • post :请求能够携带的参数没有限制,大小没有限制,不会在浏览器的URL地址栏显示数据内容,安全,但不高效

2、请求头

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

4.4http响应

  • 服务器 -- 发请求--客户端

百度:

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

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包,我们手动去导入
  2. 如何能够让一个东西帮我们导入和配置这个jar包

    由此,maven诞生了!

5.1maven项目架构管理工具

目前 用来就是方便导入jar包的!

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

  • 有约束,不要去违反

maven会规定你该如何编写我们的java代码,必须按照这个规范来

5.2下载Maven

官网:https://maven.apache.org/download.cgi

5.3配置环境变量

在我们的系统环境变量中

配置如下配置:

  • M2_HOME maven目录下的bin目录
  • MAVEN_HOME maven的目录
  • 在系统的path中配置%MAVEN _HOME%\bin
JavaWeb

测试maven是否安装成功,保证必须配置完毕!

5.4阿里云镜像

  • 镜像: mirrors
    • 作用:由于国外的镜像比较慢,为了加速我们的下载
  • 国内建议使用阿里云的镜像
    <mirror>
        <id>nexus-aliyun</id>
        <mirrorOf>*,!jeecg,!jeecg-snapshots</mirrorOf>
        <name>Nexus aliyun</name>    <url>http://maven.aliyun.com/nexus/content/groups/public</url> 
    </mirror>
               
    shift + tab 格式化代码

5.5本地仓库

在本地的仓库,远程仓库;

默认的本地仓库

JavaWeb

建立一个仓库:localRepository,在conf/settings文件下添加

JavaWeb
<localRepository>D:\soft\apache-maven-3.6.3\maven-repo</localRepository>
           

5.6在idea中使用maven

  1. 启动idea
  2. 创建一个mavenWeb项目
  3. JavaWeb
  4. JavaWeb
JavaWeb

这时候idea 创建maven项目报错: Failed to create parent directories for tracking file,我到了D盘的maven那个文件给它完全控制权限

然后重新载入,发现正在下载

JavaWeb
  1. 观察maven仓库中多了什么东西?
    JavaWeb
  2. idea中的maven,idea项目创建成功后,看一眼配置
    JavaWeb
    JavaWeb
    ​ 到这里,maven在idea中的配置和使用就OK了

    5.7创建一个普通的maven项目

JavaWeb
JavaWeb
JavaWeb

这个只有在web应用下才会有!

5.8标记文件夹功能

JavaWeb

新建java文件夹,将其设置为源码目录

JavaWeb

同时新建resources目录,将其设置为资源目录

JavaWeb
JavaWeb
JavaWeb
JavaWeb

5.9在idea中配置tomcat

JavaWeb
JavaWeb
JavaWeb
JavaWeb

解决警告问题

为什么会有这个问题?我们访问一个网站,需要指定一个文件夹名字

JavaWeb
JavaWeb
JavaWeb
JavaWeb

5.10pom文件

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

JavaWeb
<?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>com.kuang</groupId>
  <artifactId>javaweb-01-maven</artifactId>
  <version>1.0-SNAPSHOT</version>
<!--  package项目的打包方式
    jar :java应用
    war:javaweb应用
-->
  <packaging>war</packaging>

<!--配置-->
  <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>

    </dependency>
  </dependencies>
<!--项目构建用的东西-->
  <build>
    <finalName>javaweb-01-maven</finalName>
    <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
      <plugins>
        <plugin>
          <artifactId>maven-clean-plugin</artifactId>
          <version>3.1.0</version>
        </plugin>
        <!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_war_packaging -->
        <plugin>
          <artifactId>maven-resources-plugin</artifactId>
          <version>3.0.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-compiler-plugin</artifactId>
          <version>3.8.0</version>
        </plugin>
        <plugin>
          <artifactId>maven-surefire-plugin</artifactId>
          <version>2.22.1</version>
        </plugin>
        <plugin>
          <artifactId>maven-war-plugin</artifactId>
          <version>3.2.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-install-plugin</artifactId>
          <version>2.5.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-deploy-plugin</artifactId>
          <version>2.8.2</version>
        </plugin>
      </plugins>
    </pluginManagement>
  </build>
</project>

           
<?xml version="1.0" encoding="UTF-8"?>
<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>

    <groupId>com.kuang</groupId>
    <artifactId>javaweb-01-maven02</artifactId>
    <version>1.0-SNAPSHOT</version>
    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.11</version>

        </dependency>
<!-- maven的高级之处在于,他会帮你导入这个jar包所依赖的其他jar-->
        <!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.3.9</version>
        </dependency>

    </dependencies>

</project>
           
JavaWeb

依赖如果爆红的话

后经排查问题出在新建工程后maven本地仓库自动设置为了默认.m2\repository仓库,如果自己在配置maven时更改过本地仓库,要再次在设置里更改为修改后的本地仓库地址。

maven由于他的约定大于配置,我们之后可能会遇到我们写的配置文件,无法被导出或者生效的问题,解决方案:

<!--    在build中配置resources,来防止我们资源导出的问题-->
<build>
    <resources>
        <resource>
            <directory>src/main/java</directory>
            <includes>
                <include>**/*.properties</include>
                <include>**/*.xml</include>
            </includes>
            <filtering>false</filtering>
        </resource>
        <resource>
            <!--                让src/main/java可以包含.properties、.xml文件-->
            <directory>src/main/resources</directory>
            <includes>
                <include>**/*.properties</include>
                <include>**/*.xml</include>
            </includes>
            <filtering>false</filtering>
        </resource>
    </resources>
</build>

           

5.11目录树

JavaWeb

5.12解决遇到的问题

  1. Maven 3.6.2

    Unable to import maven project: See logs for details

解决方法:降级为3.6.1

JavaWeb
JavaWeb
  1. tomcat闪退
JavaWeb
  1. idea中每次都要配置maven

在idea中的启动页面(如果不是点击close project跳转到这个页面)

或者1.打开Settings for New Projects窗口

​ File > Other Settings > Settings for New Projects...

JavaWeb

2.设置maven的安装路径(maven home directory、user settings file、local repository)

注意这个标题不是Settings,而是Settings for New Projects

JavaWeb
  1. maven项目中tomcat无法配置
  2. maven中默认的web项目中的web.xml版本问题
    JavaWeb
    JavaWeb
    <?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>
    
               
    1. maven 仓库的使用

      地址:https://mvnrepository.com/

tomcat10有些bug所以我又换回了9

更改的时候只需要更改环境变量里面的

CATALINA_HOME:D:\soft\apache-tomcat-9.0.52
           

并且需要给apache-tomcat-9.0.52这个文件完全控制权限,要不然会报错500

然后将tomcat10的那个删除重建一个

JavaWeb

6、servlet

6.1servlet简介

  • servlet就是sun公司用于开发动态web的一门技术
  • sun公司在这些api中提供了一个接口叫做:servlet,如果你想要开发一个Servlet程序,只需要完成两个小步骤
    • 编写一个类,实现Servlet接口
    • 把开发好的java类部署到web服务器中

把实现了Servlet接口的java程序叫做servlet

6.2HelloServlet

servlet接口在sun公司有两个默认的实现类HttpServlet ,GenericServlet

  1. 构建一个普通Maven项目,删掉里面的src,以后我们的学习就在这个项目里面建立Model,这个空的工程就是maven的主工程
  2. 关于maven父子关系的理解

    父项目中pom文件中会有一个

    <modules>
        <module>servlet-01</module>
    </modules>
               
    子项目中会有
    <parent>
    <artifactId>javaweb-02-servlet</artifactId>
    <groupId>com.kuang</groupId>
    <version>1.0-SNAPSHOT</version>
    </parent>
               
    父项目的java子项目可以直接使用
    son extends father
               
  3. Maven环境优化

    1.修改web.xml为最新的

    2.将maven的结构搭建完整

  4. 编写一个servlet程序

    1.编写一个普通类

    2.实现servlet接口

    JavaWeb
    package com.kuang.servlet;
    
    import javax.servlet.ServletException;
    import javax.servlet.ServletOutputStream;
    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 HelloServlet extends HttpServlet {
        //由于get或者post只是请求实现不同的方式,可以相互调用,因为业务逻辑都一样
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            //        ServletOutputStream outputStream = resp.getOutputStream();
            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>helloServlet</servlet-name>
        <servlet-class>com.kuang.servlet.HelloServlet</servlet-class>
    </servlet>
    <!--    servlet的请求路径-->
    <servlet-mapping>
        <servlet-name>helloServlet</servlet-name>
        <url-pattern>/hello</url-pattern>
    </servlet-mapping>
               

    6.配置tomcat

    点击run 里面的edit configuration

    JavaWeb
    JavaWeb
  5. 启动测试

    报一个错:

    JavaWeb
    JavaWeb
    重新选择显示配置
    JavaWeb
    JavaWeb

6.3 、Servlet原理

servlet是由web服务器调用,web服务器在收到浏览器请求之后会

JavaWeb

6.4Mapping

  1. 一个servlet可以指定一个映射路径
    <!--    servlet的请求路径-->
    <servlet-mapping>
        <servlet-name>helloServlet</servlet-name>
        <url-pattern>/hello</url-pattern>
    </servlet-mapping>
               
  2. 一个servlet可以指定多个映射路径
    <servlet-mapping>
            <servlet-name>helloServlet</servlet-name>
            <url-pattern>/hello</url-pattern>
        </servlet-mapping>
        <servlet-mapping>
            <servlet-name>helloServlet</servlet-name>
            <url-pattern>/hello2</url-pattern>
        </servlet-mapping>
        <servlet-mapping>
            <servlet-name>helloServlet</servlet-name>
            <url-pattern>/hello3</url-pattern>
        </servlet-mapping>
        <servlet-mapping>
            <servlet-name>helloServlet</servlet-name>
            <url-pattern>/hello4</url-pattern>
        </servlet-mapping>
               
  3. 一个servlet可以指定通用映射路径
    <servlet-mapping>
        <servlet-name>helloServlet</servlet-name>
        <url-pattern>/hello/*</url-pattern>
    </servlet-mapping>
               
    JavaWeb
  4. 默认请求路径

    什么都不写,他会比index.html优先级高

    <servlet-mapping>
        <servlet-name>helloServlet</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>
               
    JavaWeb
  5. 指定一些后缀或者前缀等等...
    <!--    可以自定义后缀实现请求映射
    注意点.*前面不能加项目映射的路径
    hello/sjnjavnaskfn.qinjiang -->
        <servlet-mapping>
            <servlet-name>helloServlet</servlet-name>
            <url-pattern>*.qinjiang</url-pattern>
        </servlet-mapping>
               
    JavaWeb
  6. 优先级问题

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

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

6.5

JavaWeb
JavaWeb

然后新建了servlet2出现了ignore pom

JavaWeb

由于相同名称的module在之前被创建过,因此在IDEA中留有痕迹。重新创建一个新的同名module会让IDEA误以为是之前被删除掉的module,所以才自动将这个pom.xml文件忽略了。

解决方案:

1. 点击file > Setting进入设置

JavaWeb

2. 找到lgnored file,把右边已选中的选项取消勾选,然后点击 ok

JavaWeb

3. 建议再点击右上角Maven中的刷新一下,这样pom.xml 文件就被变回来了

JavaWeb

输出乱码:

JavaWeb

这种情况是tomcat的日志配置文件的编码需要修改,找到tomcat安装目录,找到conf下的logging.properties文件,将其中的encoding = UTF-8的部分全部修改为encoding = GBK,如图:

JavaWeb

修改之后保存重启题目cat

JavaWeb

6.5servletContext

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

1.共享数据

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

JavaWeb

先存再取,先set后get

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
    }

}

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

    }
}

           
<?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">
    <servlet>
        <servlet-name>hello</servlet-name>
        <servlet-class>com.kuang.servlet.HelloServlet</servlet-class>
        <!--        <init-param>-->
        <!--            <param-name></param-name>-->
        <!--            <param-value></param-value>-->
        <!--        </init-param>-->
    </servlet>
    <servlet-mapping>
        <servlet-name>hello</servlet-name>
        <url-pattern>/hello</url-pattern>
    </servlet-mapping>
    <servlet>
        <servlet-name>getc</servlet-name>
        <servlet-class>com.kuang.servlet.GetServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>getc</servlet-name>
        <url-pattern>/getc</url-pattern>
    </servlet-mapping>
</web-app>
           

测试访问结果:

先输入http://localhost:8080/servlet_02_war/hello

再输入http://localhost:8080/servlet_02_war/getc

JavaWeb

2.获取初始化参数

<!--    配置web应用的初始化参数-->
<context-param>
    <param-name>url</param-name>
    <param-value>jdbc::mysql://localhost:3306/mybatis/param-value</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);

}
           

3.请求转发

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    System.out.println("进入了servletDemo04");
    ServletContext context = this.getServletContext();
    //        RequestDispatcher requestDispatcher = context.getRequestDispatcher("/gp");//转发的请求路径
    //        requestDispatcher.forward(req,resp);//调用forward实现请求转发
    context.getRequestDispatcher("/gp").forward(req,resp);
}
           
<servlet>
    <servlet-name>sd4</servlet-name>
    <servlet-class>com.kuang.servlet.ServletDemo04</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>sd4</servlet-name>
    <url-pattern>/sd4</url-pattern>
</servlet-mapping>
           

4.读取资源文件

properties

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

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

思路:需要一个文件流

username = root12345
password = 123456121123213
           
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");
        InputStream is = this.getServletContext().getResourceAsStream("/WEB-INF/classes/com/kuang/servlet/aaa.properties");
        Properties prop = new Properties();
        prop.load(is);
        String user= prop.getProperty("username");
        String pwd = prop.getProperty("password");
        resp.getWriter().print(user+":"+pwd);
    }
}
           

访问测试即可

JavaWeb

6.6HttpServletResponse

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

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

1.简单分类

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

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

负责向浏览器发送响应头的方法

//extends ServletResponse
void setCharacterEncoding(String var1);

void setContentLength(int var1);

void setContentLengthLong(long var1);

void setContentType(String var1);
//HttpServletResponse
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;
           

2.常见应用

  1. 向浏览器输出消息(一直在讲,就不说了)
  2. 下载文件
    1. 要获取下载文件的路径
    2. 下载的文件名是啥?
    3. 设置想办法让浏览器能够支持下载我们需要的东西
    4. 获取下载文件的输入流
    5. 创建缓冲区
    6. 获取OutPutStream对象
    7. 将FileOutPutStream流写入到buffer缓冲区
    8. 使用 OutPutStream将缓冲区中的数据输出到客户端
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //  1. 要获取下载文件的路径
        //        D:\soft\apache-tomcat-9.0.52\webapps\response_war\1.png
    
        //        D:\山建\大二下暑假\软赛\javaweb-02-servlet\response\target\classes\1.png
        String realPath = "D:\\山建\\大二下暑假\\软赛\\javaweb-02-servlet\\response\\target\\classes\\秦疆.png";
        //        String realPath = this.getServletContext().getRealPath("/1.png");
        System.out.println("下载文件的路径:"+realPath);
        //  2. 下载的文件名是啥?
        /*
            * 就是取一个文件完整路径中的文件名,譬如 D:\img\abc.jpg,我们要得到abc.jpg.
               如果不+1,得到的就包括\本身,成了 \abc.jpg
               * str.LastIndexOf("\\")--最后一个\的位置
            * */
        String fileName = realPath.substring(realPath.lastIndexOf("\\") + 1);
        //  3. 设置想办法让浏览器能够支持下载(Content-Disposition)我们需要的东西
        /*Content-Disposition 就是当用户想把请求所得的内容存为一个文件的时候提供一个默认的文件名。
            Content-Disposition: attachment; filename="filename.jpg"*/
        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();
    
    }
               

3.验证码功能

验证怎么来的?

  • 前端实现
  • 后端实现,需要用到java的图片类,生成一个图片
public class ImageServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //如何让浏览器3秒自动刷新一次
        resp.setHeader("refresh","3s");
        //在内存中创建一个图片
        BufferedImage image = new BufferedImage(80,20,BufferedImage.TYPE_INT_RGB);
        //得到图片
        Graphics2D g = (Graphics2D) image.getGraphics();//笔
        //设置图片的背景颜色
        g.setColor(Color.white);
        g.fillRect(0,0,80,20);
        //给图片写数据
        g.setColor(Color.BLUE);
        g.setFont(new Font(null,Font.BOLD,20));
        g.drawString(makeNumber(),0,20);
        //告诉浏览器这个请求用图片的 方式打开
        resp.setContentType("image/jepg");
        //网站存在缓存,不让浏览器缓存
        resp.setDateHeader("expires",-1);
        resp.setHeader("Cache-Control","no-cache");
        resp.setHeader("Pragma","no-cache");
        //把图片写给浏览器
        ImageIO.write(image,"jpg",resp.getOutputStream());

    }
    //生成随机数
    private String makeNumber(){
        Random random = new Random();
        String num = random.nextInt(9999999)/*生成一个7位的随机数*/+"";
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < 7-num.length(); i++) {
            sb.append("0");
        }
        //下面这句话的意思是,如果生成不到7位数的话剩下的字符用0去填充
        num = sb.toString()+num;
        return num;//这样能保证他必定是7位数

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

           

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

JavaWeb

常见场景:

  • 用户登录
void sendRedirect(String var1) throws IOException;
           

测试:

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    /*
        * resp.setHeader("Location","/r/img");
           resp.setStatus(302);
        * */
    resp.sendRedirect("/response_war/img");//重定向
}
           

面试题:请你聊聊重定向和转发的区别?

相同点:

  • 页面都会跳转

不同点

  • 请求转发的时候,url不会产生变化
  • 重定向时候,url地址栏会发生变化
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);
        resp.sendRedirect("/response_war/success.jsp");
        //重定向时候一定要注意路径问题,否则就会404
        System.out.println("进入这个请求");
    }

           
<servlet>
    <servlet-name>request</servlet-name>
    <servlet-class>com.kuang.servlet.RequestTest</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>request</servlet-name>
    <url-pattern>/login</url-pattern>
</servlet-mapping>
           
<html>
    <body>
        <h2>Hello World!</h2>
        <%--这里提交的路径旭=需要寻找到项目的路径--%>
        <%--{pageContext.request.contextPath}代表当前项目--%>
        <form action="${pageContext.request.contextPath}/login" method="get">
            用户名:<input type="text" name = "username">
            密码:<input type="password" name = "password">
            <input type="submit">
        </form>
    </body>
</html>
           
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
    <head>
        <title>Title</title>
    </head>
    <body>
        <h1>success</h1>
    </body>
</html>

           

6.7HttpServletRequest

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

    

JavaWeb
JavaWeb
1、获取前端传递的参数
JavaWeb
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应用的/request_war路径
    req.getRequestDispatcher("/success.jsp").forward(req,resp);

}
           

请求转发不需要项目名,重定向要加

  • 请求转发的时候,url不会产生变化 307
  • 重定向时候,url地址栏会发生变化 302

7 、Cookie 、 Session

7.1会话

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

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

你能怎么证明你是西开的学生?

你 西开

  1. 发票 西开给你发票
  2. 学校登记 西开标记你来过了

一个网站怎么证明你来过?

客户端 服务端

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

7.2保存会话的两种技术

cookie

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

session

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

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

7.3cookie

JavaWeb
  1. 从请求中拿到cookie信息
  2. 服务器响应给客户端cookie
    Cookie[] cookies = req.getCookies();//这里返回数组,说明Cookie可能存在多个
    cookies.getName();//获得cookie中的key
    cookie.getValue();//获得cookie中的value
    new Cookie("lastLoginTime",System.currentTimeMillis()+"");//新建一个cookie
     cookie.setMaxAge(24*60*60);//设置cookie有效期
     resp.addCookie(cookie);//响应给客户瑞一个cookie
               

    cookie:一般会保存在本地的用户目录下面的APPdata

    一个网站的cookie是否存在上限!

  • 一个cookie只能保存一个信息
  • 一个web可以给浏览器发送多个cookie,浏览器大概有300kie,每个站点大概存放20个cookie
  • cookie的大小有限制4kb

删除Cookie;

  • 不设置有效期,关闭浏览器自动失效
  • 设置有效期的时间为0

编码解码:

URLDecoder.decode(cookie.getValue(),"utf-8");
URLEncoder.encode("秦疆","utf-8")
           

7.4Session(重点)

JavaWeb

什么是Session:

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

Session和Cookie的区别

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

使用场景:

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

使用Session

package com.kuang.servlet;

import com.kuang.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 {
//        解决乱码问题
        resp.setCharacterEncoding("UTF-8");
        req.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

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    //        解决乱码问题
    resp.setCharacterEncoding("UTF-8");
    req.setCharacterEncoding("UTF-8");
    resp.setContentType("text/html;charset = utf-8");
    //        得到Session
    HttpSession session = req.getSession();
    Person person = (Person) session.getAttribute("name");
    System.out.println(person.toString());
}
           

手动注销session

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    HttpSession session = req.getSession();
    session.removeAttribute("name");
    session.invalidate();//注销sessionid
}
           

设置session默认的失效时间,会话自动过期

<session-config>
    <!--        1分钟后session自动失效,以分钟为单位-->
    <session-timeout>1</session-timeout>
</session-config>
           

遇到的问题:

JavaWeb

每个浏览器都有自己的session:

JavaWeb

8、JSP

8.1什么是JSP

java server pages : java端页面,也和Servlet一样,用于动态Web技术!

最大的特点:

  • 写jsp就像在写HTML
  • 区别:
    • HTML只给用户提供静态的数据
    • jsp页面中可以嵌入java代码,为用户提供动态数据

8.2JSP原理

思路:jsp到底如何执行的?

  • 代码层面没有任何问题,就类似与HTML的页面代码
  • 服务器内部工作

    tomcat中有一个work目录;

    在idea中使用tomcat的会在idea的tomcat目录中产生一个work目录

    我电脑的地址:

    C:\Users\sgc\AppData\Local\JetBrains\IntelliJIdea2020.2\tomcat\Tomcat_9_javaweb-02-servlet\work\Catalina\localhost\javaweb_session_cookie_war\org\apache\jsp
               
    发现页面转变为了java程序
    JavaWeb

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

    JSP也会被转换成为java类

    我们写的jsp转换为java程序,他手动帮我们做了原来程序员做的一些繁琐的事情,而我们只需要去写简单的HTML页面就可以了

    JavaWeb
    jsp本质就是一个servelet
    JavaWeb
    //初始化
    public void _jspInit() {
    }
    //销毁
    public void _jspDestroy() {
    }
    //JSP的service
    public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response)
               
    1. 判断请求
      if (!javax.servlet.DispatcherType.ERROR.equals(request.getDispatcherType())) {
          final java.lang.String _jspx_method = request.getMethod();
          if ("OPTIONS".equals(_jspx_method)) {
              response.setHeader("Allow","GET, HEAD, POST, OPTIONS");
              return;
          }
          if (!"GET".equals(_jspx_method) && !"POST".equals(_jspx_method) && !"HEAD".equals(_jspx_method)) {
              response.setHeader("Allow","GET, HEAD, POST, OPTIONS");
              response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, "JSP 只允许 GET、POST 或 HEAD。Jasper 还允许 OPTIONS");
              return;
          }
                 
    2. final javax.servlet.jsp.PageContext pageContext;//页面上下文
      javax.servlet.http.HttpSession session = null;//session
      final javax.servlet.ServletContext application;//application
      final javax.servlet.ServletConfig config;//config
      javax.servlet.jsp.JspWriter out = null;//out
      final java.lang.Object page = this;//page:当前页面
      HttpServletRequest request		//请求
      HttpServletResponse response	//响应
                 
    3. 输出页面前增加的代码
      response.setContentType("text/html");//设置文本响应类型为html
      pageContext = _jspxFactory.getPageContext(this, request, response,null, true, 8192, true);
      _jspx_page_context = pageContext;
      application = pageContext.getServletContext();
      config = pageContext.getServletConfig();
      session = pageContext.getSession();
      out = pageContext.getOut();
      _jspx_out = out;
                 
    4. 以上的这些个对象我们可以在jsp页面中直接使用
    JavaWeb

    ​ 在jsp页面中:

    ​ 只要是java代码,就会原封不动的输出

    ​ 如果是HTML代码会被转换为

    out.write("<html>\n");
               
    这样的格式输出到前端

8.3JSP基础语法

JavaWeb

任何语言的都有自己的语法,Java中有,jsp作为java技术的一种应用,他拥有自己扩充的一些语法(了解,知道即可!)java所有语法都支持!

jsp表达式

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

jsp脚本片段

<%--jsp脚本片段--%>
<%
int sum = 0;
for (int i = 0; i < 100; i++) {
    sum+=i;

}
out.println("<h1>Sum="+sum+"</h1>");
%>
           

脚本片段的再实现

<%
int x = 10;
out.print(x);

%>
<p>这是一个jsp文档</p>
<%
out.print(x);
%>
<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 kuang(){
  System.out.println("进入了方法kuang");
}
%>
           

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

<%%>
<%=%>
<%!%>
<%--注释--%>
           

8.4JSP指令

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

<%--@include会将两个页面合二为一--%>
<%@include file="common/header.jsp" %>
<h1>网页主体</h1>
<%@include file="common/footer.jsp" %>
<%--jsp标签--
jsp:include:拼接页面本质还是三个
--%>
<jsp:include page="common/header.jsp"/>
<h1>网页主体</h1>
<jsp:include page="common/footer.jsp"/>

           

8.5、9大内置对象

  • PageContext 存东西
  • Request 存东西
  • Response
  • Session 存东西
  • Application【ServletContext】存东西
  • config【ServletConfig】
  • out
  • page
  • excepetion