IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> 【Servlet】【学习笔记】寒假javaweb学习之旅1.2 -> 正文阅读

[Java知识库]【Servlet】【学习笔记】寒假javaweb学习之旅1.2

坏了坏了,寒假快结束了,年前开始溜了,过年大溜特溜了,急了急了,这回真滴急了😭😭😭

1、Servlet初入

1.1、什么是servlet

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

1.2、第一个Servlet程序

1、编写一个类去实现Servlet接口,这里我们编写了一个HelloServlet类
2、实现service方法,处理请求,并响应数据
在这里插入图片描述
我们快速重写他的service方法,这里只是简单输出一下,只要访问HelloServlet程序,service方法就会被执行

3、到web.xml中去配置servlet程序的访问地址

<?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.flzj.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>

在工程名后面+hello,运行一下,就看到了我们之前在HelloServlet.java 重写的service方法执行了,效果不错┗|`O′|┛ 嗷~~
在这里插入图片描述

1.3、url地址访问Servlet程序图解

在这里插入图片描述客户端访问http:localhost:8080/javaweb02/hello,发送请求,localhost找到服务器ip,总所周知,电脑上有很多的软件,tomcat就是一个软件,在8080端口监听,通过8080端口和tomcat建立连接,tomcat里面跑了很多滴工程,什么javaweb02工程,ROOT工程…,\javaweb02 会找到javaweb02工程,而\hello资源路径 找到web.xml 里面的<url-pattern>/hello</url-pattern>找有没有对应的地址
在这里插入图片描述
很明显找到了,找到了后,继续往上找这个地址是给谁用的,会找到是给HelloServlet用的,接着往上找是给哪个Servlet程序用的,发现是HelloServlet程序用的,接招找,它的全名是什么,找com.flzj.servlet.HelloServlet,接招找到我们写的这个类,执行了service方法

1.4、Servlet的生命周期

1、执行 Servlet 构造器方法

2、执行 init 初始化方法

@Override
public HelloServlet() {
    System.out.println("1、执行Servlet构造器方法");
}

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

再第一次访问,的时候创建Servlet程序会调用

3、执行service方法

@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
    System.out.println("3、执行service方法");
}

每次访问都会调用

4、执行destroy销毁方法

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

web工程停止时会调用

下面是效果图,我多次刷新页面,使得service方法多次执行
在这里插入图片描述

1.5、请求的发送和处理

1.5.1、servle请求的发送和处理

表单会发送 post 和 get 的请求。我们在webapp下写个a.html,点击提交,会跳转到action指向的页面,启动servlet程序。

 <!DOCTYPE html>
 <html lang="en">
	 <head>    
		 <meta charset="UTF-8">    
		 <title>post and get</title>
	 </head>
	 <body>    
		 <form action="http://localhost:8080/javaweb02/hello" method="get">        
		 	<input type="submit">    
		 </form>
	 </body>
 </html>

在service方法可以接收并使用,传过来的请求。

🔍问题:我要怎么区别是post请求还是get请求捏

非常简单,我们只要使用ServletRequest 下的 HttpServletRequest类的getMethon方法,下面的doPost和doGet方法是我们自己写的,使代码整洁

@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
    HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
    String method = httpServletRequest.getMethod();
    if(method.equals("GET")){
        doGet();	
    }else if(method.equals("POST")){
        doPost();
    }
}
public void doGet(){
    System.out.println("get请求");
}
public void doPost(){
    System.out.println("post请求");
}

在这里插入图片描述

1.5.2、HttpServlet请求的发送和处理

开发中一般找Servlet的子类去继承,比如HttpServlet类
1、编写一个类去继承HttpServlet 类
2、根据业务需要重写doGet或doPost方法(这个直接重写方法就是比手写方便多了

package com.flzj.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 {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("doPost执行");
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("doGet执行");
    }
}

3、到web.xml中的配置Servlet 程序的访问地址

<servlet>
    <servlet-name>HelloServlet2</servlet-name>
    <servlet-class>com.flzj.servlet.HelloServlet2</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>HelloServlet2</servlet-name>
    <url-pattern>/hello2</url-pattern>
</servlet-mapping>

效果自然不在多说
在这里插入图片描述

1.5.3、使用IDEA生成servlet程序

这个操作,我称之为kami , (🙅?罕见,damei
在这里插入图片描述
生成效果自带doPost和doget方法

package com.flzj.servlet;

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

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

    }

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

    }
}

在xml这里,直接配置好了servlet,剩下只要自己写servlet-mapping即可

<servlet>
    <servlet-name>HelloServlet3</servlet-name>
    <servlet-class>com.flzj.servlet.HelloServlet3</servlet-class>
</servlet>

1.6、Servlet类的继承体系

在这里插入图片描述
我这图图改改的,本来一点都不麻的图,好像现在👴自己看了都有一点点小麻,但是聪明的同学,一定会看懂,对吧,对吧😍😍😍

1.6.1、GenericServlet 类

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

@Override
public String getInitParameter(String name) {
    return getServletConfig().getInitParameter(name);
}

抽象 service( )方法

@Override
public abstract void service(ServletRequest req, ServletResponse res)
    throws ServletException, IOException;

1.6.2、HttpService类

两个service方法,一个负责类型转换,一个负责通过

protected void service(HttpServletRequest req, HttpServletResponse resp)
        throws ServletException, IOException {

        String method = req.getMethod();

        if (method.equals(METHOD_GET)) {
            long lastModified = getLastModified(req);
            if (lastModified == -1) {
                // servlet doesn't support if-modified-since, no reason
                // to go through further expensive logic
                doGet(req, resp);
            } else {
                long ifModifiedSince;
                try {
                    ifModifiedSince = req.getDateHeader(HEADER_IFMODSINCE);
                } catch (IllegalArgumentException iae) {
                    // Invalid date header - proceed as if none was set
                    ifModifiedSince = -1;
                }
                if (ifModifiedSince < (lastModified / 1000 * 1000)) {
                    // If the servlet mod time is later, call doGet()
                    // Round down to the nearest second for a proper compare
                    // A ifModifiedSince of -1 will always be less
                    maybeSetLastModified(resp, lastModified);
                    doGet(req, resp);
                } else {
                    resp.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
                }
            }

        } else if (method.equals(METHOD_HEAD)) {
            long lastModified = getLastModified(req);
            maybeSetLastModified(resp, lastModified);
            doHead(req, resp);

        } else if (method.equals(METHOD_POST)) {
            doPost(req, resp);

        } else if (method.equals(METHOD_PUT)) {
            doPut(req, resp);

        } else if (method.equals(METHOD_DELETE)) {
            doDelete(req, resp);

        } else if (method.equals(METHOD_OPTIONS)) {
            doOptions(req,resp);

        } else if (method.equals(METHOD_TRACE)) {
            doTrace(req,resp);

        } else {
            //
            // Note that this means NO servlet supports whatever
            // method was requested, anywhere on this server.
            //

            String errMsg = lStrings.getString("http.method_not_implemented");
            Object[] errArgs = new Object[1];
            errArgs[0] = method;
            errMsg = MessageFormat.format(errMsg, errArgs);

            resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED, errMsg);
        }
    }


@Override
    public void service(ServletRequest req, ServletResponse res)
        throws ServletException, IOException {

        HttpServletRequest  request;
        HttpServletResponse response;

        try {
            request = (HttpServletRequest) req;
            response = (HttpServletResponse) res;
        } catch (ClassCastException e) {
            throw new ServletException(lStrings.getString("http.non_http"));
        }
        service(request, response);
    }

1.6.3、查看servlet源码

出现上方蓝色这条线捏,是告诉我们,要选择个tomcat的源码路径,我们选择 -src 的(可以从官网下
在这里插入图片描述在这里插入图片描述
我们只需要java的就行了,其他测试什么的,就不管了,👌ok一下效果😤😤😤
在这里插入图片描述

Library source does not match the bytecode for class xxxx

在这里插入图片描述

这个是我目前科技解释不了的问题,待我日后学有所成必须,来试试看 好像是Maven的问题

2、ServletConfig 类

ServletConfig类从类名上来看,就知道是Servlet程序的配置信息类😁

2.1、ServletConfig类作用

我们去继承了servlet类的init()方法 找参数servletConfig测试

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

1、可以获取Servlet程序的别名(servlet-name)的值

servletConfig.getServletName()

@Override
public void init(ServletConfig servletConfig) throws ServletException {
    System.out.println("servlet-name 是 : " + servletConfig.getServletName());
}

2、获取初始化参数init-param

我们广块溜到web.xml,在servlet标签里加上,这个是键值对,也可以多写几组,下面我写了2组

<servlet>
    <servlet-name>HelloServlet</servlet-name>
    <servlet-class>com.flzj.servlet.HelloServlet</servlet-class>
    <init-param>
        <param-name>username</param-name>
        <param-value>root</param-value>
    </init-param>
    <init-param>
        <param-name>url</param-name>
        <param-value>jdbc:mysql.localhost:3060</param-value>
    </init-param>
</servlet>

然后回到我们的HelloServlet类里面的init()方法来试试看

@Override
public void init(ServletConfig servletConfig) throws ServletException {
    System.out.println("username对应的值是" + servletConfig.getInitParameter("username"));
    System.out.println("url对应的值是" + servletConfig.getInitParameter("url"));

}

3、获取ServletContext对象

@Override
public void init(ServletConfig servletConfig) throws ServletException {
    System.out.println("获取ServletContext对象" + servletConfig.getServletContext());
}

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

细节

1、ServletConfig对象可以获取

下面我们在继承了HttpSevlet类的HelloServlet2类,使用了getServletConfig()方法获取到了ServletConfig对象.

public class HelloServlet2 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletConfig servletConfig = getServletConfig();
    }
}

小细节

这里就会有家人好奇了,为什么是在doGet这里重写啊,为什么我不能在doPost重写啊,根据👴的几次测试,发现这个默认访问是使用GET( QWQ 不会就我现在才发现把

👴已经粗略的学完了,👆上面不理解的内容,后面会解释

2.2、不同类的ServletConfig对象是不同的

在这里插入图片描述
这里的HelloSevlet 的ServletConfig对象和其他的类绝对是🙅?不同的,在之前,我们在web.xml下,给HelloServle配置了init-param,(username和url 忘记往上👆看),HelloServlet2👴没有给它配init-param,如果我们在HelloServlet2里给他这样写会怎么样。

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    System.out.println("doPost执行");
    ServletConfig servletConfig = getServletConfig();
    System.out.println("username对应的值是" + servletConfig.getInitParameter("username"));
    System.out.println("url对应的值是" + servletConfig.getInitParameter("url"));
}

会输出null😄 ,因此我们可以得出结论,这两个ServletConfig对象不是同一个
在这里插入图片描述

2.3、重写init()方法去掉super.init(config)

众所周知,我们的IDEA在我们重写init()方法的时候会,自动加上这个super.init(config)那么我们去掉会怎么样捏?

@Override
public void init(ServletConfig config) throws ServletException {
    //super.init(config) 我们在这里给他注释掉
    System.out.println("重写了init方法,👴不畏惧");
}

然后启动,访问会报空指针异常😰😰😰
在这里插入图片描述
这是怎么会是捏?我们广块看一看,哦哦原来是父类GenericServlet的这个init()方法给我们重写了,父类的保存操作就会丢失

@Override
public void init(ServletConfig config) throws ServletException {
    this.config = config;
    this.init();		//这里调用的是下面那个专门给我们重写的init()方法
}

真的铸币了,GenericServletl类还有一个init()方法专门是给我们重写用的
在这里插入图片描述
no need to call super.init(confing) …

3、ServletContext类

3.1、什么是ServletContext

1、ServletContext 是一个接口, 它表示Servlet上下文对象
2、一个web工程,只有一个ServletContext对象实例
3、ServletContext 对象是一个域对象

这时候肯定有家人会问了,啊啊啊啊啊啊啊啊啊啊啊啊,什么是域对象??

域对象,是可以像Map一样存取数据的对象,叫域对象。这里的域指的是存取数据的操作范围,整个web工程。

存数据取数据删数据
Mapput()get()remove()
域对象setAttribute()getAttribute()removeAttribute()

4、ServletContext是在web工程部署启动的时候创建。在web工程停止的时候销毁。

3.2、ServletContext类的四个作用

3.2.1、获取web.xml中配置的上下文参数context-param

首先我们要去web.xml 里面写,这个也是键值对,可以有多组。context-param是上下文参数(它属于整个web工程)

<?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>
            <param-name>username</param-name>
            <param-value>context</param-value>
        </context-param>
        <context-param>
            <param-name>password</param-name>
            <param-value>root</param-value>
        </context-param>
    ...

ContextServlet类里面doGet()方法我们重写下

@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    //获取ServletContext对象 也可以直接getServletContext() 3.2.4解释原因
    ServletContext servletContext = getServletConfig().getServletContext();
    //调用servletContext.getInitParameter()方法获取对应的值
    System.out.println("username是: " + servletContext.getInitParameter("username"));
    System.out.println("password是:" + servletContext.getInitParameter("password"));
}

3.2.2、获取当前的工程路径格式:/工程路径

getContextPath() 方法

System.out.println("当前工程路径" + servletContext.getContextPath());

3.2.3、获取工程部署后在服务器硬盘上的绝对路径

/ 被服务器解释地址为 : http://ip:port/工程名/

System.out.println("工程部署路径" + servletContext.getRealPath("/"));

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

3.2.4、像Map一样存取数据

解释下,3.2.1的问题(为什么获取ServletContext对象可以直接写getServletContext()),因为GenericServlet父类的getServletContext()方法长这样

@Override
public ServletContext getServletContext() {
    return getServletConfig().getServletContext();
}

😄下面是像Map一样溜,为了证实一个web工程,只有一个ServletContext对象实例,我们写两个类

public class ContextServlet1 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        ServletContext context = getServletContext();
        System.out.println("从ContextServlet1中提取(此时为空)"+context.getAttribute("k"));
        context.setAttribute("k","v");
        System.out.println("从ContextServlet1中提取"+context.getAttribute("k"));
    }
public class ContextServlet2 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        ServletContext context = getServletContext();
        System.out.println("从ContextServlet2中提取"+context.getAttribute("k"));
    }
}

ContextServlet2 也是提的取到ContextServlet1存的内容的
在这里插入图片描述

4、HTTP

4.1、什么是HTTP协议

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

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

所谓HTTP协议,就是指,客户端和服务器之间通信时,发送的数据,需要遵守的规则,叫HTTP协议。

HTTP协议中的数据又叫报文。

4.2、请求的HTTP协议格式

4.2.1、GET请求

组成部分

1、请求行
(1)请求的方式GET
(2)请求的资源路径[+?+请求参数]
(3)请求的协议的版本号HTTP/1.1

2、请求头
key: value组成
不同的键值对,表示不同的含义。

图解

在这里插入图片描述

4.2.2、POST请求

组成

1、请求行
(1)请求的方式POST
(2)请求的资源路径[+?+请求参数]
(3)请求的协议的版本号HTTP/1.1

2、请求头key: value不同的请求头,有不同的含义

空行

3、请求体:发送给服务器的数据

图解

在这里插入图片描述

4.2.3、常用的请求头

Accept: 表示客户端可以接收的数据类型
Accpet-Languege: 表示客户端可以接收的语言类型
User-Agent: 表示客户端浏览器的信息
Host: 表示请求时的服务器ip和端口号

4.2.4、区分GET和POST请求

GET请求有哪些:

1、form 标签method=get
2、a标签
3、link 标签引入css
4、Script 标签引入js文件
5、img标签引入图片
6、iframe 引入html页面
7、在浏览器地址栏中输入地址后敲回车

POST请求有哪些:
1、form 标签method=post

4.3、响应的HTTP协议格式

1.响应行
(1)响应的协议和版本号
(2)响应状态码
(3)响应状态描述符

2、响应头
(1) key: value 不同的响应头,有其不同含义
空行

3、响应体
回传给客户端的数据
在这里插入图片描述

常见的响应码

200 表示请求成功

302 表示请求重定向

404 表示请求服务器已经收到了,但是你要的数据不存在(请求地址错误)

500 表示服务器已经收到请求,但是服务器内部错误(代码错误)

之前的重写init()方法,导致代码出写空指针异常

在这里插入图片描述

4.4、MIME类型说明

MIME是HTTP协议中数据类型。
MIME的英文全称是"Multipurpose Internet Mail Extensions"多功能Internet邮件扩充服务。MIME类型的格式是“大类型/小类型”,并与某一种文件的扩展名相对应。

文件MIME类型
超文本标记语言文本.html ,.htm text/html
普通文本.txt text/plain
RTF文本.rtf application/rtf
GIF 图形.gif image/gif
AVI 文件.avi video/x-msvideo
TAR 文件.tar application/x-tar

4.5、如何用浏览器查看HTTP协议

在这里插入图片描述

5、HttpServletRequerst 类

每次只要有请求进入Tomcat服务器, Tomcat 服务器就会把请求过来的HTTP协议信息解析好封装到Request对象中。然后传递到service方法( doGet和doPost)中给我们使用。我们可以通过HttpServletRequest 对象,获取到所有请求的信息。

5.1、HttpServletRequerst 类的常用方法

API作用
getRequestURI( )获取请求的资源路径
getRequestURL( )获取请求的统一资源定位符(绝对路径)
getRemoteHost( )获取客户端的ip地址
getHeader( )获取请求头
getParameter( )获取请求的参数
getParameters( )获取请求的参数(多个值的时候使用)
getMethod( )获取请求的方式 GET 或 POST
setAttribute(key , value)设置域数据
getAttribute(key)获取域数据
getRequestDispatcher( )获取请求转发对象

我们刚快测试一些来试试看
在这里插入图片描述

@Override
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
    System.out.println("URI ==> " + request.getRequestURI());
    System.out.println("URL ==> " + request.getRequestURL());
    System.out.println("客户端ip地址==>" + request.getRemoteHost());
    System.out.println("请求头User-Agent==>" + request.getHeader("User-Agent"));

}

获取参数

先写一个html的表单方便测试 和 ParameterServlet类来接收数据

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>调查问卷</title>
</head>
<body>
    <form action="localhost:8080/javaweb03/parameterServlet" method="get">
        用户名<input type="text" name="username"><br/>
        密码 <input type="password" name="pwd"> <br/>
        爱好 <input type="checkbox" name="hobby" value="cpp">c++
        <input type="checkbox" name="hobby" value="java">java
        <input type="checkbox" name="hobby" value="js">javascript <br/>
        <input type="submit">
    </form>
</body>
</html>
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("用户名:" + req.getParameter("username"));
        System.out.println("密码:" + req.getParameter("pwd"));
        String[] hobby = req.getParameterValues("hobby");
        System.out.println("爱好" + Arrays.asList(hobby));
    }

在这里插入图片描述

post 请求中文乱码问题

在这里插入图片描述
我们只要设置请求体的字符集为UTF-8,setCharacterEncoding() 方法,要在获取请求参数之前调用才有效

req.setCharacterEncoding("UTF-8");

在这里插入图片描述

5.2、请求转发

5.2.1、 图解

在这里插入图片描述

5.2.2、代码实现

public class Servlet1 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1、获取请求的参数(办事的材料)查看
        String username = request.getParameter("username");
        System.out.println("在Servlet1(柜台1)中查看参数(材料)" + username);

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

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

        //4、走到servlet2(柜台2)
        requestDispatcher.forward(request,response);
    }

}
public class Servlet2 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1、获取请求的参数(办事的材料)查看
        String username = request.getParameter("username");
        System.out.println("在Servlet2(柜台2)中查看参数(材料)" + username);

        //2、查看柜台1是否有盖章
        System.out.println("柜台1盖的章是" + request.getAttribute("key1"));

        //3、servlet2处理自己的业务
        System.out.println("servlet2处理自己的业务");
    }
}

在这里插入图片描述

5.2.3、特点

1、浏览器地址栏没有发生变化

2、他们是一次请求

3、共享request域中的数据

4、可以访问到WEB-INF目录下

之前tomcat那里,我们就学习过,这个WEB-INF目录不能直接访问,比如这里面的aa.html

在这里插入图片描述

但是请求转发可以访问到,我们只要😁在servlet1这个类里面改改就行

//3、问问aa.htm怎么走
RequestDispatcher requestDispatcher = request.getRequestDispatcher("/WEB-INF/aa.html");

//4、走到aa.html
requestDispatcher.forward(request,response);

在这里插入图片描述

5、不能访问工程以外的资源

比如我们访问www.baidu.com 会
在这里插入图片描述

5.3、Servlet-base标签

base标签可以设置当前页面中所有相对路径工作时,参照哪个路径来进行跳转。

比如这里,我们写了一个html

<html lang="zh_CN">
	<head>
        <meta charset="UTF-8">
        <title>Title</title>
        <base href="http://localhost:8080/javaweb2/a/b/c.html">
	</head>
	<body>
        这是a下的b下的c.html页面 <br/>
		<a href = "../../index.html" >跳回首页</a>
	</body>
</html>

如果我们用,请求转发访问到这个页面,因为请求转发的特性(浏览器地址栏没有发生变化),所以会导致这个a标签返回的地址不正确,比如,我们需要返回到http://localhost:8080/javaweb2/index.html 但可能会从
http://localhost:8080/javaweb02/servletFoward 返回到http://localhost:8080/index.html显然这不是我们想要的。这时候加上base标签,就会解决我们的问题🌶,这个路径会变成base标签设置页面相对路径工作时参照的地址

5.4、Web种的相对路径和绝对路径

相对路径是:
.??????????表示当前目录
…???????表示上一级目录
资源名 表示当前目录/资源名

绝对路径:
http://ip:port/工程路径/资源路径

5.5、web种 \ 斜杆的不同含含义

/斜杠如果被浏览器解析,得到的地址是: htp://ip:port/

<a href="/"> 斜杠 </a>

/ 斜杠如果被服务器解析,得到的地址是: htp://ip:port/工程路径

1、<url-pattern>/serv1et1</url-pattern>
2、servletContext. getRealPath("/");
3、request. getRequestDispatcher("/");

特殊情况:

//把斜杆发给浏览器解析,得到http://ip:port/
response.sendRediect("/");		

6、HttpServletResponse

6.1、HttpServletResponse类的作用

HttpServletResponse类和HttpServletRequest类一样。每次请求进来,Tomcat 服务器都会创建一个Response对象传递给Servlet程序去使用

HttpServletRequest 表示请求过来的信息,HttpServletResponse 表示所有响应的信息,我们如果需要设置返回给客户端的信息,都可以通过HttpServletResponse对象来进行设置

6.2、两个输出流的说明

字节流??????????getOutputStream(); 常用于下载(传递二进制数据)
字符流??????????getWriter(); 常用于回传字符串(常用)
两个流同时只能使用一个。
使用了字节流,就不能再使用字符流,反之亦然,否则就会报错。

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

在这里插入图片描述

6.3、如何往客户端回传数据

public class RequestResponse_ extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        PrintWriter writer = resp.getWriter();	//获取字节流对象
        writer.print("链接成功🌶");			     //调用方法
    }
}

然后会发现中文不行🌶 ┭┮﹏┭┮ 会出现???

在这里插入图片描述

//设置服务器的字符集为UTF-8
resp.setCharacterEncoding("UTF-8");	//只加上会乱码

//通过响应头,设置浏览器使用UTF-8
 resp.setHeader("Content-Type","text/html; charset=UTF-8");

在这里插入图片描述

其实还有一种方法

// 它会同时设置服务器和客户端都使用UTF-8字符集, 还设置了响应头  需要在获取流对象前使用
resp.setContentType("text/html;charset=UTF-8");

确实是同时修改了服务器的字符集

在这里插入图片描述

浏览器我们在检查一下,嗷嗷嗷确实是这样

在这里插入图片描述

6.4、请求重定向

6.4.1、请求重定向了解

图解

在这里插入图片描述

代码实现

public class Response1 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("经过response1");
        //设置响应状态码302,表示重定向(已搬迁)
        response.setStatus(302);
        //设置响应头,说明新的地址在哪里
        response.setHeader("Location","http://localhost:8080/javaweb03/response2");
    }
}
public class Response2 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        response.getWriter().write("欢迎来到response2");
    }
}

效果图

在这里插入图片描述

特点

1、浏览器地址栏会发生变化

2、两次请求

3、不共享Request域中数据

因为每次请求进来, Tomcat 服务器都会创建一个Response对象传递给Servlet程序去使用。

4、不能访问WEB-INF下的资源

第二次请求是浏览器发起的,不能访问服务器的WEB-INF(请求转发是服务器发起的)

5、可以访问工程外的资源

道理就是浏览器发起的,所以dddd

6.4.2、请求重定向简单版

sendRedirect() 方法

public class Response1 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("经过response1");
        response.sendRedirect("http://localhost:8080/javaweb03/response2");
    }
}
  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-02-05 21:35:51  更:2022-02-05 21:36:23 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 11:00:46-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码