尚硅谷最新版JavaWeb全套教程,java web零基础入门完整版(一)

HTML和CSS

  • ctrl + shift + / 在同一行代码中的后半截产生注释

HTML标签的介绍

在这里插入图片描述

  • 标签拥有自己的属性,分为 基本属性 和 事件属性
  • 标签的基本属性bgcolor="red 可以修改简单的样式效果
  • 标签的事件属性onclick="alert('你好');"

单标签:

  • br/ 换行
  • hr/ 水平线

常用标签介绍:

  • foot标签是字体标签,可以用来修改文本的 字体face,颜色color,大小size
  • 特殊字符 :小于号,空格,和号&,引号",撇号’ 等 我是<br>标签
  • 标题标签 :h1 到 h6, 属性align控制左对齐left(默认),中间center,右对齐(会随着窗口大小自动调整)
  • 超链接标签 :属性href控制链接,属性target控制当前(_self),和另一个页面(_blank)
  • 无序列表ul :属性type可以修改列表项前面的符号(兼容)
  • img标签 :属性src设置图片的路径,width,height,border设置边框大小,alt
  • 表格标签table,tr是行标签,th(相当于td加上b加粗)是表头标签,td是单元格标签,align设置单元格文本对齐方式;bordr,width,height,align设置表格相对于页面的对齐方式,cellspacing设置单元格间距
  • 跨行跨列表格,colspan属性设置跨列(用了以后要把其他同一行的单元格删掉部分,否则表格会突出);rowspan属性设置跨行
  • iframe框架标签(内嵌窗口),可以在一个html页面上打开一个小窗口小区域,去加载一个单独的页面;iframe标签和a标签组合使用的步骤 :1.在iframe标签中使用name属性定义一个名称;2.在a标签的target属性上设置iframe的name属性值
  • 表单标签form :
    在这里插入图片描述
  • 表单格式化 :form里面嵌套table
  • 表单提交的细节 :
    在这里插入图片描述
    在这里插入图片描述
  • 其他标签 :div标签默认独占一行;span标签 它的长度是封装数据的长度;p段落标签 默认会在段落的上方或下方各空出一行来(如果已经有就不再空)

CSS技术

常用样式:

  • 字体颜色color: red;
  • 宽度;高度;(像素值 / 百分比值)
  • 背景颜色background-color
  • 字体大小font-size
  • 红色1像素实线边框border: 1px solid red;
  • DIV居中margin-left: auto; margin-right: auto;
  • 文本居中text-align: center;
  • 超链接去下划线text-decoration: none;
  • 表格细线 :
    在这里插入图片描述
  • 列表去除修饰ul {list-style: none;}

JavaScript语言入门

  • JS是弱类型(类型可变),Java是强类型
  • 特点 :1.信息的动态交互;2.安全性,不允许直接访问本地硬盘;3.跨平台性,只要是可以解释js的浏览器都可以执行,和平台无关
  • src属性专门用来引入js文件路径(可以是相对路径或者绝对路径)

变量

在这里插入图片描述

  • typeof()函数 判断变量的类型

比较运算

在这里插入图片描述

逻辑运算

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

数组

  • var arr = [];
  • var arr = [1,'abc',true];
  • js语言中的数组,只要我们通过数组下标赋值,那么最大的下标值,就会自动给数组做扩容操作

函数

  • 在java中函数允许重载,但是在js中函数的重载会直接覆盖掉上一次的定义

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

  • 函数的隐形参数 arguments(只在function函数内)

JS中的自定义对象

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

js中的事件

  • 事件 : 电脑输入设备与页面进行交互的响应

常用的事件 :

  • onload 加载完成事件;页面加载完成后,常用于做页面js代码初始化操作
  • onclick 单击事件;常用于按钮的点击响应操作
  • onblur 失去焦点事件;常用于输入框失去焦点后验证其输入内容是否合法
  • onchange 内容发生改变事件;常用于下拉列表和输入框内容发生改变后操作
  • onsubmit 表单提交事件;常用于表单提交前,验证所有表单项是否合法

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

  • 阻止表单提交 :
  • 静态注册 : 在标签属性中的onsubmit中 不仅要在函数中return false,在调用函数的前面,还要加上一个return!
  • 动态注册 : 直接在 标签对象 的函数中return false 即可

DOM模型

  • DOM全称是 Document Object Model 文档对象模型
  • 就是把文档中的 标签,属性,文本 转换成对象来管理
  • document对象 的理解 :
    1.document管理了所有的html文档内容
    2.document是一种 树结构 的文档,有层级关系
    3.它让我们把所有的标签 都 对象化
    4.我们可以通过document访问所有的标签对象
  • 正则表达式RegExp :
    1.表示要求字符串中,是否包含字母e :
    1)var patt = new RegExp(“e”);
    2)var patt = /e/;
    3)以上两种皆为 正则表达式对象
    4)验证方法 :
    var str = “abcd”;
    alert(patt.test(str));
    2.表示要求字符串中,是否包含字母a或b或c : var patt = /[abc]/;
    3.表示要求字符串中,是否包含任意小写字母 : var patt = /[a-z]/;
    4.表示要求字符串中,是否包含任意数字 : var patt = /[0-9]/;
    5.元字符中 \w 用于查找单词字符(a-z,A-Z,0-9,下划线);因此,var patt = /\w/; 表示要求字符串中,是否包含字母,数字,下划线; \W 查找 非单词字符
    6.量词中 a+ ,var patt = /a+/;表示要求字符串中,是否包含至少一个a;var patt = /a*/;表示字符串中是否包含零个 或 多个a;var patt = /a?/;表示字符串中是否包含零个 或 一个a;var patt = /a{3}/;表示字符串中是否包含连续三个a

