【狂神说】JavaWeb 笔记(上)

javaWeb


JavaWeb 中

基本概念

静态web:所有人看到的网页都一样,代表技术 html,css
动态web:不同人看到的不一样,例如淘宝 ,代表技术 servlet,jsp ,asp ,php

一个web应用有多部分组成

  • html、css,js
  • jsp,servlet
  • java程序
  • jar包
  • 配置文件(properties)

web应用编写完毕之后:需要统一一个服务器来管理

静态web:如果服务器上面存在,我们就一直可以访问
在这里插入图片描述

其缺点:

  • web无法更新,所有用户都是同一个页面
  • 无法与数据库进行交互,数据无法持久化

动态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写的)

可以承载三高问题带来的影响;

语法像ASP,ASP->JSP,加强市场强度;

web服务器

服务器是一种被动的操作,用来处理用户的一些请求和给用户一些响应信息;
lIS
微软的;ASP.,Windows中自带的
Tomcat

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

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

Tomcat 实际上运行JSP页面和Serlet。Tornct最新版易9.0

安装Tomcat

首先在官网上下载压缩包然后解压缩

在这里插入图片描述

在bin目录下找到startup.bat打开

如果出现闪退,首先检查jdk是否安装,在命令行(win+r后输入cmd)输入java或javac检查

然后右键startup选择编辑输入以下代码

SET JAVA_HOME=C:\Program Files\Java\jdk-11.0.10(jdk 地址)
SET TOMCAT_HOME=G:\Tomcat\apache-tomcat-9.0.52(Tomcat地址)

然后右键shutdown进行同样的操作。

一般就解决了问题 但也有可能jdk的版本和Tomcat不兼容(来自弹幕

乱码问题建议不要去解决

如果想解决:修改tomcat的conf下的logging.properties中的 一句话

java.util.logging.ConsoleHandler.encoding = UTF-8 改为——》

java.util.logging.ConsoleHandler.encoding = GBK

测试:http://localhost:8080/ 是否能打开

底层配置

不懂别乱操作.讲这里只是为了更好的理解底层,不要动这些文件,和现在使用没有关系

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-X9OISexg-1632027242091)(安装Tomcat.assets/image-20210914111303312.png)]

可以配置启动的端口号

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

可以配置主机的名称

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

面试题:
请你谈谈网站是如何进行访问的!

  1. 输入一个域名;敲回车
  2. 检查本机的C:\Windows\System32\drivers\etc\hosts配置文件下有没有这个域名映射;
    1. 有:直接返回对应的ip地址,这个地址中,有我们需要访问的web程序,可以直接访问
    2. 没有:去DNS服务器找,找到的话就返回,找不到就返回找不到;

发布网站

  • 将自己写的网站,放到服务器(Tomcat)中指定的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

概括

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

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

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
1、请求行

请求行中的请求方式:GET
请求方式:Get,Post,HEAD,DELETE,PUT,TRACT.…
get:请求能够携带的参数比较少,大小有限制,会在浏览器的URL地址栏显示数据内容,不安全,但高效
post:请求能够携带的参数没有限制,大小没有限制,不会在浏览器的URL地址栏显示数据内容,安全,但不高效。

2、消息头
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   类型  

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:网关错误

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

。。。。

Maven

我为什么要学习这个技术?

在Javaweb开发中,需要使用大量的jar包,我们手动去导入;
如何能够让一个东西自动帮我导入和配置这个jar包。
由此,Maven (项目架构管理工具) 诞生了!

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

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

安装

Maven – Download Apache Maven官网下载安装后缀为bin.zip的文件,解压。

maven3已经不需要配两个环境变量了,选择一个path就行(来自弹幕)

但我还是按照老师说的三个全写上了。
在我的电脑的环境变量中配置环境变量。

  • M2_HOME (变量)值为 电脑中maven目录下的bin目录的路径
  • MAVEN_HOME (变量)值为 电脑中 maven的目录 的路径
  • 在系统的path中添加 %MAVEN_HOME%\bin

配好了变量之后点击确定后,可以在win+r,输入cmd检查一下 mvn-version

