JavaWeb 15.详解Servlet及其源码

目录

一、Servlet简介

1.动态资源和静态资源

静态资源

动态资源

生活举例

动/静态资源的响应过程

2.Servlet简介

Servlet执行流程

Servlet作用

二、Servlet开发流程

1.目标

2.开发流程

3.问题

[① Servlet-api.jar导入问题](#① Servlet-api.jar导入问题)

[② Content-Type响应头的问题](#② Content-Type响应头的问题)

4.Servlet_url-pattern的一些特殊写法问题

url-pattern:pattern路径

三、Servlet_注解方式配置Servlet

1.@WebServlet注解源码

​编辑

2.@WebServlet注解使用

四、Servlet生命周期

1.生命周期简介

什么是Servlet的生命周期

Servlet容器

Servlet主要的生命周期执行特点

2.生命周期调试

配置Servlet

3.生命周期总结

五、Servlet继承结构

1.Servlet接口

[① void init(Servletconfig var1) throws ServletException;](#① void init(Servletconfig var1) throws ServletException;)

[② ServletConfig getServletConfig();](#② ServletConfig getServletConfig();)

[③ void service(ServletRequest var1,ServletResponse var2) throws ServletException, IOException;](#③ void service(ServletRequest var1,ServletResponse var2) throws ServletException, IOException;)

[④ String getServletInfo();](#④ String getServletInfo();)

[⑤ void destroy();](#⑤ void destroy();)

[2.抽象类 GenericServlet](#2.抽象类 GenericServlet)

[① private transient ServletConfig config;](#① private transient ServletConfig config;)

[② public GenericServlet(){}](#② public GenericServlet(){})

[⭐③ public void destroy(){}](#⭐③ public void destroy(){})

[④ public String getInitParameter(String name)](#④ public String getInitParameter(String name))

[⑤ public Enumeration getInitParameterNames()](#⑤ public Enumeration getInitParameterNames())

[⭐⑥ public ServletConfig getServletConfig()](#⭐⑥ public ServletConfig getServletConfig())

[⑦ public ServletContext getServletContext()](#⑦ public ServletContext getServletContext())

[⑧ public String getServletInfo()](#⑧ public String getServletInfo())

[⭐⑨ public void init(ServletConfig config) throws ServletException()](#⭐⑨ public void init(ServletConfig config) throws ServletException())

[⭐⑩ public void init() throws ServletException](#⭐⑩ public void init() throws ServletException)

[⑪ public void log(String msg) public void log(String message,Throwable t)](#⑪ public void log(String msg) public void log(String message,Throwable t))

[⭐⑫ public abstract void service(ServletRequest req, ServletResponse res) throws ServletException, IOException;](#⭐⑫ public abstract void service(ServletRequest req, ServletResponse res) throws ServletException, IOException;)

[⑬ public String getServletName()](#⑬ public String getServletName())

[3.抽象类 HttpServlet](#3.抽象类 HttpServlet)

4.自定义Servlet

5.掌握技能

六、ServletConfig和ServletContext

1.ServletConfig

ServletConfig是什么

ServletConfig是一个接口,定义了如下API:

2.ServletContext⭐

ServletContext是什么

ServletContext其他重要API

[① 获取资源的磁盘路径](#① 获取资源的磁盘路径)

[② 获取项目的上下文路径](#② 获取项目的上下文路径)

[③ 域对象的相关API](#③ 域对象的相关API)

七、HttpServletRequest

1.简介

HttpServletRequest是什么

2.常见API

获取请求行信息相关(请求方式,请求的url路径,协议及版本)

获得请求头信息相关:

获得请求参数相关:

其他API:

八、HttpServletResponse

1.简介

HttpServletResponse是什么

2.常见API

设置响应行相关

设置响应头相关

设置响应体相关

其他API

3.MIME类型

常见的MIME类型举例如下:

九、请求转发和响应重定向

概述

什么是请求转发和响应重定向

请求转发

请求转发运行逻辑图

请求转发特点⭐

响应重定向

响应重定向运行逻辑图

响应重定向特点⭐

十、MVC架构模式

MVC模式简介

M:Model模型层,具体功能如下

[V:View 视图层,具体功能如下](#V:View 视图层,具体功能如下)

[C:Controller 控制层,具体功能如下](#C:Controller 控制层,具体功能如下)

MVC模式下项目中的常见包

M:

C:

V:

非前后端分离的MVC

​编辑

十一、web乱码和路径问题总结

乱码问题

乱码问题产生的根本原因是什么?

HTML乱码问题

Tomcat控制台乱码

GET请求乱码

POST方式请求乱码

响应乱码问题

路径问题

相对路径和绝对路径:


所有受过的委屈,都在提醒你

要好好争气。

------ 24.10.7

一、Servlet简介

1.动态资源和静态资源

静态资源

无需在程序运行时通过代码运行生成的资源,在程序运行之前就写好的资源,例如:html、css、js、img、音频文件和视频文件

动态资源

需要在程序运行时通过代码运行生成的资源,在程序运行之前无法确定的数据,运行时动态生成,例如:Servlet、Thymeleaf、......

动态资源指的不是视图上的动画效果或者是简单的人机交互效果


生活举例

去蛋糕店买蛋糕:

静态资源:直接买柜台上的成品

动态资源:预定蛋糕,要求现场制作


动/静态资源的响应过程


2.Servlet简介

Servlet (server applet)是运行在服务端(tomcat)的Java小程序,是sun公司提供一套定义动态资源规范;从代码层面上来讲Servlet就是一个接口

不是所有的JAVA类都能用于处理客户端请求,能处理客户端请求并做出响应的一套技术标准就是Servlet

其主要功能在于交互式地浏览和修改数据,生成动态Web内容。

Servlet是运行在服务端的,所以Servlet必须在WEB项日中开发并在Tomcat这样的服务容器中运行


Servlet执行流程

① 浏览器向TomCat发送一个请求报文:请求行、请求头、请求体

② TomCat接受了请求报文,TomCat将请求报文信息转换成了一个HttpServletRequest对象,该对象中包含了请求中的所有信息:请求行、请求头、请求体

③ TomCat同时创建了一个HttpServletResponse对象,该对象用于承载要响应给客户端的信息,后面该对象会被转换成响应的报文:响应行、响应头、响应体

④ TomCat会根据请求定义一个servlet类,实现一个接口标准(implements Servlet)

⑤ TomCat根据请求中的资源路径找到对应的Servlet,将servlet实例化,调用service方法,同时将HttpServletRequest请求对象和HttpServletResponse响应对象传入

1.从request对象中获取请求的所有信息(参数)

2.根据参数生成要响应给客户端的数据

3.将响应的数据放入response对象

⑥ TomCat将response对象转换成一个响应报文发送给客户端


Servlet作用

用来接收、处理客户端请求、响应给浏览器的动态资源。在整个Web应用中,Servlet主要负责接收处理请求、协同调度功能以及响应数据。我们可以把Servlet称为Web应用中的控制器

Servlet充当一个**"中间商"**的角色,将客户端请求接收下来传递给服务端,服务端处理完成后再将处理好的响应数据传递给Servlet,然后通过Servlet将服务端的响应数据传给客户端


二、Servlet开发流程

1.目标

校验注册时,用户名是否被占用,通过客户端向一个Servlet发送请求,携带username,如果用户名是'YYSHlcl',则向客户端响应NO,如果是其他,响应YES

2.开发流程

① 创建一个JavaWeb项目,点击Project Settings同时将tomcat添加为当前项目的依赖

② 添加web资源组件

点击Help------>Find Action------>Add Frameworks support

③ 创建小表单,建立html页面

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<form method="get" action="userServlet">
    用户名:<input type="text" name="username"><br>
    <input type="submit" value="校验">
</form>

</body>
</html>

④ 重写service方法:继承HttpServlet,间接实现了service方法

传递了请求报文信息和响应报文信息

service(HttpServletRequest req,HttpServletResponse resp)

java 复制代码
public class UserServlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 1.从request对象中获取请求报文中的任何信息(username参数)
        //   根据参数名获取参数值,无论参数是在url?后,还是在请求体中
        String username = req.getParameter("username");

        // 2.处理业务的代码
        String res = "Yes";
        if("YYSHlcl".equals(username)){
            res = "No";
        }

        // 3.将要响应的数据放入response
        PrintWriter writer = resp.getWriter(); // 该方法返回的是一个向响应体中打印字符串的打印流
        writer.write(res);
    }
}

⑤ 在service方法中,定义业务处理代码

java 复制代码
        String info = "Yes";
        if("YYSHlcl".equals(username)){
            info = "No";
        }

⑥ 在Web.xml文件中,配置Servlet对应的请求映射路径

XML 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="https://jakarta.ee/xml/ns/jakartaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_6_0.xsd"
         version="6.0">
<!--
    1.配置Servlet类,并起一个别名
        servlet-name    用于关联请求的映射路径
        servlet-class   告诉Tomcat对应的要实例化的Servlet类
-->
    <servlet>
        <servlet-name>userServlet</servlet-name>
        <servlet-class>Servlet.UserServlet</servlet-class>
    </servlet>
    
    <servlet-mapping>
        <servlet-name>userServlet</servlet-name>
        <url-pattern>/userServlet</url-pattern>
    </servlet-mapping>

</web-app>

3.问题

① Servlet-api.jar导入问题

servlet-api 编码的时候需要,运行的时候,在服务器的环境中,由服务软件(Tomcat)提供

因此,我们的JAVAWEB项目中,在打包/构建的时候,是无需携带servlet-api的jar包

② Content-Type响应头的问题

MINE类型响应头 媒体类型,文件类型,响应的数据类型

MINE类型用于告诉客户端响应的数据是什么类型的数据,客户端以此类型决定用什么方式解析响应体


4.Servlet_url-pattern的一些特殊写法问题

url-pattern:pattern路径

① 精确匹配

/servlet1

② 模糊匹配

* 作为通配符,*在哪里,哪里就是模糊的

/ 匹配全部,不包含isp文件

/* 来匹配全部,包含isp文件

/a/* 匹配前缀,后缀模糊

*.action 匹配后级,前缀模糊


三、Servlet_注解方式配置Servlet

1.@WebServlet注解源码

java 复制代码
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package jakarta.servlet.annotation;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface WebServlet {
    String name() default "";

    String[] value() default {};

    String[] urlPatterns() default {};

    int loadOnStartup() default -1;

    WebInitParam[] initParams() default {};

    boolean asyncSupported() default false;

    String smallIcon() default "";

    String largeIcon() default "";

    String description() default "";

    String displayName() default "";
}


2.@WebServlet注解使用

java 复制代码
// value 和 urlpatterns表示路径名,定义一个就够了
@WebServlet(name = "servlet1",value = "/s1")
public class Servlet1 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("Servlet1执行了");
    }
}

四、Servlet生命周期

1.生命周期简介

什么是Servlet的生命周期

应用程序中的对象不仅在空间上有层次结构的关系,在时间上也会因为处于程序运行过程中的不同阶段而表现出不同状态和不同行为。这就是对象的生命周期。

简单的叙述生命周期,就是对象在容器中从开始创建到销毁的过程。


Servlet容器

Servlet对象是Servlet容器创建的,生命周期方法都是由容器(Tomcat)调用的。开发人员要尽可能多的将精力放在业务逻辑的实现上。


Servlet主要的生命周期执行特点

1.实例化 构造器 第一次请求/服务启动 1次

2.初始化 init 构造完毕 1次

3.接收请求,处理请求,服务 service 每次请求 多次

4.销毁 destroy 关闭服务 1次


2.生命周期调试

java 复制代码
package Servlet;

import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.io.IOException;

/*
    1.实例化                   构造器            第一次请求/服务启动
    2.初始化                    init            构造完毕
    3.接收请求,处理请求,服务      service          每次请求
    4.销毁                     destroy          关闭服务
 */

// 配置Servlet方式2:注解方式    配置Servlet方式1:xml文件配置信息
@WebServlet(value = "/ServletLifeCycle",loadOnStartup = 100)
public class ServletLifeCycle extends HttpServlet {
    public ServletLifeCycle() {
        System.out.println("构造器");
    }

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

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("服务");
    }

    @Override
    public void destroy(){
        System.out.println("destroy");
    }


}

配置Servlet

XML 复制代码
    <servlet>
        <servlet-name>servletLifeCycle</servlet-name>
        <servlet-class>Servlet.ServletLifeCycle</servlet-class>
        <load-on-startup>3</load-on-startup>
    </servlet>

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

3.生命周期总结

  1. 通过生命周期测试我们发现Servlet对象在容器中是单例的

  2. 容器是可以处理并发的用户请求的,每个请求在容器中都会开启一个线程

  3. 多个线程可能会使用相同的Servlet对象,所以在Servlet中,我们不要轻易定义一些容易经常发生修改的成员变量(加锁会降低性能),会引发线程安全问题

  4. default-servlet 用于加载静态资源的servlet,默认随服务启动,默认启动序号为1

  5. load-on-startup中定义的正整数表示实例化顺序,如果数字重复了,容器会自行解决实例化顺序问题,但是应该避免重复

  6. Tomcat容器中,已经定义了一些随系统启动实例化的servlet,我们自定义的servlet的load-on-startup尽量不要占用数字1-5


五、Servlet继承结构

1.Servlet接口

java 复制代码
void init(Servletconfig var1) throws ServletException;
// 初始化方法,构造完毕后,由tomcat自动调用完成初始化功能的方法

ServletConfig getServletConfig();
// 获得ServletConfig对象的方法

void service(ServletRequest var1,ServletResponse var2) throws ServletException, IOException;
// 接收用户请求,向用于响应信息的方法

String getServletInfo();
// 返回Servlet字符串形式描述信息的方法

void destroy();
// Servlet在回收前,由tomcat调用的销毁方法,往往用于做资源的释放工作

① void init(Servletconfig var1) throws ServletException;

初始化方法,构造完毕后,由tomcat自动调用完成初始化功能的方法

② ServletConfig getServletConfig();

获得ServletConfig对象的方法

③ void service(ServletRequest var1,ServletResponse var2) throws ServletException, IOException;

接收用户请求,向用于响应信息的方法

④ String getServletInfo();

返回Servlet字符串形式描述信息的方法

⑤ void destroy();

Servlet在回收前,由tomcat调用的销毁方法,往往用于做资源的释放工作


2.抽象类 GenericServlet

GenericServlet 抽象类是对Servlet接口一些固定功能的粗糙实现 ,以及对service方法的再次抽象声明,并定义了一些其他相关功能方法,侧重于除了service方法以外其他方法的处理

① private transient ServletConfig config;

初始化对象作为属性

② public GenericServlet(){}

构造器,为了满足继承而准备

⭐③ public void destroy(){}

将抽象方法重写为普通方法,在方法内部没有任何的实现代码,销毁方法的平庸实现

④ public String getInitParameter(String name)

获取初识参数的快捷方法

⑤ public Enumeration getInitParameterNames()

返回所有初始化参数名的方法

⭐⑥ public ServletConfig getServletConfig()

获取初识Servlet初始配置对象ServletConfig的方法

⑦ public ServletContext getServletContext()

获取上下文对ServletContext的方法

⑧ public String getServletInfo()

获取Servlet信息的平庸实现

⭐⑨ public void init(ServletConfig config) throws ServletException()

tomcat在调用init方法时,会读取配置信息进入一个Servletconfig对象并将该对象传入init方法初始化

⭐⑩ public void init() throws ServletException

重载的init初始化方法,我们定义重写初始化功能时对应的方法

⑪ public void log(String msg) public void log(String message,Throwable t)

打印日志的方法及重载

⭐⑫ public abstract void service(ServletRequest req, ServletResponse res) throws ServletException, IOException;

服务方法再次抽象声明

⑬ public String getServletName()

获取ServletName的方法


3.抽象类 HttpServlet

abstract class HttpServlet extends GenericServlet

HttpServlet抽象类,除了基础的实现以外,增加了更多的基础功能,侧重于service方法的处理

java 复制代码
     private static final String METHOD_DELETE = "DELETE"

     private static final String METHOD_HEAD = "HEAD";

     private static final String METHOD_GET = "GET";

     private static final String METHOD_OPTIONS = "OPTIONS";

     private static final String METHOD_POST = "POST";

     private static final String METHOD_PUT = "PUT";

     private static final String METHOD_TRACE = "TRACE";

上述属性用于定义常见请求方式名常量值


java 复制代码
public HttpServlet(){}

构造器,用于处理继承


java 复制代码
public void service(ServletRequest req, ServletResponse res) throws ServletException, 
IOException;

服务方法的实现

在该方法中,将请求和响应对象转换成对应HTTP协议的HttpServletRequest和 HttpServletResponse对象

调用重载的service方法


java 复制代码
public void service(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException;

重载的service方法,被重写的service方法所调用

在该方法中,通过请求方式判断, 用具体的do***方法完成请求的处理。


java 复制代码
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws 
ServletException, IOException;

protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws 
ServletException, IOException;

protected void doHead(HttpServletRequest req, HttpServletResponse resp) throws 
ServletException, IOException;

protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws 
ServletException, IOException;

protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws 
ServletException, IOException;

protected void doOptions(HttpServletRequest req, HttpServletResponse resp) throws 
ServletException, IOException;

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

对应不同请求方式的处理方法

除了doOptions和doTrace方法,其他的do*** 方法都在故意响应错误信息


4.自定义Servlet

自定义Servlet中,必须要对处理请求的方法进行重写

要么重写service方法

要么重写doGet/doPost方法


5.掌握技能

继承HttpServlet,要么重写service方法; 要么重写doGet/doPost方法


六、ServletConfig和ServletContext

1.ServletConfig

ServletConfig是什么

为Servlet提供初始配置参数的一种对象,每个Servlet都有自己独立唯一的ServletConfig对象;

容器(Tomcat)会为每个Servlet实例化一个ServletConfig对象,通过Servlet的init方法传入给Servlet 作为属性;

Tomcat从 web.xml / 注解 中获取到初始配置参数,然后tomcat自动获取到配置信息,自动为每个Servlet实例化一个ServletConfig对象,再将这个ServletConfig对象传入Servlet作为属性

ServletConfig是一个接口,定义了如下API:

getServletName() 获取<servlet-name>HelloServlet</servlet-name>定义的Servlet名称

getServletContext() 获取ServletContext对象

getInitParameter() 获取配置Servlet设置的初始化参数,根据名字获取值

getInitParameterNames() 获取所有初始化参数名组成的Enumeration对象

java 复制代码
package akarta.servlet;
import ava.util.Enumeration;
public interface ServletConfig {
    String getServletName();
    ServletContext getServletContext();
    String getInitParameter(String var1);
    Enumeration<String> getInitParameterNames();
}

2.ServletContext⭐

ServletContext是什么

ServletContext对象是单例的

ServletContext对象有称呼为上下文对,或者叫应用域对象;

容器为每个app创建 一个独立的唯一的ServletContext对象;

ServletContext对象为所有的Servlet所共享;

ServletContext可以为所有的Servlet提供初始配置参数;

ServletContext其他重要API

① 获取资源的磁盘路径

获得一个指向项目部署位置下的某个文件/目录的磁盘真实路径的API

java 复制代码
String realPath = servletContext.getRealPath("资源在web目录中的路径");

例如我们的目标是需要获取项目中某个静态资源的路径,不是工程目录中的路径,而是部署目录中的路径;我们如果直接拷贝其在我们电脑中的完整路径的话其实是有问题的,因为如果该项目以后部署到公司服务器上的话,路径肯定是会发生改变的,所以我们需要使用代码动态获取资源的真实路径.只要使用了servletcontext动态获取资源的真实路径,那么无论项目的部署路径发生什么变化,都会动态获取项目运行时候的实际磁盘路径,所以就不会发生由于写死真实路径而导致项目部署位置改变引发的路径错误问题。

② 获取项目的上下文路径

java 复制代码
String contextPath = servletContext.getContextPath();

项目的部署名称,也叫项目的上下文路径,在部署进入tomcat时所使用的路径,该路径是可能发生变化的,通过该API动态获取项目真实的上下文路径,可以帮助我们解决一些后端页面渲染技术或者请求转发和响应重定向中的路径问题。

③ 域对象的相关API

域对象: 一些用于在一些特定的范围内存储数据和传递数据的对象,不同的范围称为不同的"域",不同的域对象代表不同的域,共享数据的范围也不同;

ServletContext 代表应用,所以ServletContext域也叫作应用域,是webapp中最大的域,可以在本应用内实现数据的共享和传递;

webapp中的三大域对象,分别是应用域,会话域,请求域。

三大域对象都具有的API如下:

void setAttribute(String key,Object value); 向域中存储/修改数据

Object getAttribute(String key); 获得域中的数据

void removeAttribute(String key); 移除域中的数据


七、HttpServletRequest

1.简介

HttpServletRequest是什么

HttpServletRequest是一个接口,其父接口是ServletRequest;

HttpServletRequest是Tomcat将请求报文封装而来的对象,在Tomcat用service方法时传入;

HttpServletRequest代表客户端发来的请求,请求中的所有信息都可以通过该对象获得;


2.常见API

获取请求行信息相关(请求方式,请求的url路径,协议及版本)

StringBuffer getRequestURL(); 获取客户端请求的url

String getRequestURI(); 获取客户端请求项目中的具体资源

int getServerPort(); 获取客户端发送请求时的端口

int getLocalPort(); 获取本应用在所在容器的端口

int getRemotePort(); 获取客户端程序的端口

String getScheme(); 获取请求协议

String getProtocol(); 获得请求协议及版本号

String getMethod(); 获取请求方式

获得请求头信息相关:

String getHeader(String headerName); 根据头名称获取请求

Enumeration getHeaderNames(); 获取所有的请求头名字

String getContentType(); 获取content-type请求头

获得请求参数相关:

String getParameter(String parameterName); 根据请求参数名获取请求单个参数值

String[] getParameterValues(String parameterName); 根据请求数获取请求个数数 Enumeration getParameterNames(); 获取所有请求参数名

Map<String,String[]> getParameterMap(); 获取所有请求参数的键值对集合

BufferedReader getReader() throws IOException; 获取请求体的字符输入流

ServletInputStream getInputStream() throws IOException; 获取请求体的字节输入流

int getContentLength(); 获得请求体的字节数

其他API:

String getServletPath(); 获取请求的Servlet的映射路径

ServletContext getServletContext(); 获取ServletContext对象

Cookie[] getCookies(); 获取请求体中的所有cookie

HttpSession getSession(); 获取Session对象

void setCharacterEncoding(String encoding) ; 设置请求体字符集


八、HttpServletResponse

1.简介

HttpServletResponse是什么

HttpServletResponse是一个接口,其接口是ServletResponse;

HttpServletResponse是Tomcat预先创建的,在Tomcat调用service方法时传入;

HttpServletResponse代表对客户端的响应,该对象会被转换成响应的报文发送给客户端,通过该对象我们可以设置响应信息;


2.常见API

设置响应行相关

void setStatus(int code); 设置响应状态码

设置响应头相关

void setHeader(String headerName, String headerValue); 设置/修改响应头键值对

void setContentType(String contentType); 设置content-type响应头及响应集(设置MIME类型)

设置响应体相关

PrintWriter getWriter() throws IOException; 获得向响应体放入信息的输出流 ServletOutputStream getOutputStream() throws IOException;

获得向响应体放入信息的输出流

void setContentLength(int length); 设置响应体的,其实就是在设置content-length响应头

其他API

void sendError(int code, String message) throws0Exception;

向客户端响应错误信息的方法,需要指定响应码和响应信息
void addCookie(Cookie cookie); 向响应体中增加cookie
void setCharacterEncoding(String encoding); 设置响应体字符集


3.MIME类型

MIME类型,可以理解为文档类型,用户表示传递的数据是属于什么类型的文档;

浏览器可以根据MIME类型决定该用什么的方式解析接收到的响应体数据;

可以理解为:前后端交互数据时,对方发给对方的是 html/css/js/图片/声音/视频/... ...;

tomcat/conf/web.xml中配置了常见文件的拓展名和MIMIE类型的对应关系;

常见的MIME类型举例如下:

文件拓展名 MIME类型

.html text/html

.css text/css

.js application/javascript

.json application/json

.png /.jpeg /.jpg /... image /jpeg

.mp3/.mpe/.mpeg/... video /mp4

.m1v /.m1v /.m2v /.mpe /... video/mpeg


九、请求转发和响应重定向

概述

什么是请求转发和响应重定向

请求发和响应重定向是web应用中间接访问项目资源的两种手段,也是Servlet控制页面跳转的两 种手段;

请求转发通过HttpServletRequest实现,响应重定向通过HttpServletResponse实现;

请求转发生活举例:张三找李四借钱,李四没有,李四找王五,让王五借给张三

响应重定向生活举例:张三找李四借钱,李四没有,李四让张三去找王五,张三自己去找王五借钱


请求转发

请求转发运行逻辑图


请求转发特点⭐

① 请求转发通过HttpServletRequest对象获取请求转发器实现;

② 请求转发是服务器内部的行为,对客户端是屏蔽的;

③ 客户端只发送了一次请求,客户端地址栏是不变的;

④ 服务端只产生了一对请求和响应对象,这一对请求和响应对象继续传递给下一个资源;

⑤ 因为全程只有一个HttpServletRequset对象,所以请求参数可以传递,请求域中的数据也可以传递;

⑥ 请求转发可以发给其他Servlet动态资源,也可以转发给一些静态资源以实现页面跳转;

⑦ 请求转发可以发给WEB-INF下受保护的资源;

⑧ 请求转发不能转发到本项目以外的外部资源;


响应重定向

响应重定向运行逻辑图


响应重定向特点⭐

① 响应重定向通过HttpServletResponse对象的sendRedirect方法实现;

② 响应重定向是服务端通过302响应码和路径,告诉客户端自己去寻找其他资源,是在服务端提示下的客户端的行为

③ 客户端至少发送了两次请求,客户端地址栏是要变化的;

④ 服务端产生了多对请求和响应对象,且请求和响应对象不会传递给下一个资源;

⑤ 因为全程产生了多个HttpServletRequset对象,所以请求参数不可以传递,请求域中的数据也不可以传递

⑥ 重定向可以是其他Servlet动态资源,也可以是一些静态资源以实现页面跳转;

⑦ 重定向目标资源不可以是WEB-INF下受保护的资源

⑧ 重定向目标资源可以是本项目以外的全部资源

结论:同样能够实现页面跳转,优先使用响应重定向


十、MVC架构模式

MVC模式简介

MVC(Model View Controller)是软件工程中的一种 软件架构模式,它把软件系统分为模型 、 视图 和 控制器 三个基本部分。用一种业务逻辑、数据、界面显示分离的方法组织代码,将业务逻辑聚集到一个部件里面,在改进和个性化定制界面及用户交互的同时,不需要重新编写业务逻辑

MVC提供了一套项目代码设计、分类、存放的一套设计思想

更加符合:① 高内聚低耦合 ② 开闭原则

M:Model模型层,具体功能如下

1.存放和数据库对象的实体类以及一些用于存储非数据库表完整相关的VO对象

2.存放一些对数据进行逻辑运算操作的一些业务处理代码

V:View 视图层,具体功能如下

1.存放一些视图文件相关的代码 html css js等

2.在前后端分离的项目中,后端已经没有视图文件,该层次已经行化成独立的前端项目

C:Controller 控制层,具体功能如下

1.接收客户端请求,获得请求数据

2.将准备好的数据响应给客户端


MVC模式下项目中的常见包

M:

1.实体类包(pojo /entity /bean) 专门存放和数据库对应的实体类和一些VO(valueObject)对象

2.数据库访问包(dao/mapper) 专门存放对数据库不同表格CURD方法封装的一些类

3.服务包(service) 专门存放对数据进行业务逻辑预算的一些类

C:

1.控制层包(controller)

V:

1.web目录下的视图资源 html、css、js img等

2.前端工程化后,在后端项目中已经不存在了

非前后端分离的MVC


十一、web乱码和路径问题总结

乱码问题

乱码问题产生的根本原因是什么?

① 数据的编码和解码使用的不是同一个字符集

② 使用了不支持某个语言文字的字符集


HTML乱码问题

设置项目文件的字符集要使用一个支持中文的字符集


Tomcat控制台乱码

将 tomcat /conf /loggin.properties 中所有的字符集UTF-8修改为GBK即可

sout 乱码问题,设置JVM 加载.class文件时使用UTF-8 字符集。


GET请求乱码

GET方式提交数的方式是将参数放到URL后面,如果使用的不是UTF-8,那么对参数进行URL编 码处理;

HTML中的 **<meta charset='字符集'/>**影响了GET方式提交参数的URL编码;

当GET方式提交的参数URL编码和Tomcat的URI编码不一致时,就会出现乱码;

解决方式

方式1:设置GET方式提交的编码和Tomcat的URI默认解析编码一致即可。

方式2 :设置Tomcat的URI解析字符集和GET请求发送时所使用URL转码时的字符集一致即可,修改conf/server.xml中 Connecter 添加 URIEncoding="GBK"


POST方式请求乱码

form 表单的POST请求将数在请求体中进行发送;

请求体使用的字符受集到了 <meta charset='字符集'/> 的影响;

如果请求体的URL转码和Tomcat的请求体解析编码不一致,就容易出现乱码

解决方式

方式1 : 请求时,使用UTF-8 字符集提交请求体 (

方式2:后端在获取参数前,设置解析请求体使用的字符集和请求发送时使用的字符集一致


响应乱码问题

浏览器在接收响应信息时,使用了不同的字符集或者是不支持中文的字符集就会出现乱码。

解决方式

方式1:手动设定浏览器对本次响应体解析时使用的字符集

edge和 chrome浏览器没有提供直接的比较方便的入口,不方便

方式2:后端通过设置响应体的字符集和浏览器解析响应体的默认字符集一致

方式3::通过设置Content-Type响应头,告诉浏览器以指定的字符集解析响应体


路径问题

相对路径和绝对路径:

相对路径:

相对路径的规则是以当前资源所在的路径为出发点去寻找目标资源

相对路径不以 / 开头;

在file协议下,使用的是磁盘路径;

在http协议下,使用的是url路径;

相对路径中可以使用**./**表示当前资源所在路径,可以省略不写;

相对路径中可以使用**../**表示当前资源所在的上一层路径,需要时要手动添加;

**缺点:**目标资源路径收到当前资源路径的影响,不同的为止,相对路径写法不同

绝对路径:

绝对路径的规则是: 使用以一个固定的路径做出发点去寻找目标资源,和当前资源所在的路径没有关系;

绝对路径要以**/**开头;

绝对路径的写法中,不以当前资源的所在路径为出发点,所以不会出现 ./ 和../开头

不同的项目和不同的协议下,绝对路径的基础位置可能不同,要通过测试确定;

绝对路径的好处就是,无论当前资源位置在哪,寻找目标资源路径的写法都一致;

**缺点:**要补充项目的上下文,而上下文是可以改变的

应用场景:

  1. 前端代码中,href、src、action 等属性;

  2. 请求转发和重定向中的路径

不设置当前项目上下文路径

取消项目上下文路径后直接写 / + 绝对路径就好

相关推荐
xlsw_3 小时前
java全栈day20--Web后端实战(Mybatis基础2)
java·开发语言·mybatis
神仙别闹4 小时前
基于java的改良版超级玛丽小游戏
java
黄油饼卷咖喱鸡就味增汤拌孜然羊肉炒饭4 小时前
SpringBoot如何实现缓存预热?
java·spring boot·spring·缓存·程序员
暮湫4 小时前
泛型(2)
java
超爱吃士力架4 小时前
邀请逻辑
java·linux·后端
南宫生5 小时前
力扣-图论-17【算法学习day.67】
java·学习·算法·leetcode·图论
转码的小石5 小时前
12/21java基础
java
李小白665 小时前
Spring MVC(上)
java·spring·mvc
GoodStudyAndDayDayUp5 小时前
IDEA能够从mapper跳转到xml的插件
xml·java·intellij-idea
装不满的克莱因瓶6 小时前
【Redis经典面试题六】Redis的持久化机制是怎样的?
java·数据库·redis·持久化·aof·rdb