在这里插入图片描述

  • document.getElementByName() :根据指定的name属性查询返回多个标签对象集合;这个集合的操作和数组一样;集合中每个元素都是dom对象;这个集合中的元素顺序是他们在html页面中从上到下的顺序
  • document.getElementByTagName() :按照指定标签名来进行查询并返回集合;同上
  • document对象的三个查询方法,如果有id属性,优先使用ById;如果没有id属性,则优先使用ByName;最后才用TagName
  • 以上三个方法一定要在页面加载完成之后执行,才能查询到标签对象

节点的常用属性和方法

  • 方法 :
    appendChild(divObj)
    document.createElement(tagName) 通过给定的标签名,创建一个标签对象
  • 属性 :
    childNodes 获取当前节点的所有子节点
    firstChild
    lastChild
    parentNode
    nextSibling
    previousSibling
    className 获取或设置标签的class属性值
    innerHtml 内容
    innerText 文本

jQuery

  • 引入jQeury库,<script type="text/javascripy" src="../script/jquery-1.7.2.js"></script>
  • $(function () {}); 表示 页面加载完成之后,相当于window.onload = function () {}
  • var $btnObj = $("#btnId"); 表示按id查询标签对象
  • $btnObj.click(function () {alert("");}); 绑定单击事件

$是jQeury的核心函数
传入参数为 函数 时 :表示页面加载完成之后,相当于window.onload = function () {}
传入参数为 HTML字符串 时 :会对我们创建这个html标签对象
传入参数为 选择器字符串 时 :id选择器、标签名选择器、类型选择器
传入参数为 DOM对象 时 : 会把这个dom对象转换为jQeury对象

jQeury对象和dom对象区分
在这里插入图片描述
在这里插入图片描述

  • jQeury对象的本质 :是dom对象的数组 + jQeury提供的一系列功能函数
  • jQeury对象不能使用DOM对象的属性和方法;DOM对象也不能使用jQeury…

dom对象转化为jQeury对象
1.先有dom对象
2.$(dom对象);就可以

jQeury对象转化为dom对象
1.先有jQeury对象
2.jQeury对象[下标]取出相应的dom对象

基础选择器
在这里插入图片描述
层级选择器
在这里插入图片描述
基本过滤选择器
在这里插入图片描述
内容过滤选择器
在这里插入图片描述
属性过滤选择器
在这里插入图片描述
表单过滤选择器
在这里插入图片描述

筛选元素
在这里插入图片描述
属性的操作
在这里插入图片描述
在这里插入图片描述
dom的增删改
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
CSS样式操作
在这里插入图片描述
jQeury动画
在这里插入图片描述
jQeury事件操作
在这里插入图片描述
在这里插入图片描述
jQeury中其他事件的处理方法
在这里插入图片描述
事件冒泡
在这里插入图片描述
事件对象
在这里插入图片描述

XML

在这里插入图片描述

<?xml version="1.0" encoding="utf-8" ?>
<!--
    <?xml version="1.0" encoding="utf-8" ?>
    以上内容就是xml文件的声明
    version="1.0"   version表示xml的版本
    encoding="utf-8"  encoding表示xml文件本身的编码
-->

<books>
    <book sn="1">
        <name>时间简史</name>
        <author>霍金</author>
        <price>100</price>
    </book>
    <book sn="2">
        <name>java</name>
        <author>teacher</author>
        <price>120</price>
    </book>
</books>

在这里插入图片描述
xml解析技术介绍

  • 不管是html文件还是xml文件它们都是标记型文档,都可以使用w3c组织制定的dom技术来解析
package com.atguigu.pojo;

import java.math.BigDecimal;

public class Book {
    private String sn;
    private String name;
    private BigDecimal price;
    private String author;

//    control + enter 快速生成函数


//    constructor -> a全选 -> ok
    public Book(String sn, String name, BigDecimal price, String author) {
        this.sn = sn;
        this.name = name;
        this.price = price;
        this.author = author;
    }

    @Override
    public String toString() {
        return "Book{" +
                "sn='" + sn + '\'' +
                ", name='" + name + '\'' +
                ", price=" + price +
                ", author='" + author + '\'' +
                '}';
    }

    //    constructor -> select none
    public Book() {
    }

    public String getSn() {
        return sn;
    }

    public void setSn(String sn) {
        this.sn = sn;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public BigDecimal getPrice() {
        return price;
    }

    public void setPrice(BigDecimal price) {
        this.price = price;
    }

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }
}

package com.atguigu.pojo;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.junit.jupiter.api.Test;

