Java教程

JavaWeb之Servlet、Request与Response总结

本文主要是介绍JavaWeb之Servlet、Request与Response总结,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

一、什么是Servlet?

Servlet是一个Java编写的程序,此程序是基于Http协议的(不仅仅只http协议),在服务器端运行的(如tomcat),是按照Servlet规范编写的一个Java类

二、Servlet有什么作用

主要是处理客户端的请求并将其结果发送到客户端

三、Servlet的生命周期

Servlet的生命周期是由Servlet的容器来控制的,它可以分为3个阶段;初始化,运行,销毁

1.初始化阶段: 第一次被访问时,执行init() 方法,只执行一次

  1. Servlet容器加载servlet类,把servlet类的.class文件中的数据读到内存中
  2. 然后Servlet容器创建一个ServletConfig对象。ServletConfig对象包含了Servlet的初始化配置信息
  3. Servlet容器创建一个servlet对象
  4. Servlet容器调用servlet对象的init() 方法进行初始化。

2.运行阶段: 每次访问Servlet时,Service() 方法都会被调用一次

  1. 当servlet容器接收到一个请求时,servlet容器会针对这个请求创建servletRequest和servletResponse对象。
  2. 然后调用service方法。并把这两个参数传递给service方法。Service方法通过servletRequest对象获得请求的信息并处理该请求。再通过servletResponse对象生成这个请求的响应结果。然后销毁servletRequest和servletResponse对象。
  3. 不管这个请求是post提交的还是get提交的,最终这个请求都会由service方法来处理。

3.销毁阶段: 执行destroy() 方法,只执行一次

  1. 当Web应用被终止时,servlet容器会先调用servlet对象的destrory方法,然后再销毁servlet对象,同时也会销毁与servlet对象相关联的servletConfig对象。
  2. 我们可以在destroy方法的实现中,释放servlet所占用的资源,如关闭数据库连接,关闭文件输入输出流等。

四,Servlet怎么处理一个请求?

  1. 当用户发送一个请求到某个Servlet的时候,Servlet容器会创建一个ServletRequst和ServletResponse对象。

  2. 在ServletRequst对象中封装了用户的请求信息,然后Servlet容器把ServletRequst和ServletResponse对象

  3. 传给用户所请求的Servlet,Servlet把处理好的结果写在ServletResponse中,然后Servlet容器把响应结果传给用户。

五、Servlet相关配置

1.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>
        <!-- 配置Servlet名称,名称必须唯一  -->
        <servlet-name>test</servlet-name>
        <!-- 配置Servlet完全路径(包名+类名) -->
        <servlet-class>Demo.Demo1</servlet-class>
    </servlet>
    <!-- 配置Servlet映射(访问路径) -->
    <servlet-mapping>
        <!-- 配置Servlet名称,必须和上面的相同 -->
        <servlet-name>test</servlet-name>
        <!-- 配置虚拟路径(访问路径) -->
        <url-pattern>/demo</url-pattern>
    </servlet-mapping>
</web-app>

2.注解配置: @WebServlet("/URL(路径)")

一个Servlet可以定义多个访问路径 : @WebServlet({"/demo1","/demo2","/demo3"})

URL(路径)定义规则 :

  1. /xxx:路径匹配
  2. /xxx/xxx:多层路径,目录结构
  3. *.do:扩展名匹配

六、Servlet的常用俩种实现方式

1.继承Servlet接口,覆盖重写全部5个方法

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

@WebServlet("/servletDemo")        //注解方式配置路径
public class ServletDemo implements Servlet {
    //初始化方法,第一次访问时执行
    @Override
    public void init(ServletConfig servletConfig) throws ServletException {

    }

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

    //service方法,当用户每访问一次Servlet就执行一次
    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {

    }

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

    //结束方法,Servlet被销毁时执行
    @Override
    public void destroy() {

    }
}

2.继承HttpServlet抽象类: 按照需要重写方法,一般重写doPost和doGet方法

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

@WebServlet("/httpServlet")    //注解方式配置路径
public class HttpServletDemo extends HttpServlet {
    //post请求调用此方法
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

    }

    //get请求调用此方法
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //直接调用doPost方法,因为代码一样,只是请求方式不一样,一个get方式,一个post方式
        this.doPost(req, resp);
    }
}

七、HTTP

概念: Hyper Text Transfer Protocol 超文本传输协议

传输协议: 定义了,客户端和服务器端通信时,发送数据的格式

默认端口号: 80

HTTP请求消息数据格式:

1.请求行:请求方式 请求url 请求协议/版本

