JavaWeb上

前言:

web开发:

  • web,网页的意思 , www.baidu.com
  • 静态web
    • html,css
    • 提供给所有人看的数据始终不会发生变化!
  • 动态web
    • 淘宝,几乎是所有的网站;
    • 提供给所有人看的数据始终会发生变化,每个人在不同的时间,不同的地点看到的信息各不相同!
    • 技术栈:Servlet/JSP,ASP,PHP
      在java中,动态web资源开发的技术统称位javaweb

web应用程序

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

  • a.html、b.html…多个web资源,这些web资源可以被外界访问,对外界提供服务;
  • 你们能访问到的任何一个页面或者资源,都存在于这个世界的某一个角落的计算机上。
  • URL
  • 这个统一的web资源会被放在同一个文件夹下,web应用程序–>Tomcat:服务器
  • 一个web应用由多部分组成 (静态web,动态web)
    • html,css,js
    • jsp,servlet
    • Java程序
    • jar包
    • 配置文件 (Properties)
      web应用程序编写完毕之后,如果想提供给外界访问就需要一个服务器来进行统一管理

静态web

.htm,.html这些都是网页的后缀,如果服务器上面一直存在这些东西,我们就可以直接进行获取
PS:名词解释:
请求: Request 相应:Response web服务器:Web Service在这里插入图片描述
静态web存在的缺点:

  • web页面无法进行动态更新,所有用户看到的都是同一个页面

    轮播图,点击特效这些都是伪动态
    JavaScript[实际开发中,它用的最多]
    VBScript

  • 无法和数据库进行交互(数据无法进行持久化,用户无法进行交互)

动态web

页面会进行动态展示,web的页面展示效果会因人而异;
Plugin:插件
在这里插入图片描述
缺点:
加入服务器的动态web资源出现了错误时,需要重新编写我们的后台程序,重新发布;(也就是停机维护)
优点:
web页面可以动态更新,所有用户看到都不是同一个页面
可以跟数据库进行交互(数据持久化:注册,商品信息,用户信息…)
在这里插入图片描述

web服务器

技术讲解:

ASP:
微软出品,国内最早流行的就是ASP;
在HTML中嵌入了VB的脚本,ASP+COM;
在ASP开发中,基本一个页面中都有几千行的业务代码,页面极其混乱
维护成本高
C#
IIS
php:

  • PHP开发速度很快,功能很强大,跨平台,代码很简单 (70% , WP)
  • 无法承载大访问量的情况(局限性)
    JSP/Servlet:
    B/S:浏览器和服务器
    C/S:客户端和服务器
    sun公司主推的B/S架构
    基于java语言(所有的大公司,或者一些开源的组件,都是用java写的)
    可以承载三高问题

web服务器

服务器是一种被动的操作,用来处理用户的一些请求和给用户一些响应信息,
一般情况下以tomcat为例:
Tomcat是Apache 软件基金会(Apache Software Foundation)的Jakarta 项目中的一个核心项目,最新的Servlet 和JSP 规范总是能在Tomcat 中得到体现,因为Tomcat 技术先进、性能稳定,而且免费,因而深受Java 爱好者的喜爱并得到了部分软件开发商的认可,成为目前比较流行的Web 应用服务器。
Tomcat 服务器是一个免费的开放源代码的Web 应用服务器,属于轻量级应用服务器,在中小型系统和并发访问用户不是很多的场合下被普遍使用,是开发和调试JSP 程序的首选。对于一个Java初学web的人来说,它是最佳的选择
Tomcat 实际上运行JSP 页面和Servlet。Tomcat最新版本为9.0。

Tomcat

安装Tomcat
官网: http://tomcat.apache.org/
在这里插入图片描述
在这里插入图片描述

Tomcat启动和配置

文件夹作用:
在这里插入图片描述
启动关闭Tomcat:
在这里插入图片描述
访问测试:http://localhost:8080/
可能遇到的问题有:
java环境变量没有配置
闪退问题:需要配置兼容性
乱码问题:配置文件中进行设置