import java.util.List;

public class Dom4jTest {

    @Test
    public void test1() throws DocumentException {
        SAXReader saxReader = new SAXReader();

//        Document document = saxReader.read("src/books.xml");
        Document read = saxReader.read("src/books.xml");

//        System.out.println(document);
    }


    @Test
    public void test2() throws DocumentException {
        SAXReader reader = new SAXReader();
        Document document = reader.read("src/books.xml");
        Element rootElement = document.getRootElement();

//        System.out.println(rootElement);
        List<Element> books = rootElement.elements("book");

        for (Element book : books) {
//            System.out.println(book.asXML());
//            Element name = book.element("name");
//            System.out.println(name.asXML());
//            String text = name.getText();
//            System.out.println(text);
            String price = book.elementText("price");
            System.out.println(price);
        }
    }
}

JavaWeb

Web资源的分类

  • web资源按实现的技术和呈现的效果的不同,又分为静态资源和动态资源两种
  • 静态资源 :html、css、js、txt、mp4视频、jpg图片
  • 动态资源 :jsp页面、Servlet程序

常用的Web服务器
Tomcat :一种Web服务器,提供对jsp和Servlet的支持,它是一种轻量级的javaWeb容器(服务器),也是当前应用最广的JavaWeb容器(服务器)

Tomcat服务器和Servlet版本的对应关系
在这里插入图片描述
Tomcat目录介绍
bin 专门用来存放tomcat服务器的可执行程序
conf 专门用来存放tomcat服务器的配置文件
lib 专门用来存放tomcat服务器的jar包
logs 专门用来存放tomcat服务器运行时输出的日记信息
temp 专门用来存放tomcat服务器运行时产生的临时数据
webapps 专门用来存放部署的web工程
work 是tomcat工作时的目录,用来存放tomcat运行时jsp翻译为servlet的源码,和session钝化的目录

在这里插入图片描述

如何在idea中部署工程到tomcat上运行

建议修改web工程对应的tomcat运行实例名称

Servlet 01

0.jsp,servlet,tomcat的关系

  • tomcat是web服务器(javaweb项目常用tomcat),servlet在tomacat中能运行,jsp是一种servlet
  • 浏览器是向服务器(tomcat)发出请求,然后tomcat根据浏览器的请求,派出对应的servlet去处理这些请求,在处理后,servlet得到一系列处理后的数据,然后将这个数据交给jsp,让jsp显示出来给用户看到
  • 在servlet中通过流将html代码输出给客户端(然后由客户端也就是浏览器渲染结果,所以并不是浏览器执行java代码),为了方便就诞生了jsp(本质上就是servlet),jsp中可以抛开java代码,直接使用html标签编写代码,这样就很好的将java代码和html代码分离,但其实jsp最终运行时会被编译成servlet

什么是Servlet

Servlet是JavaEE规范之一。规范 就是 接口
Servlet是JavaWeb三大组件之一。三大组件分别是 :Servlet程序、Filter过滤器、Listener监听器
Servlet是运行在服务器上的一个java小程序,它可以接收客户端发来的请求,并相应数据给客户端

手动实现Servlet程序

1.编写一个类去实现Servlet接口
2.实现service方法,处理请求,并相应数据
3.到web.xml中去配置servlet程序的访问地址

package com.atguigu.servlet;

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

public class HelloServlet implements Servlet {
    @Override
    public void init(ServletConfig servletConfig) throws ServletException {

    }

    @Override
    public ServletConfig getServletConfig() {
        return null;
    }

    /**
     * service方法 专门用来处理请求和响应的
     * @param servletRequest
     * @param servletResponse
     * @throws ServletException
     * @throws IOException
     */
    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
//        System.out.println("HelloServlet 被访问了");
        System.out.println("this is the service method");
    }

    @Override
    public String getServletInfo() {
        return null;
    }

    @Override
    public void destroy() {

    }
}

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

    <!-- servlet标签给tomcat配置servlet程序 -->
    <servlet>
        <!-- servlet-name标签 给Servlet程序起一个别名(一般是类名) -->
        <servlet-name>HelloServlet</servlet-name>
        <!-- servlet-class 是Servlet程序的全类名 -->
        <servlet-class>com.atguigu.servlet.HelloServlet</servlet-class>
    </servlet>


    <!-- servlet-mapping标签给servlet程序配置访问地址 -->
    <servlet-mapping>
        <!-- servlet-name标签的作用是告诉服务器,我当前配置的地址给哪个servlet程序使用 -->
        <servlet-name>HelloServlet</servlet-name>
        <!-- url-pattern标签配置访问地址
               / 斜杠在服务器解析的时候,表示地址为:http://ip:port/工程路径
               /hello 表示地址为:http://ip:port/工程路径/hello
         -->
        <url-pattern>/hello</url-pattern>
    </servlet-mapping>

</web-app>

<!-- 常见错误1:url-pattern中配置的路径没有以斜杠打头 Invalid <url-pattern> hello in servlet mapping -->
<!-- 常见错误2:servlet-name配置的值不存在 Servlet mapping specifies an unknown sevlet name HelloServlet1 -->
<!-- 常见错误3:servlet-class标签的全类名配置错误 java.lang.ClassNotFoundException: com.atguigu.sssss.HelloServlet(写的时候直接输入Hello就会自己补全) -->