常见的请求方式有两种:

GET:

  1. 请求参数在请求行中,在url后
  2. 请求的url长度有限制的
  3. 不太安全

POST:

  1. 请求参数在请求体中
  2. 请求的url长度没有限制的
  3. 相对安全

2.请求头:客户端浏览器告诉服务器一些信息

​ 格式:请求头名称: 请求头值

常见的请求头:

(1)User-Agent:浏览器告诉服务器,我访问你使用的浏览器版本信息,可以在服务器端获取该头的信息,解决浏览器的兼容性问题

(2)Referer:用户在访问当前资源之前的位置路径

​             作用:防盗链 和 统计工作:

3.请求空行:

      空行,就是用于分割POST请求的请求头,和请求体的。

4.请求体(正文):

封装POST请求消息的请求参数的

请求体,是请求报文的负荷,可以是文本、图片、视频、HTML 文档、应用程序、电子邮件等

在这里插入图片描述

八、响应消息数据格式

组成:协议/版本 响应状态码 状态码描述

1.响应行:

响应状态码:服务器告诉客户端浏览器本次请求和响应的一个状态。不同状态具有不同含义 :状态码都是3位数字

状态码分类:

分类分类描述
1**信息,服务器收到请求,需要请求者继续执行操作
2**成功,操作被成功接收并处理。代表:200
3**重定向,需要进一步的操作以完成请求。代表:302(重定向),304(访问缓冲)
4**客户端错误,请求包含语法错误或无法完成请求。代表:404(请求路径没有对应的资源),405(请求方式没有对应的doXxx方法)
5**服务器错误,服务器在处理请求的过程中发生了错误。代表:500(服务器内部出现异常)

2.响应头:

头信息描述
Allow这个头信息指定服务器支持的请求方法(GET、POST 等)
Cache-Control这个头信息指定响应文档在何种情况下可以安全地缓存。可能的值有:public、privateno-cache 等。Public 意味着文档是可缓存,Private 意味着文档是单个用户私用文档,且只能存储在私有(非共享)缓存中,no-cache 意味着文档不应被缓存
Connection这个头信息指示浏览器是否使用持久 HTTP 连接。值 close 指示浏览器不使用持久 HTTP 连接,值 keep-alive 意味着使用持久连接
Content-Disposition这个头信息可以让您请求浏览器要求用户以给定名称的文件把响应保存到磁盘
Content-Encoding在传输过程中,这个头信息指定页面的编码方式
Content-Language这个头信息表示文档编写所使用的语言。例如,en、en-us、ru 等
Content-Length这个头信息指示响应中的字节数。只有当浏览器使用持久(keep-alive)HTTP 连接时才需要这些信息
Content-Type这个头信息提供了响应文档的 MIME(Multipurpose Internet Mail Extension)类型
Expires这个头信息指定内容过期的时间,在这之后内容不再被缓存
Last-Modified这个头信息指示文档的最后修改时间。然后,客户端可以缓存文件,并在以后的请求中通过 If-Modified-Since 请求头信息提供一个日期
Location这个头信息应被包含在所有的带有状态码的响应中。在 300s 内,这会通知浏览器文档的地址。浏览器会自动重新连接到这个位置,并获取新的文档
Refresh这个头信息指定浏览器应该如何尽快请求更新的页面。您可以指定页面刷新的秒数
Retry-After这个头信息可以与 503(Service Unavailable 服务不可用)响应配合使用,这会告诉客户端多久就可以重复它的请求
Set-Cookie这个头信息指定一个与页面关联的 cookie

常见的响应头:

1.Content-Type:服务器告诉客户端本次响应体数据格式以及编码格式

2.Content-disposition:服务器告诉客户端以什么格式打开响应体数据

值:

​       in-line:默认值,在当前页面内打开

​       attachment;filename=xxx:以附件形式打开响应体。用于文件下载

3. 响应空行

4. 响应体:传输的数据

响应空行与相应体的作用与请求报文相同

九、请求:request

下面的方法可用在Servlet程序中读取HTTP头。这些方法通过HttpServletRequest对象 可用 (标红的是常用的)