配置:

在这里插入图片描述
可配置启动的端口号

  • tomcat的默认端口号为:8080
  • mysql:3306
  • http:80
  • https:443
    (如下,修改port后重启Tomcat,再把输入栏改为localhost:+修改后的端口号就可以访问了)
<Connector port="8080" protocol="HTTP/1.1"
           connectionTimeout="20000"
           redirectPort="8443" />

可以配置主机的名称

  • 默认的主机名为:localhost->127.0.0.1
  • 默认网站应用存放的位置为:webapps
  <Host name="www.xg.com"  appBase="webapps"
        unpackWARs="true" autoDeploy="true">

面试题:
请你谈一谈网站时如何进行访问的:
1,输入域名,回车
2,检查本机的 C:\Windows\System32\drivers\etc\hosts配置文件下面有没有这个域名映射,如果有的话直接返回对应的ip地址,在这个地址中,有我们需要访问的web地址,可以直接进行访问

127.0.0.1       www.xg.com

如果没有的话就去DNS(全世界的域名都在这里进行管理)找,找到的话就进行返回,找不到就返回找不到;
在这里插入图片描述
3,可以配置一下环境变量(可选性)

发布一个web网站

不会就先模仿: 将自己写的网站放在服务器中指定的web应用的文件夹(webapps)下,就可以访问了
网站应有的结构:

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

Http

什么是http?
HTTP(超文本传输协议)是一个简单的请求-相应协议,它通常运行在tcp之上,
https:更安全的

两个时代

  • http1.0
    • HTTP/1.0:客户端可以与web服务器连接后,只能获得一个web资源,断开连接
  • http2.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
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响应

服务器–响应–客户端
百度:

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:请求相应成功
3xx:请求重定向(重新到提供的新位置去)
4xx:找不到资源 404(最常见,资源不存在)
5xx:服务器代码错误 500 502:网关错误

Maven

为什么需要使用maven仓库?
在javaweb项目开发中,需要使用大量的jar包,我们手动去导入会太过麻烦
如果能有一个东西帮我们自动导入和配置jar包就好了,所以maven就出来了

maven项目架构管理工具

我们目前就是用来方便导入jar包的
Maven的核心思想就是:约定大于配置
有约定,就不要去违反!
Maven会规定好你该如何去编写我们的java代码,必须要按照这个规范来进行

下载安装Maven

官网: https://maven.apache.org/
在这里插入图片描述
下载之后解压即可

配置环境变量

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

  • M2_HOME maven目录下的bin目录
  • MAVEN_HOME maven的目录
  • 在系统的path中配置 %MAVEN_HOME%\bin
    在这里插入图片描述
    测试Maven是否安装成功,保证必须配置完毕!

阿里云镜像

在这里插入图片描述

  • 镜像: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>

本地仓库:

在本地的仓库,远程仓库;
建立一个本地仓库:localRepository

<localRepository>D:\Environment\apache-maven-3.6.2\maven-repo</localRepository>

在IDEA中使用maven

首先启动idea
然后创建一个mavenWeb项目
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
等待项目初始化完毕,一般普通项目需要手动点击自动更新
在这里插入图片描述
在这里插入图片描述
这个时候就可以观察一下maven中新增的依赖
大坑注意:
IDEA项目创建成功之后,要看一眼maven的仓库镜像下载配置
idea2021.2版本会无法设置新建项目的maven镜像下载源,总是按照默认的,那个速度贼慢,慢到会让人觉得idea卡死了
在这里插入图片描述
在这里插入图片描述
这样就算创建完成了

创建一个普通的maven项目

在这里插入图片描述
在这里插入图片描述
注意,一般导入项目之后一定要记得导入依赖,往后随着项目的不断学习会导入越来越多的maven依赖

<!--    servlet 的依赖-->
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>servlet-api</artifactId>
        <version>2.5</version>
    </dependency>