url地址如何定位到Servlet程序去访问 :
在这里插入图片描述

  • 在localhost中,一个程序可以占用多个端口号,但是一个端口号唯一标识一个程序

Servlet的生命周期

1.执行Servlet构造器方法
2.执行init初始化方法
第一、二步是在,第一次访问的,的时候 创建servlet程序会调用
3.执行service方法
第三步,每次访问都会调用
4.执行destroy销毁方法
第四步,在web工程停止的时候调用

package com.atguigu.servlet;

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

public class HelloServlet implements Servlet {

	// Constructor方法(一开始点“实现方法”后这个不会出现,要另外再添加)
    public HelloServlet() {
        System.out.println("1 构造器方法");
    }

    @Override
    public void init(ServletConfig servletConfig) throws ServletException {
        System.out.println("2 init初始化方法");
    }

    @Override
    public ServletConfig getServletConfig() {
        return null;
    }

    /**
     * service方法 专门用来处理请求和响应的
     * @param servletRequest
     * @param servletResponse
     * @throws ServletException
     * @throws IOException
     */
    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
//        System.out.println("HelloServlet 被访问了");
        System.out.println("3 service方法 -- HelloServlet被访问了");
    }

    @Override
    public String getServletInfo() {
        return null;
    }

    @Override
    public void destroy() {
        System.out.println("4 destroy销毁方法");
    }
}

// console output
1 构造器方法
2 init初始化方法
3 service方法 -- HelloServlet被访问了
3 service方法 -- HelloServlet被访问了
3 service方法 -- HelloServlet被访问了
3 service方法 -- HelloServlet被访问了
3 service方法 -- HelloServlet被访问了
3 service方法 -- HelloServlet被访问了
3 service方法 -- HelloServlet被访问了

  • 因此发现是 单例模式

请求的分发处理

  • 问题 :service方法只有一个,而我们的请求有两种,一种是get,一种是post
  • 第1步,在 webapp 下创建一个 a.html ,里面有一个form表单,填入action属性(/hello)和method属性,form表单中有一个提交按钮
  • 第2步,启动服务器后,在工程后面加上/a.html,进入了http://localhost:8080/_servlet/a.html,然后按下提交按钮,就会进入hello,也就是http://localhost:8080/_servlet/hello?
  • 只有在点下按钮,进入到hello以后,Server才会输出“11111 Constructor
    22222 init
    33333 service – HelloServlet被访问啦“
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <form action="http://localhost:8080/_servlet/hello" method="get">
        <!-- input:submit 然后tab -->
        <input type="submit">
    </form>
</body>
</html>
  • 将get改成post后,要记得刷新网页(但居然不需要重启服务器)
  • 改成post后,同样的操作,点了按钮后,会进入http://localhost:8080/_servlet/hello,同时,Server会输出"33333 service – HelloServlet被访问啦",service一样的被使用了
  • 问题 :一般情况下,get和post请求是不一样的,因此,在service方法中要写不同
    在这里插入图片描述
  • 发现ServletRequest类无法直接使用getMethod方法
  • 查看子类 快捷键 :在HelloServlet.java中 鼠标选中 service方法中的 ServletRequest,然后control + h,然后显示该类(?)的层次结构,可以看到ServletRequest还有一个HttpServletRequest子类,点击后,看到里面有一个String getMethod()方法,也就是说子类可以
  • 因此,类型转换,将它转换为子接口(注意到这里是向下转型?,但本质上还是向上转型,接口的实现类就是它的子类,子类的对象就是该接口的子类对象),(快捷方式,先打出HttpServletRequest httpServletRequest = servletRequest;,然后option + enter,自动补全为HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
  • httpServletRequest.getMethod()后再option + enter然后补全为String method = httpServletRequest.getMethod();
@Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {

        // 类型转换(因为它有getMethod()方法)
        HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;

        // 获取请求的方式
        String method = httpServletRequest.getMethod();

        System.out.println(method);
    }
  • 然后 重启服务器,再在a.html中点击按钮后,Server中就会输出“POST“
  • 因此说明我们已经可以得到method了,那么就可以根据method的不同类型来作出不同代码
@Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
        String method = httpServletRequest.getMethod();

        if ("POST".equals(method)) {
            System.out.println("post请求");
        } else {
            System.out.println("get请求");
        }
    }
  • 如果if里执行的语句太多,显得很臃肿;因此,我们采用 封装 的思想,将if中语句换成函数
@Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
        String method = httpServletRequest.getMethod();

        if ("POST".equals(method)) {
            doPost();
        } else {
            doGet();
        }
    }
    
    public void doPost()
    {
        System.out.println("this is Post");
        System.out.println("ohayo!");
    }
    
    public void doGet()
    {
        System.out.println("this is Get");
        System.out.println("ohayo!");
    }