[]

优化

因为国内被墙所以使用阿里云镜像,其他镜像也可,可以在百度搜索其他镜像,这里使用阿里云为示范。

在settings.xml文件中的mirrors下添加mirror标签(我直接把原来自带的删了
下面两个选择一个就行,我选择的第二个

<mirror>
    <id>alimaven</id>
    <mirrorOf>central</mirrorOf>
    <name>aliyun maven</name>
    <url>http://maven.aliyun.com/nexus/content/repositories/central/</url>
</mirror>

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

<!--这两个都行。。。只不过狂神好像对第一个不感冒  但我没感觉出来有什么不同(菜-->

下面这一步是我自己加上的,因为不加的话,后面再使用过程,jdk总是默认1.5,每次都要手动调,在这里可以直接一劳永逸(当然,要根据自己的jdk版本进行相应的修改。
下面这一段要加载setting,xml文件中的 profiles 标签里面,有高亮打开高亮!不要加在注释中!!

<profile>
           <id>jdk-11</id>
           <activation>
              <activeByDefault>true</activeByDefault>
              <jdk>11</jdk>
            </activation>
                    <properties>
                       <maven.compiler.source>11</maven.compiler.source>
                            <maven.compiler.target>11</maven.compiler.target>
                             <maven.compiler.compilerVersion>11</maven.compiler.compilerVersion> 
                    </properties>
</profile>

下面在本地建一个仓库

首先在maven根目录建一个新文件夹,名称为 maven-repo

然后在刚刚的settings.xml文件添加如下
记得将中间路径改为自己的路径
还有注意别写到注释中,如果看不出来哪里是注释,可以下载一个带高亮的编辑软件如:nodepad++

<localRepository>G:\Maven\apache-maven-3.8.2\maven-repo</localRepository>

使用

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7yHEyLbI-1632027242095)(JavaWeb.assets/image-20210914164353839.png)]

  • 在Maven中选择sdk然后勾选Create from archetype(maven自带的模板) 然后选择webapp创建工程 要看清楚,不要选错了

在这里插入图片描述

  1. 第一个窗口改为自己下载的maven地址(因为idea自带的有maven
  2. 第二个窗口填maven的设置信息
  3. 第三个窗口填之前自己创建的本地仓库

然后创建完毕

新版的包会给在右下角你自动导入,第一次进入肯定会卡,耐心等着。

!!!!IDEA项目每次创建时,要看一眼仓库的位置,有可能会给你放到默认的c盘!!!

创建新的java文件夹和resources文件夹
在这里插入图片描述

将java文件夹标记为源码目录,方便创建class文件夹

将resources文件夹标记为资源目录

在这里插入图片描述

(jdk过高好像不支持哦。

在Idea中配置Tomcat

点击右上角 Add Configuration

在弹出的窗口中然后点击加号,找到Tomcatserver选择local(本地)进行如下配置

如果没有Tomcat选择插件下载下载Tomcat(来自弹幕

如果APPlication server报错就手动确定Tomcat位置

如果Tomcat为10有可能就会报错,选择tomcat9(来自弹幕

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7sK8A1YG-1632027242098)(JavaWeb.assets/image-20210914190451060.png)]

解决警告问题:

我们访问一个网站,需要指定一个文件夹的名字

在这里插入图片描述

因此点击Fix然后跳转到第二个小窗口点击加号新建一个就可以了。

点击右上角的绿色小箭头启动Tomcat,然后就会自动弹出webapp文件夹里的index.jsp文件的网页。

pom文件

pom文件为核心文件

首先按照view ->tool windows -> Maven打开下面窗口

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vr4w9OoP-1632027242100)(JavaWeb.assets/image-20210914195338176.png)]

选中左边文件目录的target然后双击clean进行清理命令。

关于左侧pom文件的一些参数的介绍

<?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>third-Maven</artifactId>
     <version>1.0-SNAPSHOT</version>
      <!-- 项目的打包方式
       jar:java应用
       war:javaweb应用-->
     <packaging>war</packaging>
      <!-- 狂神把这一段删了 说没用-->
     <name>third-Maven Maven Webapp</name>
     <!-- FIXME change it to the project's website -->
  <url>http://www.example.com</url>
    <!--配置-->
  <properties>
      <!-- 项目的默认配置编码-->
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
      <!--编译版本-->
      <!--我的删掉之后,后面有时会出现默认jdk版本错误,不知道和这个有没有关系--->
    <maven.compiler.source>1.7</maven.compiler.source>
    <maven.compiler.target>1.7</maven.compiler.target>
  </properties>
    <!--项目依赖-->
  <dependencies>
      <!-- 具体依赖的jar包  在右边的Maven结构的Dependencies里面实时反馈-->
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
    <!--这里面存放项目构建所用到的东西-->
  <build>
    <finalName>third-Maven</finalName>
  </build>
</project>

高级之处

当你想在 dependencies 标签中放入一个你所需要的 jar包链接 时,Maven 会自动帮你导入其所需要的基础jia包,可以在左侧目录栏看见自动导入的jar包的名称

顺带一提,以后当你在java文件夹中写入xml文件等不属于java类型的文件时,当你想要导出会出现失败的情况,需要在 build 标签提前粘贴一段resources代码。。后面还会讲到,这里先不用管。

专门开了一节课来解决问题

在这里插入图片描述

有需要的就直接来看视频吧(虽然我感觉看到这里的人,所遇到的问题都已经自己解决了

Servlet

sun公司在API中提供了一个接口:Servlet,用于开发动态Web。如果你想开发一个 Servlet程序,只需要完成两个小步骤:

  • 编写一个类,实现Servlet接口
  • 把开发好的java类部署到web服务器上

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

在这里插入图片描述

准备环境

首先创建一个新的Maven项目,不用像之前一样选javaweb和打对勾,直接创建一个就行。(因为这将会是一个主工程,这里面不会写代码。。。。

然后把创好的工程中的src文件删除,这个将会作为我们的主工程,将来其他的一些子工程将会建在这个目录下面。在主工程中尽量将一些依赖的jar包都导入进来。

首先我们之后需要学习servlet和jsp,我们先将所依赖的jar包导入到工程中,这个时候就体现出Maven的好处了,在Maven Repository:搜索两种技术(servlet 和 jsp),将最新的(或者使用人最多的)链接复制到 dependencies 标签目录下就行了

<dependencies>

    <!-- https://mvnrepository.com/artifact/javax.servlet.jsp/javax.servlet.jsp-api -->
    <dependency>
        <groupId>javax.servlet.jsp</groupId>
        <artifactId>javax.servlet.jsp-api</artifactId>
        <version>2.3.3</version>
        <scope>provided</scope>
        <!--tomcat中也有servlet-api包,这样,发生了冲突
			解决方法:添加<scope>provided</scope>,因为provided表明该包只在编译和测试的时候用,所以,当启动tomcat的时候,就不会冲突了-->
        <!--  但是狂神建议删除。。。会不会因为provided没有传递性。在后面的子工程就不能够应用到该jar包了? -->
        <!--为了和狂神一致性,我也删了-->
    </dependency>

    <!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <version>4.0.1</version>
        <scope>provided</scope>
    </dependency>

</dependencies>

在这里插入图片描述

然后在本工程的名字上右键选择新建Module ,打上对勾‘create from archetype’,这一次选择使用 webapp模板 然后新建成功子工程。

在这里插入图片描述

在父工程的pom文件中会多一个module,指向新建的子工程

<modules>
    <module>javeweb-Maven-1-1</module>
</modules>

在子工程的pom文件中会

emmm 我的好像没有狂神视频中的parent标签,弹幕中说是新版本改为自动继承,不会显示了。。。

虽然不弄也能出网页,但是还是尽量写上吧。。。parent 标签吧,主要是怕各种错误,熟练之后可以尝试不写试试)
(我后面就不写了。。。如果出现了不知道哪里错误的bug就回头尝试写上能不能解决吧)

解决方法搜到如下:

  • 手动添加 父工程名 **** 1.0-SNAPSHOT ,一定要重启或者刷新 idea!!!
  • 把 .idea删除然后重新加载就出来的
  • 把父工程中依赖scorp标签删除的
  • 更新了idea就出来的
  • 来自评论的一个解决方法:
    在这里插入图片描述

(捣鼓半个下午我快吐了

进行两步环境的优化:

每次新建通过webapp模板的工程文件中的web.xml文件都是默认的老版本 2.3,一般情况下我们就需要自己修改为新版本。。将下面的代码直接覆盖原文件web.xml

<?xml version="1.0" encoding="UTF-8" ?>

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

然后优化文件结构:在子工程的目录main中新建java文件夹,标记为源码文件; 新建resources文件夹,标记为资源文件 (idea会有自动提示

编写Servlet

创建一个普通类然后实现Servlet接口,这里我们直接继承HttpServlet。

首先查看了源码,了解了HttpServlet的 继承servlet接口的路径,了解为什么我们需要重写HttpServlet;

ctrl+o 选择需要重写的方法

在选择框中选择重写doGet和doPost两种方法

由于get或者post只是请求实现的不同的方式,可以相互调用,业务逻辑都一样(狂神的这句话感觉有点绝对了。。。但是这样使用应该没问题)。因此do_post方法直接引入了do_get而只修改do_get方法。。

public class HelloServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //ServletOutputStream outputStream = resp.getOutputStream();
        PrintWriter writer = resp.getWriter(); //响应流 alt+enter可以快速补全调用函数所缺少的import
        writer.print("Hello,Serlvet");

    }

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

映射Servlet

为什么需要映射:

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

在web.xml文件中的 web-app 标签间加入映射 要善于使用自动补全代码 (按tab键。)

<!--注册Servlet -->
<servlet>
    <servlet-name>hello</servlet-name>
    <servlet-class>HelloServlet  </servlet-class>
</servlet>
<!--Servlet的请求路径 注意第二个hello有斜杠-->
<servlet-mapping>
    <servlet-name>hello</servlet-name>
    <url-pattern>/hello</url-pattern>
</servlet-mapping>

配置tomcat

点击右上角 Add Configuration

在弹出的窗口中然后点击加号,找到Tomcatserver选择local(本地)进行如下配置

如果没有Tomcat选择插件下载下载Tomcat(来自弹幕

如果APPlication server报错就手动确定Tomcat位置

如果Tomcat为10有可能就会报错,选择tomcat9(来自弹幕

在这里插入图片描述

在这里插入图片描述

因此点击Fix然后跳转到第二个小窗口点击加号新建一个就可以了。

点击右上角的绿色小箭头启动Tomcat,没有问题自动弹出webapp文件夹里的index.jsp文件的网页。

出现了错误:Error during artifact deployment. See server log for details

检查无果,将子工程删除重新来过。

最终成功运行,但是却突然发现弹出的网页是404.。。。

源服务器未能找到目标资源的表示或者是不愿公开一个已经存在的资源表示。

稀里糊涂的试了很多很多

在这里插入图片描述

后来发现,当点击开始运行跳转到的第一个页面是localhost是404,在后面加上/s1 就出来了页面。。。。(在配置tomcat时,更改URL可修改这个问题

这好像建立在target文件中出现了index.jsp文件

我在网上搜索后搜索到了这位大佬的博客:(3条消息) IntelliJ IDEA 编译maven项目时,target中没有web-app目录下的文件_斑得贝迪的博客-CSDN博客_idea webapp没有导入target

(实在找不到BUG就仔细按照步骤,重新来过哦)

Servlet 原理

在这里插入图片描述

理解Servlet工作原理 - 简书 (jianshu.com)

Mapping 问题

servlet中所有访问路径都要用绝对路径“/”开头

一个 Servlet 可以指定一个映射路径 (就是我们刚刚在helloservlet中的代码)

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

一个 Servlet 可以指定多个映射路径(就是一个名字同时映射多个路径)

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

一个 Servlet 可以指定通用映射路径(星号代表乱写都能访问到这个页面)

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

设置默认请求路径(就是啥都不输入就跳转到这个页面,只不过就覆盖了原来的首页)

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

制定一些后缀或者前缀

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

ServeltContext 对象

重新建一个子工程;采用模板依旧是webapp

修改web.xml 为最新的版本;补全main文件的结构(java和resources 记得标记

巴拉巴拉。。。

记得tomcat最后将上一个删除,改为这一个项目(用哪个就打哪个的包)

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

1、共享数据

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

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

        //this.getInitParameter()   初始化参数
        //this.getServletConfig()   Servlet配置
        //this.getServletContext()  Servlet上下文
        //this.getServletName()  Servlet名字
        ServletContext context = this.getServletContext();//创建一个“云” 该对象来作为中转站实现数据在不同的servlet中传输

        String username = "szg";
        context.setAttribute("username",username); //将数据保存到ServletContext中(键值对的方式)
    }

}

创建另一个java文件

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");//在云中获取数据 因为获取的object对象,所以需要强行转换

        //改变编码,使其能够显示中文
        resp.setContentType("text/html");
        //contentType="text/html;charset=UTF-8"的作用是指定对服务器响应进行重新编码的编码。 
        resp.setCharacterEncoding("utf-8");
        //页面输出
        resp.getWriter().print("名字"+username);
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

记得给新建立的java文件在web.xml文件注册并建立路径。

在运行了tomcat之后,要记得先进入发送数据的网页,再打开接受数据的网页才能收到数据,顺序不要错!!

2、获取初始化参数

这里好像是关于关于请求

Web.xml配置文件中context-param的作用 – 小白教程 (schoolw3c.com)

就是在运行项目之前通过读取这个param可以提前知道一些东西。。

<!--配置一些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);
}

3、请求转发

转发和重定向并不是一个东西
servlet中的转发和重定向

转发:A向B要苹果,B没有,B向C要了苹果,然后给了A (明面上给A的是B,实际上是C的苹果

重定向:A向B要苹果,B没有,但是C有,B让A向C要,A向C要来了苹果(明面上给A的是B,

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    ServletContext context = this.getServletContext();
    //RequestDispatcher requestDispatcher = context.getRequestDispatcher("/gp"); //转发的请求路径
    //requestDispatcher.forward(req,resp); //调用forward实现请求转发;
    //转发之后页面内容为新指向  的页面。。。但是地址为原来页面的地址。。
    context.getRequestDispatcher("/gp").forward(req,resp);
}

在这里插入图片描述

4、读取资源文件

Properties:继承于 Hashtable。表示一个持久的属性集.属性列表中每个键及其对应值都是一个字符串。

在获取环境变量时它就可以作为 System.getProperties() 方法的返回值。

  • 在 resources 目录下新建 bb.properties 内容就随便写一个键值对 然后我们发现在编译之后在target文件中出现了该文件。
  • 然后我们在java目录下新建aa.properties 内容和aa一样, 然后当我们编译之后就发现target文件中没有该文件

这就扯到了之前狂神说过的导出文件存在了导不出来的尴尬情况我们需要在pom.xml中添加如下代码

(如果粘贴之后出现build标签有红色就是和原本文件中的出现了重复,将文件中的build标签合并就行)

(目的是在导出时要识别其他格式的文件,要随着java的一起导出。)

(有人说,你这不是多此一举吗,直接放到resources就没事了,但是这样可以提高可读性同时在后面spring的框架中会用到。–来自弹幕

(有可能会有延迟,重启一下比较好)

 <build>
    <resources>
      <resource>
        <directory>src/main/java</directory>
        <includes>
          <include>**/*.properties</include>
          <include>**/*.xml</include>
        </includes>
        <filtering>true</filtering>
      </resource>
    </resources>
  </build>

在这里插入图片描述

新建一个java文件然后写入以下内容

public class ServletDemo05 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		//这个路径是在target中关于
        InputStream is = this.getServletContext().getResourceAsStream("/WEB-INF/classes/com/szg/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);
    }
}

记得在web.xml文件中加上servlet映射

根据结果即可知 成功读取了资源文件。

HttpServletResponse

1、简单分类

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

  • 如果要获取客户端请求过来的参数:找HttpServletRequest

  • 如果要给客户端响应一些信息:找HttpServletResponse

    HttpServletResponse对象代表服务器的响应。这个对象中封装了向客户端发送数据、发送响应头,发送响应状态码的方法。

    • 负责向浏览器发送数据的方法
    //getOutputStream()返回的字节输出流对象,类型为:ServletOutputStream,直接输出字节数组中的二进制数据。
    servletOutputstream getOutputstream() throws IOException; 
    //getWriter()方法将Servlet引擎的数据缓冲区包装成PrintWriter类型的字符输出流对象后返回,PrintWriter对象只能输出字符文本内容。
    Printwriter getwriter() throws IOException;
    //getOutputStream()和getWriter()这两个方法互相排斥,调用了其中的任何一个方法后,就不能再调用另一方法。
    
    //在获取PrintWriter输出流之前首先使用"response.setCharacterEncoding(charset)"设置字符以什么样的编码输出到浏览器,再使用response.getWriter(),获取PrintWriter输出流,这两个步骤不能颠倒。
    
    • 负责向浏览器发送响应头的方法
    void setCharacterEncoding(String var1)//进行重新编码
    void setContentLength(int var1)void setContentLengthLong(long var1);
    void setContentType(String var1)void setDateHeader(String varl,long var2);//该方法是设置只有一个值且值的类型为long类型的响应头,例如expies响应头,表示过期时间
    void addDateHeader(String var1,long var2)//该方法是设置只有一个值且值的类型为long类型的响应头,例如expies响应头,表示过期时间
    void setHeader(String var1,String var2);//该方法是设置只有一个值的响应头,参数name表示响应头名称,参数value表示响应头的值
    void addHeader(String var1,String var2)//该方法是设置有多个值的响应头,参数name表示响应头名称,参数value表示响应头的值
    void setIntHeader(String var1,int var2);//该方法是设置只有一个值且值的类型为int类型的响应头,例如Content-Length响应头,该响应头是代表响应内容有多少字节数
    void addIntHeader(String varl,int var2);//该方法是设置有多个值且值的类型为int类型的响应头
    

    状态码记住几个常见的,其他的到时候上网查吧。

    • SC_NOT_FOUND 状态码404对应的常量

    • SC_OK 状态码200对应的常量

    • SC_INIERNAL_SERVER_ERROR 状态码500对应的常量

    • 常用应用:向浏览器输出信息(outputstream和writer)、 在网页制造下载任务

2、下载任务

步骤:

  1. 要获取下载文件的路径
  2. 下载的文件名是啥?
  3. 设置想办法让浏览器能够支持下载我们需要的东西
  4. 获取下载文件的输入流
  5. 创建缓冲区
  6. 获取OutputStream对象
  7. 将FileOutputStream流写入到bufer缓冲区
  8. 使用OutputStream将缓冲区中的数据输出到客户端!

先创建一个新的module,名字就是respose了。然后按照之前的流程先走一遍(配置web、优化文件结构、改tomcat等等

在这里取得的路径(当然,我不在target文件中取,在main的resources中copy路径也可以实现下载文件

在这里插入图片描述

不知道为啥我的已进入网页就自动下载完了。。。。。根本没有弹出狂神的那个360浏览器下载页面(我不是360

(出现不对就仔细检查一下代码,好多都是因为代码有问题而导致的错误)

推荐使用OutputStream流,避免使用PrintWriter流,因为OutputStream流是字节流,可以处理任意类型的数据,而PrintWriter流是字符流,只能处理字符数据,如果用字符流处理字节数据,会导致数据丢失。


public class FileServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 1. 要获取下载文件的路径
        String realPath = "G:\\javaweb-Maven-1\\response\\src\\main\\resources\\szg.png";

        // 2. 下载的文件名
        //这里很巧妙,因为路径中的最后一个斜杠的后面肯定是文件名,通过这种方式获得了文件名
        String fileName = realPath.substring(realPath.lastIndexOf("\\") + 1);
        // 3. 设置想办法让浏览器能够支持(Content-Disposition)下载我们需要的东西。
        // 中文文件名URLEncoder.encode编码,否则有可能乱码
        // 当然在实际中不提倡使用中文作为文件名称 注意下面语句中间有一个分号,不注意容易弄成冒号。。~
        resp.setHeader("Content-Disposition","attachment ;  filename="+ URLEncoder.encode(fileName,"UTF-8"));
        // 4. 获取下载文件的输入流
        FileInputStream in = new FileInputStream(realPath);
        // 5. 创建缓冲区
        int len = 0;
        byte[] buffer = new byte[1024];
        // 6. 获取OutputStream对象
        ServletOutputStream out = resp.getOutputStream();
        // 7. 将FileOutputStream流写入到buffer缓冲区,使用OutputStream将缓冲区中的数据输出到客户端!
        while ((len=in.read(buffer))>0){
            out.write(buffer,0,len);
        }

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

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

3、实现验证码

不强求理解并应用。(我没在自己的电脑上尝试,下面直接复制的狂神代码

通过后端产生一个验证码,大体思路:

通过随机数生成器产生随机数,将其写入到一张纯色背景的图片中,然后将图片放到页面中,获取用户输入的验证码与随机数形成比对

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

    //随机数生成器 返回string
    private String makeNum(){
        Random random = new Random();
        String num = random.nextInt(9999999) + "";
        StringBuffer sb = new StringBuffer();
        //用0补全缺少的位置,确保为7位数
        for (int i = 0; i < 7-num.length() ; i++) {
            sb.append("0");
        }
        num = sb.toString() + num;
        return num;
    }

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

HttpServletRequest

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

了解以下函数:

在这里插入图片描述

一个是返回一个,一个是返回一个数组

新建一个request子工程配置好

处理请求的java类:


public class LoginServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //通过jsp的标签的名字属性来获取值
        String username=req.getParameter("username");
        String password=req.getParameter("password");
        String[] hobbies=req.getParameterValues("hobbies");
        System.out.println(username);
        System.out.println(password);
        System.out.println(Arrays.toString(hobbies));
        System.out.println("path:"+req.getContextPath());//解决相对路径的问题,可返回站点的根路径。
        //通过请求转发,(分清转发和重定向)forward
        //这里的‘/’代表当前的web应用,不需要在前面再加上斜杠,不然会出现重复路径。
        req.getRequestDispatcher("/succes.jsp").forward(req,resp);
    }

    @Override
    //话说dopost和doget因为相互调用,所以选谁都没问题
    //但是好像不写dopost再提交的时候会出现405错误
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        doGet(req, resp);
    }
}

删掉之前的然后新建的index.jsp:
csdn没有jsp格式,采用的html高亮

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Hello</title>

</head>
<body>
<%-- ${pageContext. request.contextPath} 是JSP取得绝对路径的方法,获得项目的http路径 --%>
<%-- 在本段代码中等价于 s1/login --%>
<h1>登录</h1>
<div style="text-align: center">
    <%--提交到login请求--%>
    <form action="${pageContext. request.contextPath}/login" method="post">
        用户名: <input type="text" name="username" > <br>
        密码:<input type="password" name="password"><br>
        爱好:
        <input type="checkbox"name="hobbies" value="girl">女朋友
        <input type="checkbox"name="hobbies" value="code">代码
        <input type="checkbox"name="hobbies" value="movie">电影
        <input type="checkbox"name="hobbies" value="sing">唱歌
        <br>
        <input type="submit">
    </form>
</div>
</body>
</html>

新建一个success.jsp:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<h1>success!</h1>
</body>
</html>

编译时出现了:再支持源选项 5 请使用 6 或更高版本。不支持发行版本 5
在这里插入图片描述

在这里插入图片描述

然后这样解决。

然后出来登陆页面点击提交之后不跳转:

最后也没找到方法是我配置问题吗?

实在不知道错哪里了。。

2021.9.28————
actoin写成了。。。cation

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值