<!--    JSP的依赖-->
    <dependency>
        <groupId>javax.servlet.jsp</groupId>
        <artifactId>javax.servlet.jsp-api</artifactId>
        <version>2.3.3</version>
    </dependency>

然后就会发现以下两个文件夹:
在这里插入图片描述
标记文件夹功能:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在IDEA中配置tomcat:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
解决警告问题:
必须要的配置:为什么有会有这个问题:我们访问这个网站,需要指定一个文件夹的名字
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

pom文件

pom.xml是maven的核心配置文件
在这里插入图片描述

<?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.8</maven.compiler.source>
    <maven.compiler.target>1.8</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>

在这里插入图片描述
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>

IDEA操作
在这里插入图片描述
在这里插入图片描述
解决遇到的问题:
1.Maven 3.6.2
解决方法:降级为3.6.1
在这里插入图片描述
Tomcat闪退:
解决办法如下图:更换为3.6.1版本
在这里插入图片描述
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>

maven仓库的使用
1,现在开始所有导的包都可以在maven仓库中进行查找添加(alt+回车选中)

2,如果本地maven仓库没有,那么就到网上去找https://mvnrepository.com/然后点击热度最高的那个
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
还会发下下面有几行代码,还有jar包可以进行下载
在这里插入图片描述
直接复制到pom.xml文件的< dependency>< /dependency>标签中,可以选择将之前的删除,然后就可以进行导入添加

模拟请求以及响应

一切配置完成之后,点击运行,(注意,运行时还要确保tomcat的cmd窗口关闭,不然就是两个端口同时使用造成端口堵塞)
在这里插入图片描述
因为JSP/Servlet属于动态映射会被优先响应首先会通过localhost:8080/yingshe打开webapp下面的index.jsp,然后打开一个预先就有的窗口,
在这里插入图片描述
如下,又因为在web.xml设置过Servlet的映射的请求路径,此时在输入栏中再输入localhost:8080/yingshe/xg就可以映射访问自己设定的页面
在这里插入图片描述

Servlet

简介:
Servlet是sun公司开发动态web的一门技术
sun在这些api中提供一个接口叫做servlet,如果你想开发一个Servlet程序,只需要完成两个小步骤:

  • 编写一个类,实现Servlet接口
  • 把开发好的Java类部署到web服务器中。
    实现了Servlet接口的java程序叫做Servlet,

HttpServlet的创建过程

Servlet接口有两个默认的实现类,其中一个就是HttpServlet,动手:
构建一个普通的Maven项目
删除掉里面的src目录,然后再在项目中新建Moudel,这个空项目就是Maven主工程;
关于Maven父子工程的理解:
首先父项目中的pom依赖中会有子项目的注入

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

子项目中的pom.xml会有:

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

类似继承关系,子项目可以直接使用父项目的配置依赖

Maven环境优化

修改web.xml为最新版,将原有的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>

将maven的结构搭建完整:(创建两个目录文件夹,一般java目录用来存放源码,resources目录用来存放静态资源)
在这里插入图片描述

编写Servlet程序

在建立的java目录文件夹中创建一个包,然后再保重创建java文件
在这里插入图片描述
然后实现Servlet接口,这里我们直接继承HttpServlet

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,Serlvet");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}
编写Servlet的映射

为什么需要映射:
我们写的是java程序,但是需要通过浏览器访问,而浏览器需要连接web服务器,所以我们需要在web服务中注册我们写的Servlet,还需要给它一个浏览器能够访问的路径;也就需要在servlet.xml中注入容器了

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

打开右侧菜单栏的Tomcat配置栏
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
启动测试,完成

Servlet流程原理

Servlet是由web服务器调用,web服务器在收到浏览器请求之后会有以下流程
在这里插入图片描述

Mapping问题

一个servlet指定一个映射路径

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

一个Servlet指定多个映射路径,或者说多个映射路径可以指定同一个name的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可以指定通用映射路径,*代表通配符,这样不管hello/后面的url路径是什么都会指向同一个Servlet

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