通过继承HttpServlet类来实现Servlet程序

  • 实际开发中,很少通过 “通过实现Servlet接口” 的方式来实现Servlet程序
  • 开发时,一般都是导入他的子类去继承即可
  • 一般在实际开发中,都是使用继承HttpServlet类的方法去实现Servlet程序
    1.编写一个类来继承HttpServlet类
    2.根据业务需求重写doGet()和doPost()方法
    3.到web.xml中配置Servlet程序的访问地址
package com.atguigu.servlet;

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

public class HelloServlet2 extends HttpServlet {


    /**
     * 第一步,control + enter 然后点击 "重写方法"也就是 Overrride Methods
     * 第二部,按住 command ,然后就可以同时选择doGet()和doPost()
     * @param req
     * @param resp
     * @throws ServletException
     * @throws IOException
     */
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//        super.doGet(req, resp);
        System.out.println("this is HelloServlet2 - get");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//        super.doPost(req, resp);
        System.out.println("this is HelloServlet2 - post");
    }
}

<!-- 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">
    
    <servlet>
        <servlet-name>HelloServlet</servlet-name>
        <servlet-class>com.atguigu.servlet.HelloServlet</servlet-class>
    </servlet>
    
    <servlet-mapping>
        <servlet-name>HelloServlet</servlet-name>
        <url-pattern>/hello</url-pattern>
    </servlet-mapping>
    
    <servlet>
        <servlet-name>HelloServlet2</servlet-name>
        <servlet-class>com.atguigu.servlet.HelloServlet2</servlet-class>
    </servlet>
    
    <servlet-mapping>
        <servlet-name>HelloServlet2</servlet-name>
        <url-pattern>/hello2</url-pattern>
    </servlet-mapping>
    
</web-app>
<!-- 修改html中表单的action属性 -->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <form action="http://localhost:8080/_servlet/hello2" method="post">
        <!-- input:submit 然后tab -->
        <input type="submit">
    </form>
</body>
</html>
  • 然后 重启服务器;就可以显示啦
  • 我们注意到在这个编写的继承类中,我们直接只需要重写doGet方法即可,不需要再得到method,然后ifelse

使用IDEA创建Servlet程序

  • 第一步,点击要在哪个包中编写这个类,然后
    在这里插入图片描述
    在这里插入图片描述
  • 会自动创建这个类(里面有准备好doGet方法和doPost方法的重写),以及在web.xml中自动配置(但要自行写serlet-mapping)
    在这里插入图片描述

整个Servlet类的继承体系

在这里插入图片描述

ServletConfig类使用介绍

在这里插入图片描述
关于初始化参数init-param
在这里插入图片描述

  • 且这个init-param在一个servlet标签中可以有多对
    在这里插入图片描述
  • servletConfig可以在HelloServlet的init初始化方法中使用

在这里插入图片描述

HelloServlet程序的别名是:HelloServlet
初始化参数username的值是:root
org.apache.catalina.core.ApplicationContextFacade@7602e52f

ServletConfig类的补充说明

  • Servlet程序和ServletConfig对象都是由Tomcat负责创建,我们负责使用
  • Servlet程序默认是第一次访问的时候创建,ServletConfig是每个Servlet程序创建时,就创建一个对应的ServletConfig对象
  • servletconfig还可以在除了init外使用 :
    在这里插入图片描述
    在这里插入图片描述
  • 重写 init方法后(init中只放了一个sout),在doGet方法中通过servletConfig获得init-param就会有 空指针异常
  • 注意,在重写了init方法后,一定要在里面调用super.init(config);,就不会报空指针异常
  • 原因 :doGet方法中的 getServletConfig()是从哪里来的呢?发现是从GenericServlet这个类的方法,而GenericServlet类持有一个ServletConfig类的引用;发现在GenericServlet类中的init方法有一个this.config = config;是将config保存起来,那我们如果重写不就没有了吗,那么父类中init的保存就消失了,因此,要写上super

在这里插入图片描述

  • 按住command 鼠标移到方法上 就可以查看 所在的类中这个方法的位置

ServletContext对象的介绍

在这里插入图片描述

ServletContext对象作用的演示

在这里插入图片描述

  • 先在web.xml中配置好ContextServlet程序的mapping 以及 上下文参数context-param
<?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">

    <!-- context-param是上下文参数(它属于整个web工程,与servlet并列) -->
    <context-param>
        <param-name>username</param-name>
        <param-value>context</param-value>
    </context-param>

    <!-- context-param也可以拥有多对 -->
    <context-param>
        <param-name>password</param-name>
        <param-value>root</param-value>
    </context-param>

	<servlet>
    	...
</web-app>
  • 然后,通过 ServletConfig 来获得 ServletContext 对象
  • 有一个小细节,这个代码只能写在doGet中,写在doPost中是不会在Server中输出语句的
  • context.getInitParameter()只能得到context-param,不能得到servlet中的init-param(只能由ServletConfig的getInitParameter()得到)
package com.atguigu.servlet;

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