方法描述
Cookie[] getCookies()返回一个数组,包含客户端发送该请求的所有的 Cookie 对象
Enumeration getAttributeNames()返回一个枚举,包含提供给该请求可用的属性名称
Enumeration getHeaderNames() 返回一个枚举,包含在该请求中包含的所有的头名
Enumeration getParameterNames()返回一个 String 对象的枚举,包含在该请求中包含的参数的名称
HttpSession getSession()返回与该请求关联的当前 session 会话,或者如果请求没有 session 会话,则创建一个
HttpSession getSession(boolean create)
返回与该请求关联的当前 HttpSession,或者如果没有当前会话,且创建是真的,则返回一个新的 session 会话
Locale getLocale()基于 Accept-Language 头,返回客户端接受内容的首选的区域设置
Object
getAttribute(String name)
以对象形式返回已命名属性的值,如果没有给定名称的属性存在,则返回 null
ServletInputStream getInputStream()使用 ServletInputStream,以二进制数据形式检索请求的主体
String getAuthType()返回用于保护 Servlet 的身份验证方案的名称,例如,“BASIC” 或 “SSL”,如果JSP没有受到保护则返回 null
String getCharacterEncoding()返回请求主体中使用的字符编码的名称
String getContentType()返回请求主体的 MIME 类型,如果不知道类型则返回 null
String getContextPath()返回指示请求上下文的请求 URI 部分
String getHeader(String name)以字符串形式返回指定的请求头的值
String getMethod()返回请求的 HTTP 方法的名称,例如,GET、POST 或 PUT
boolean isSecure()返回一个布尔值,指示请求是否使用安全通道,如 HTTPS
String getPathInfo()当请求发出时,返回与客户端发送的 URL 相关的任何额外的路径信息
String getProtocol()返回请求协议的名称和版本
String getQueryString()返回包含在路径后的请求 URL 中的查询字符串(如:name=lss&password=123)
String getRemoteAddr()返回发送请求的客户端的互联网协议(IP)地址
String getRemoteHost()返回发送请求的客户端的完全限定名称
String getRemoteUser()如果用户已通过身份验证,则返回发出请求的登录用户,或者如果用户未通过身份验证,则返回 null
String getRequestURI()从协议名称直到 HTTP 请求的第一行的查询字符串中,返回该请求的 URL 的一部分
String getRequestedSessionId()返回由客户端指定的 session 会话 ID
String getServletPath()返回调用 JSP 的请求的 URL 的一部分
String[]
getParameterValues(String name)
返回一个字符串对象的数组,包含所有给定的请求参数的值,如果参数不存在则返回 null
int getServerPort()返回接收到这个请求的端口号
int getContentLength()以字节为单位返回请求主体的长度,并提供输入流,或者如果长度未知则返回 -1
int getIntHeader(String name)返回指定的请求头的值为一个 int 值。
String getParameter(String name)以字符串形式返回请求参数的值,或者如果参数不存在则返回 null
int getParameterMap()将参数封装成 Map 类型
StringBuffer getRequestURL()返回该请求的 URL

请求转发:

一种在服务器内部的资源跳转方式 (路径是虚拟路径)

1.通过request对象获取请求转发器对象

    RequestDispatcher getRequestDispatcher(String path)

2.使用RequestDispatcher对象来进行转发

   forward(ServletRequest request, ServletResponse response)

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

@WebServlet("/lss2")
public class ServletDemo2 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        //请求转发
        //第一个里面的参数是路径path
        req.getRequestDispatcher("/lss").forward(req, resp);
    }

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

共享数据

域对象: 一个有作用范围的对象,可以在范围内共享数据
request域: 代表一次请求的范围,一般用于请求转发的多个资源中共享数据

方法:

  1. void setAttribute(String name,Object obj)::存储数据

  2. Object getAttitude(String name):通过键获取值

  3. void removeAttribute(String name):通过键移除键值对

十、响应:response对象

下面的方法可用于在 Servlet 程序中设置 HTTP 响应报头。这些方法通过 HttpServletResponse 对象 可用(标红的是常用的)