默认请求路径方面,如果直接设置为通配符,打开localhost:8080后不会调到默认的index.jsp,而是直接调到指定name的Servlet,也就是说映射的路径比默认的index.jsp页面优先级更高,但是尽量不要这样写

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

指定一些后缀或者前缀等等,注意,此处前面不能加"/",不然不管前面加什么,只要后缀会".xg"就会跳到映射路径指定的name下

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

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

<!--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>
    <!--此处百分百会报错404,但是这个错误映射路径又有具体指向  (name为error的servlet),
                    所以所有的报错页面都有了重新的定义-->   
</servlet-mapping>

ServletContext

web容器在启动的时候,他会为每一个web程序都创建一个对应的ServletContext对象,它代表了当前的web应用:
这样就可以通过this.get/set来进行不同Servlet之间的数据共享
示意图如下:
在这里插入图片描述
共享数据
在当前Servlet中保存的数据可以在另外一个servlet中拿到

public class HelloServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        
        //this.getServletContext()  Servlet上下文
        ServletContext context = this.getServletContext();//因为所有Servlet都共享一个ServletContex 

        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");//获得容器中的属性,并强转位Sring
        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);
    }
}

测试访问结果
获取初始化参数

    <!--在web.xml中配置一些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);
}

如下,上面的示意图是请求转发的示意图:a想获得c的资源,但是只能访问b。所以需要b再去访问c,然后返回给a
下面的示意图为重定向的示意图,同样是a想要获得c的资源,但是只能访问b, 而在这里,a访问b之后b会让a重定向并指向c,这样就省略了一个步骤
在这里插入图片描述
读取web资源文件
properties

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

发现资源文件都被在了同一个路径下:classes,我们俗称这个路径为calsspath:
注意:一定要先运行一次,获取targen缓存目录,然后再targen缓存目录中找到web程序的名字
最后使用"/"开头代表本类,并一级一级往下:
/WEB-INF/classes/db.properties
在这里插入图片描述
那么假设需要一个文件流:

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

        InputStream is = this.getServletContext().getResourceAsStream("/WEB-INF/classes/com/kuang/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 {
        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;

下载文件

想要下载文件就必须知道以下消息:
要获取下载文件的路径
下载的文件名
设置想办法让浏览器能够支持下载我们需要的东西
获取下载文件的输入流
创建缓冲区
获取OutputStream对象
将FileOutputStream流写入到buffer缓冲区
使用OutputStream将缓冲区中的数据输出到客户端!

@Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//        1. 要获取下载文件的路径  绝对路径
        String path ="D:\\IDEAproject\\javaweb-02-servlet\\Response\\target\\classes\\鬼灭之刃.jpg";
        System.out.println("下载文件的路径:"+path);
//        2. 下载的文件名是啥?
//       注意,此方法是先截取字符串中最后一个"/"后面的所有字符串(+1是为了不包括/本身 而//是为了使/能被转义),
//       然受substring使其成为一个新的字符串
        String filename = path.substring(path.lastIndexOf("//") + 1);
//        3. 设置想办法让浏览器能够支持(Content-Disposition)下载我们需要的东西
//            urlencoder.encoder方法是用来将中文的文件名转码,否则可能乱码,这是在网络编程中学到的
        resp.setHeader("Content-Disposition","attachment;filename="+URLEncoder.encode(filename,"UTF-8"));
//        4. 获取下载文件的输入流
        FileInputStream is = new FileInputStream(path);
//        5. 创建缓冲区
        int len=0;
        byte[] buffer = new byte[1024];
        //        6. 获取OutputStream对象
        ServletOutputStream os = resp.getOutputStream();
//        7. 将FileOutputStream流写入到buffer缓冲区,使用OutputStream将缓冲区中的数据输出到客户端!
        while ((len=is.read(buffer))>0){  //只要有数据,就望
            os.write(buffer,0,len);
        }
//        8.关闭流
        is.close();
        os.close();
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

验证码功能

验证码前端后端都可以实现,这里以后端为例:
后端实现验证码的话需要用到java的图片类,生产一个图片

public class ImageServlet extends HttpServlet {

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

        //如何让浏览器3秒自动刷新一次;
        resp.setHeader("refresh","3");
        
        //在内存中创建一个图片
        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(makeNum(),0,20);

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

        //把图片写给浏览器
        ImageIO.write(image,"jpg", resp.getOutputStream());

    }

    //生成随机数
    private String makeNum(){
         Random random = new Random();
        //将int类型转换为String的两种方式:
        //第一种:String s = String.valueOf(random.nextInt(99999999));下面为第二种
        String num = random.nextInt(9999999)+"";//随机生成一个0~9999999之间的整数,
        //创建一个字符串缓冲区
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i <7-num.length(); i++) {//因为数是随机的,那么这个随机数的位数也是随机的,并且肯定不会大于7位
            sb.append("0");//如果随机的位数少于7,则每少几位就在开头添加几个零
            System.out.println(i);
        }
        num= sb.toString() + num;
        return num;
        /*此方法的原理:
    先创建一个不超过七位数的随机整数,然后再创建一个空的字符串缓冲区
    利用for循环,如果随机的数字小于七位,那么就在空的字符串缓冲区中添加一个0,
    这样 随机整数的位数  加上 空字符串的内容 绝对等于七位
    最后就是两者相加了
    * */
    }

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