public class ContextServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        // 1.获取web.xml中配置的上下文参数context-param
        ServletContext context = getServletConfig().getServletContext();

        String username = context.getInitParameter("username");
        System.out.println("context-param的参数username的值是:" + username);
        System.out.println("context-param的参数password的值是:" + context.getInitParameter("password"));

        // 2.获取当前的工程路径,格式:/工程路径
        System.out.println("当前工程路径:" + context.getContextPath());

        // 3.获取工程部署后在服务器硬盘的绝对路径
        /**
         *  /斜杠 被服务器解析地址为: http://ip:port/工程名/  映射到 IDEA代码的web目录
         */
        System.out.println("工程部署的路径是:" + context.getRealPath("/"));
        System.out.println("工程下css目录的绝对路径是:" + context.getRealPath("/css"));
//        System.out.println("工程下imgs目录1.jpg的绝对路径是:" + context.getRealPath("/imgs/1.jpg"));
    }

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

<!-- Server输出的内容 -->
context-param的参数username的值是:context
context-param的参数password的值是:root
当前工程路径:/_servlet
工程部署的路径是:/Users/fieldxia/Desktop/JavaWeb/_servlet/target/_servlet-1.0-SNAPSHOT/
工程下css目录的绝对路径是:/Users/fieldxia/Desktop/JavaWeb/_servlet/target/_servlet-1.0-SNAPSHOT/css

ServletContext像map一样存取数据

public class ContextServlet1 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 获取ServletContext对象
        ServletContext context = getServletContext();

        System.out.println("保存之前:Context1 获取key1的值为:" + context.getAttribute("key1"));

        context.setAttribute("key1", "value1");

        System.out.println("Context1 中获取域数据key1的值为:" + context.getAttribute("key1"));
        System.out.println("Context1 中获取域数据key1的值为:" + context.getAttribute("key1"));
    }
}

public class ContextServlet2 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        ServletContext context = getServletContext();

        System.out.println("Context2 中获取域数据key1的值为:" + context.getAttribute("key1"));
    }
}
<!-- 只访问了/context1 -->
保存之前:Context1 获取key1的值为:null
Context1 中获取域数据key1的值为:value1
Context1 中获取域数据key1的值为:value1
<!-- 在访问了/context1后再访问了/context2 -->
保存之前:Context1 获取key1的值为:null
Context1 中获取域数据key1的值为:value1
Context1 中获取域数据key1的值为:value1
14-Mar-2022 19:45:37.570 信息 [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory 把web 应用程序部署到目录 [/Users/fieldxia/Downloads/apache-tomcat-8.5.75/webapps/manager]
14-Mar-2022 19:45:37.601 信息 [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Web应用程序目录[/Users/fieldxia/Downloads/apache-tomcat-8.5.75/webapps/manager]的部署已在[30]毫秒内完成
Context2 中获取域数据key1的值为:value1
<!-- 再访问一次/context1 -->
保存之前:Context1 获取key1的值为:null
Context1 中获取域数据key1的值为:value1
Context1 中获取域数据key1的值为:value1
14-Mar-2022 19:45:37.570 信息 [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory 把web 应用程序部署到目录 [/Users/fieldxia/Downloads/apache-tomcat-8.5.75/webapps/manager]
14-Mar-2022 19:45:37.601 信息 [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Web应用程序目录[/Users/fieldxia/Downloads/apache-tomcat-8.5.75/webapps/manager]的部署已在[30]毫秒内完成
Context2 中获取域数据key1的值为:value1
保存之前:Context1 获取key1的值为:value1
Context1 中获取域数据key1的值为:value1
Context1 中获取域数据key1的值为:value1
  • 因为 “ServletContext是在web1工程部署启动的时候创建。在web工程停止的时候销毁“
  • 因此, 如果 重新部署一次,或者重启这个工程,那么web工程就停止了,里面的数据就没有了
public class ContextServlet1 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 获取ServletContext对象
        ServletContext context = getServletContext();

        System.out.println(context);
    }
}
public class ContextServlet2 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        ServletContext context = getServletContext();

        System.out.println(context);
    }
}
<!-- 一个web工程,只有一个ServletContext对象实例 -->
org.apache.catalina.core.ApplicationContextFacade@4f419be1
14-Mar-2022 19:53:39.424 信息 [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory 把web 应用程序部署到目录 [/Users/fieldxia/Downloads/apache-tomcat-8.5.75/webapps/manager]
14-Mar-2022 19:53:39.467 信息 [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Web应用程序目录[/Users/fieldxia/Downloads/apache-tomcat-8.5.75/webapps/manager]的部署已在[43]毫秒内完成
org.apache.catalina.core.ApplicationContextFacade@4f419be1

什么是HTTP协议

在这里插入图片描述

GET请求HTTP协议内容介绍

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

POST请求HTTP协议内容介绍

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

  • 注意要点了提交按钮以后才会是POST请求,直接在a.html录制还是GET请求

在这里插入图片描述

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

常用请求头

在这里插入图片描述

哪些是GET请求,哪些是POST请求

在这里插入图片描述

响应的HTTP协议介绍

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

常见的响应状态码说明

在这里插入图片描述

MIME数据类型

在这里插入图片描述

谷歌浏览器和火狐浏览器如何查看HTTP协议内容

在这里插入图片描述

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

  • 状态码304 点击 Disable Cache停用缓存 状态码200

在这里插入图片描述

Servlet 02

HttpServletRequest类的介绍

在这里插入图片描述

Request常用API的演示

在这里插入图片描述

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

        // 获取请求的资源路径
        System.out.println("URI => " + req.getRequestURI());

        // 获取请求的统一资源定位符(绝对路径)
        System.out.println("URL => " + req.getRequestURL());

        // 获取客户端的ip地址
        /**
         * 在IDEA中 使用 localhost 访问时 得到的客户端ip地址是 => 127.0.0.1
         * 因此 将 "http://localhost:8080/_servlet02/requestAPIServlet"
         * 改成 "http://127.0.0.1:8080/_servlet02/requestAPIServlet" 也可以访问
         * 在IDEA中 使用 127.0.0.1 访问时 得到的客户端ip地址是 => 127.0.0.1
         * 在IDEA中 使用 真实ip 访问时 得到的客户端ip地址是 => 真实的客户端 ip地址
         */
        System.out.println("客户端 ip地址 => " + req.getRemoteHost());

        // 获取请求头
        System.out.println("请求头User-Agent => " + req.getHeader("User-Agent"));

        // 获取请求的方式 GET 或 POST
        System.out.println("请求的方式 => " + req.getMethod());
    }
}
URI => /_servlet02/requestAPIServlet
URL => http://localhost:8080/_servlet02/requestAPIServlet
客户端 ip地址 => 0:0:0:0:0:0:0:1
请求头User-Agent => Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.99 Safari/537.36
请求的方式 => GET