方法描述
String encodeRedirectURL(String url)为 sendRedirect 方法中使用的指定的 URL 进行编码,或者如果编码不是必需的,则返回 URL 未改变
String encodeURL(String url)对包含 session 会话 ID 的指定 URL 进行编码,或者如果编码不是必需的,则返回 URL 未改变
boolean
containsHeader(String name)
返回一个布尔值,指示是否已经设置已命名的响应报头
boolean isCommitted()返回一个布尔值,指示响应是否已经提交
void addCookie(Cookie cookie)把指定的 cookie 添加到响应
void addDateHeader(String name, long date)添加一个带有给定的名称和日期值的响应报头
7void addHeader(String name, String value)
添加一个带有给定的名称和值的响应报头
8void addIntHeader(String name, int value)
添加一个带有给定的名称和整数值的响应报头
9void flushBuffer()
强制任何在缓冲区中的内容被写入到客户端
10void reset()
清除缓冲区中存在的任何数据,包括状态码和头
11void resetBuffer()
清除响应中基础缓冲区的内容,不清除状态码和头。
12void sendError(int sc)
使用指定的状态码发送错误响应到客户端,并清除缓冲区。
13void sendError(int sc, String msg)
使用指定的状态发送错误响应到客户端。
14void sendRedirect(String location)
使用指定的重定向位置 URL 发送临时重定向响应到客户端
15void setCharacterEncoding(String charset)
设置被发送到客户端的响应的字符编码(MIME 字符集)例如,UTF-8
16void setContentLength(int len)
设置在 HTTP Servlet 响应中的内容主体的长度,该方法设置 HTTP Content-Length 头
17void setContentType(String type)
如果响应还未被提交,设置被发送到客户端的响应的内容类型
18void setDateHeader(String name, long date)
设置一个带有给定的名称和日期值的响应报头
19void setHeader(String name, String value)
设置一个带有给定的名称和值的响应报头
20void setIntHeader(String name, int value)
设置一个带有给定的名称和整数值的响应报头
21void setLocale(Locale loc)
如果响应还未被提交,设置响应的区域
22void setStatus(int sc)
为该响应设置状态码
23void setBufferSize(int size)
为响应主体设置首选的缓冲区大小

重定向:

1.先设置状态码为302

2.然后设置响应头location

 response.setStatus(302);
 response.setHeader("location","/Test/responseDemo"); //第二个参数是响应资源的URL,要写绝对路径

简单的重定向方法: response里面的sendRedirect方法

response.sendRedirect("/Test/responseDemo"); //参数是响应资源的URL,要写绝对路径

乱码问题:

 response.setContentType("text/html;charset=utf-8");

十一、ServletContext对象:

概念: 代表整个web应用,可以和程序的容器(服务器)来通信

对象获取:

1. 通过request对象获取

​ request.getServletContext();

2. 通过HttpServlet获取

​ this.getServletContext();

功能:

  1. 获取MIME类型:

    MIME类型:在互联网通信过程中定义的一种文件数据类型

    ​ 格式: 大类型/小类型 1.text/html 2.image/jpeg

    获取:String getMimeType(String file)

  2. 域对象:共享数据

    1. setAttribute(String name,Object value)
    2. etAttribute(String name)
    3. removeAttribute(String name)

     ServletContext对象范围:所有用户所有请求的数据

  1. 获取文件的真实(服务器)路径

        方法:String getRealPath(String path)

获取web目录下资源访问路径:

String b = context.getRealPath("/b.txt");

获取WEB-INF目录下的资源访问路径:

String c = context.getRealPath("/WEB-INF/c.txt");

获取src目录下的资源访问路径:

String a = context.getRealPath("/WEB-INF/classes/a.txt");

文件下载案例

前端代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <!-- 路径要加上虚拟目录-->
    <a href="/JavaEE/img/美女.jpg">展示图片</a>
    <a href="/JavaEE/servletDemo?filename=img/美女.jpg ">下载图片</a>
    <a href="/JavaEE/img/美女.png">展示图片</a>
    <a href="/JavaEE/servletDemo?filename=img/美女.png">下载图片</a>
</body>
</html>

后端操作代码:

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.FileInputStream;
import java.io.IOException;

/**
 * @Author: lss
 * @Date: 2021/7/15 - 19:41
 * @Description: 文件下载
 * @version: 1.0
 */
@WebServlet("/servletDemo")
public class ServletDemo extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1.获取请求参数,文件名称
        String filename = req.getParameter("filename");

        //2.使用字节输入流加载文件到内存
        ServletContext servletContext = this.getServletContext();
        //获取文件路径
        String realPath = servletContext.getRealPath(filename);
        //获取字节输入流
        FileInputStream fis = new FileInputStream(realPath);
        //获取文件类型
        String mimeType = servletContext.getMimeType(filename);
        //注意:设置response的响应头
        resp.setHeader("content-type", mimeType);
        //设置以附件形式打开响应体
        resp.setHeader("content-disposition", "attachment;filename=" + filename);

        //3.将输入流的数据写道输出流中
        ServletOutputStream sos = resp.getOutputStream();
        byte[] bytes = new byte[1024];
        int len = 0;
        while ((len = fis.read(bytes)) != -1) {
            sos.write(bytes, 0, len);
        }
        //释放流资源
        fis.close();
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doPost(req, resp);
    }
}
这篇关于JavaWeb之Servlet、Request与Response总结的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!