实现重定向:

在这里插入图片描述
B一个web资源收到客户端A请求之后,B会通知A客户端去访问另外一个web资源C,这个过程就叫做重定向
常见场景:
用户登录:

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("/r/img");//重定向
}

面试点:
聊一聊重定向和请求转发的区别:
相同点:页面都会实现跳转
不同点:
请求转发的时候url不会发生变化 307
重定向的时候url地址栏会发生变化 302
在这里插入图片描述

简单实现登录重定向

整体思路:
开启服务器首先在初始index.jsp页面的表单中填写内容并调教到i新的servlet页面,并在servlet页面获取参数之后再跳转到登录成功的jsp页面上

<%--这里提交的路径,需要寻找到项目的路径--%>

<%--${pageContext.request.contextPath}代表当前的项目--%>
<form action="${pageContext.request.contextPath}/s4" method="get">//这个连接(action)通过/s4映射链接来跳转到/s4页面
    用户名:<input type="text" name="username"> <br>
    密码:<input type="password" name="password"> <br>
    <input type="submit">
</form>
//     s4
@Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //处理请求
        String username = req.getParameter("username");//获取参数,括号中是参数的名称(String)
        String password = req.getParameter("password");
        System.out.println(username+":"+password);

        //重定向时候一定要注意,路径问题,否则404;
        resp.sendRedirect("/xg/success.jsp");//注意加上.jsp
    }
  <!--    注册servlet-->
  <servlet>
    <servlet-name>s4</servlet-name>
    <servlet-class>com.xg.RequestTest模拟登录跳转原理</servlet-class>
  </servlet>
  <!--    映射时按照自下而上的顺序进行-->
  <servlet-mapping>
    <servlet-name>s4</servlet-name>
    <url-pattern>/s4</url-pattern>
  </servlet-mapping>

成功的页面就不放出来了

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[] hobbies = req.getParameterValues("hobbies");
        System.out.println("====================================");
        //打印参数
        System.out.println(username);
        System.out.println(password);
        System.out.println(Arrays.toString(hobbies));
        System.out.println("====================================");
   
        //resp.sendRedirect("");//此方法用来进行重定向
        //this.getServletContext();//此方法用来进行转发
   
        //通过请求转发  forward代表发送,如果不加页面不会跳转的  这里的"/"代表当前的web应用
        req.getRequestDispatcher("/success.jsp").forward(req,resp);
        //注意,转发不需要写项目路径,因为转发是服务器级别
        //req.getContextPath();此方法用来获取项目路径,也就是Tomcat中war包那边的/xg
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值