获取请求的参数值-补充

<!-- form.html -->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
  <form action="http://localhost:8080/_servlet02/parameterServlet" method="get">
    用户名:<input type="text" name="username"> <br/>
    密码:<input type="password" name="password"> <br/>
    兴趣爱好:<input type="checkbox" name="hobby" value="cpp">C++
    <input type="checkbox" name="hobby" value="java">Java
    <input type="checkbox" name="hobby" value="js">JS<br/>
    <input type="submit">
  </form>
</body>
</html>
public class ParameterServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 获取请求参数
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        String hobby = req.getParameter("hobby");

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

在这里插入图片描述
跳转至http://localhost:8080/_servlet02/parameterServlet?username=javaweb&password=123456&hobby=cpp&hobby=java

<!-- Server -->
username: javaweb
password: 123456
hobby: cpp
  • 以上hobby的做法是错的,这样兴趣爱好多选只会返回一个值,应该将getParameter换成getParameterValues
public class ParameterServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 获取请求参数
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        String[] hobby = req.getParameterValues("hobby");

        System.out.println("username: " + username);
        System.out.println("password: " + password);
        System.out.println("hobby: " + Arrays.asList(hobby));
    }
}

在这里插入图片描述

http://localhost:8080/_servlet02/parameterServlet?username=123&password=123456&hobby=cpp&hobby=java&hobby=js

<!-- Server -->
username: 123
password: 123456
hobby: [cpp, java, js]

解决POST请求中文乱码问题

  • 如果在 用户名text 中输入中文的时候,如果method="get"不会有问题,但如果method="post",不是中文没有问题,但一旦是中文,getParameter时输出就变成乱码
  • 我们只需要一个操作
  • 注意!!!必须在获取请求参数之前调用才有效。比如说我先调用pasword的参数,然后才设置utf-8,然后再调用username,如果是post且中文,还是会乱码
@Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        // 设置请求体的字符集为UTF-8,从而解决post请求的中文乱码问题
        // 也要在获取请求参数之前调用才有效
        req.setCharacterEncoding("UTF-8");

        String username = req.getParameter("username");
        String password = req.getParameter("password");
        String[] hobby = req.getParameterValues("hobby");

        System.out.println("username: " + username);
        System.out.println("password: " + password);
        System.out.println("hobby: " + Arrays.asList(hobby));
    }

请求的转发

在这里插入图片描述

在这里插入图片描述

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

        // 获取请求的参数(办事的材料)查看
        String username = req.getParameter("username");
        System.out.println("在Servlet1(柜台1)中查看参数(材料): " + username);

        // 给材料 盖一个章,并传递到Servlet2(柜台2)去查看
        req.setAttribute("key1", "柜台1的章");

        // 问路:Servlet2(柜台2)怎么走
        /**
         * 请求转发必须要以斜杠打头, / 斜杠 表示地址为: http://ip:port/工程名/ ,映射到IDEA代码的web目录
         */
        RequestDispatcher requestDispatcher = req.getRequestDispatcher("/servlet2");

        // 走向Servlet2(柜台2)
        requestDispatcher.forward(req,resp);
    }
}
public class Servlet2 extends HelloServlet {
    @Override
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
        // 获取请求的参数(办事的材料)查看
        String username = request.getParameter("username");
        System.out.println("在Servlet2(柜台2)中查看参数(材料): " + username);

        Object key1 = request.getAttribute("key1");
        System.out.println("柜台1是否有章:" + key1);

        // 处理自己的业务
        System.out.println("Servlet2 处理自己的业务");
    }
}
<!-- Server -->
在Servlet1(柜台1)中查看参数(材料): null
在Servlet2(柜台2)中查看参数(材料): null
柜台1是否有章:柜台1的章
Servlet2 处理自己的业务

  • 发现输入的前两句为null,因为我们在转入/servlet1的时候,没有传入参数
  • 若输入http://localhost:8080/_servlet02/servlet1?username=wzg168来访问,则Server打印 :
在Servlet1(柜台1)中查看参数(材料): wzg168
在Servlet2(柜台2)中查看参数(材料): wzg168
柜台1是否有章:柜台1的章
Servlet2 处理自己的业务

在这里插入图片描述

  • 第三个特点体现在上述代码中key1的传递

  • web-inf是受服务器保护的,客户端不能直接访问,但可以通过服务器中的资源进行间接访问

  • 比如如果我们把form.html放到web-inf下
    在这里插入图片描述

  • 这样的话,访问/servlet1也显示form.html的表单的内容 :
    在这里插入图片描述

在这里插入图片描述

base标签的作用

在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <!-- base标签设置页面相对路径工作时参照的地址 -->
    <base href="http://localhost:8080/_servlet02/a/b/c.html">
    <!-- 可以省略为“http://localhost:8080/_servlet02/a/b/“,但斜杠不能去掉,因为斜杠说明b是一个目录,而不是一个资源路径 -->
</head>
<body>
  这是a下的b下的c.html页面 <br>
  <a href="../../index.html">跳回首页</a>
  <!-- http://localhost:8080/_servlet02/a/b/c.html../../index.html -->
  <!-- http://localhost:8080/_servlet02/index.html -->
</body>
</html>

回顾javaweb中的路径

在这里插入图片描述

斜杠在web中的不同意义

在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>首页</title>
</head>
<body>
  这是Web下的index.html <br>
  <a href="a/b/c.html">a/b/c.html</a> <br>
  <a href="http://localhost:8080/_servlet02/forwardC">请求转发:a/b/c.html</a>
  <a href="/">斜杠</a>
</body>
</html>
  • 点击后跳转至 http://localhost:8080/

HttpServletResponse类的介绍

在这里插入图片描述

两个响应流的介绍

在这里插入图片描述

package com.atguigu.servlet;

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

public class ResponseIOServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.getOutputStream();
        resp.getWriter();
    }
}

在这里插入图片描述

给客户端回传字符串数据

package com.atguigu.servlet;

import javax.servlet.ServletException;
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 ResponseIOServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        // 要求 :往客户端回传 字符串 数据
        PrintWriter writer = resp.getWriter();
        writer.write("response's content!!!");
    }
}

在这里插入图片描述

解决响应的中文乱码

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

        // 要求 :往客户端回传 字符串 数据
        PrintWriter writer = resp.getWriter();
        writer.write("即将出现中文乱码");
    }
}

在这里插入图片描述

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

        System.out.println(resp.getCharacterEncoding());
    }
}
  • 访问页面后,Server输出 ISO-8859-1
  • 说明,默认是ISO-8859-1,这个字符集是不支持中文的
  • 因此,我们要设置支持中文的字符集
public class ResponseIOServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        // 设置 服务器 字符集为UTF-8
        resp.setCharacterEncoding("UTF-8");

        // 通过响应头,设置 浏览器 也使用UTF-8字符集(一般是GBK
        resp.setHeader("Content-Type", "text/html; charset=UTF-8");

        
        PrintWriter writer = resp.getWriter();
        writer.write("这不是中文乱码");
    }
}

在这里插入图片描述

解决响应中文乱码问题方案二

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

        // 它会同时设置服务器和客户端都使用UTF-8字符集,还设置了响应头
        // 此方法一定要在获取流对象(PrintWriter writer = resp.getWriter();)之前使用才有效
        resp.setContentType("text/html; charset=UTF-8");

        System.out.println(resp.getCharacterEncoding());    // output:"UTF-8"
    }
}

请求重定向

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

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

        System.out.println("曾到此一游 Response1");

        // 设置响应状态码302,表示重定向(已搬迁)
        resp.setStatus(302);

        // 设置响应头,说明 新的地址在哪里
        resp.setHeader("Location", "http://localhost:8080/_servlet02/response2");
    }
}
public class Response2 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        resp.getWriter().write("response2's result!!!");
    }
}
  • 然后访问http://localhost:8080/_servlet02/response1,会自动跳转至http://localhost:8080/_servlet02/response2
    在这里插入图片描述

在这里插入图片描述

  • 关于第三个特点的解释 :
    如果在Response1中保存一些数据,比如req.setAttribute("key1", "value1"); ,然后在Response2中System.out,println(req.getAttribute("key1"));会得到null
    原因 :tomcat每次收到请求,就会把请求到的数据解析好,每次请求都会封装
  • 关于第四个特点 :
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    原因 :
    第二次请求还是客户端给服务器发的,而WEB-INF目录是受保护的,浏览器无法直接访问,第二次请求还是浏览器发过来的,还是进不来
  • 第五个特点 :
    在这里插入图片描述

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

请求重定向第二种实现方案

在这里插入图片描述

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

        resp.sendRedirect("http://localhost:8080/_servlet02/response2");
    }
}

  • 7
    点赞
  • 68
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值