Servlet 的Request和Response

2023-05-16

1.Request和Response概述

1. Request: 获取请求数据

  • 浏览器会发送HTTP请求到后台服务器[Tomcat]
  • HTTP的请求中会包含很多请求数据[请求行+请求头+请求体]
  • 后台服务器[Tomcat]会对HTTP请求中的数据进行解析并把解析结果存入到一个对象中
  • 所存入的对象即为request对象,所以我们可以从request对象中获取请求的相关参数
  • 获取到数据后就可以继续后续的业务,比如获取用户名和密码就可以实现登录操作的相关业务

2. Response: 设置请求数据

  • 业务处理完后,后台就需要给前端返回业务处理的结果即响应数据
  • 把响应数据封装到response对象中
  • 后台服务器[Tomcat]会解析response对象,按照[响应行+响应头+响应体]格式拼接结果
  • 浏览器最终解析结果,把内容展示在浏览器给用户浏览

2.Request域方法 

  • void setAttribute(String name, Object value):用来存储一个对象,也可以称之为存储一个域属性,例如:servletContext.setAttribute(“xxx”, “XXX”),在request中保存了一个域属性,域属性名称为xxx,域属性的值为XXX。请注意,如果多次调用该方法,并且使用相同的name,那么会覆盖上一次的值,这一特性与Map相同;

  • Object getAttribute(String name):用来获取request中的数据,当前在获取之前需要先去存储才行,例如:String value = (String)request.getAttribute(“xxx”);,获取名为xxx的域属性;

  • void removeAttribute(String name):用来移除request中的域属性,如果参数name指定的域属性不存在,那么本方法什么都不做;

  • Enumeration getAttributeNames():获取所有域属性的名称;

3.Request获取请求头数据

  • String getHeader(String name):获取指定名称的请求头;

  • Enumeration getHeaderNames():获取所有请求头名称;

  • int getIntHeader(String name):获取值为int类型的请求头。

其他方法:

  • int getContentLength():获取请求体的字节数,GET请求没有请求体,没有请求体返回-1;

  • String getContentType():获取请求类型,如果请求是GET,那么这个方法返回null;如果是POST请求,那么默认为application/x-www-form-urlencoded,表示请求体内容使用了URL编码;

  • String getMethod():返回请求方法,例如:GET

  • Locale getLocale():返回当前客户端浏览器的Locale。java.util.Locale表示国家和言语,这个东西在国际化中很有用;

  • String getCharacterEncoding():获取请求编码,如果没有setCharacterEncoding(),那么返回null,表示使用ISO-8859-1编码;

  • void setCharacterEncoding(String code):设置请求编码,只对请求体有效!注意,对于GET而言,没有请求体!!!所以此方法只能对POST请求中的参数有效! 重点

  • String getContextPath():返回上下文路径,例如:/hello

  • String getQueryString():返回请求URL中的参数,例如:name=zhangSan

  • String getRequestURI():返回请求URI路径,例如:/hello/oneServlet

  • StringBuffer getRequestURL():返回请求URL路径,例如:http://localhost/hello/oneServlet,即返回除了参数以外的路径信息;

  • String getServletPath():返回Servlet路径,例如:/oneServlet

  • String getRemoteAddr():返回当前客户端的IP地址;

  • String getRemoteHost():返回当前客户端的主机名,但这个方法的实现还是获取IP地址;

  • String getScheme():返回请求协议,例如:http;

  • String getServerName():返回主机名,例如:localhost

  • int getServerPort():返回服务器端口号,例如:8080

//获取请求体的字节数
System.out.println("request.getContentLength(): " + request.getContentLength());	
//获取请求类型
System.out.println("request.getContentType(): " + request.getContentType());	
//返回上下文路径
System.out.println("request.getContextPath(): " + request.getContextPath());	
//返回请求方法
System.out.println("request.getMethod(): " + request.getMethod());	
//返回当前客户端浏览器的Locale
System.out.println("request.getLocale(): " + request.getLocale());			
//返回请求URL中的参数
System.out.println("request.getQueryString(): " + request.getQueryString());	
//返回请求URI路径
System.out.println("request.getRequestURI(): " + request.getRequestURI());	
//返回请求URL路径
System.out.println("request.getRequestURL(): " + request.getRequestURL());	
//返回Servlet路径
System.out.println("request.getServletPath(): " + request.getServletPath());	
//返回当前客户端的IP地址
System.out.println("request.getRemoteAddr(): " + request.getRemoteAddr());	
//返回当前客户端的主机名
System.out.println("request.getRemoteHost(): " + request.getRemoteHost());	
//返回请求协议
System.out.println("request.getScheme(): " + request.getScheme());	
//返回主机名
System.out.println("request.getServerName(): " + request.getServerName());	
//返回服务器端口号
System.out.println("request.getServerPort(): " + request.getServerPort());

 4.request获取请求参数

最为常见的客户端传递参数方式有两种:

  • 浏览器地址栏直接输入:一定是GET请求;

  • 超链接:一定是GET请求;

  • 表单:可以是GET,也可以是POST,这取决与<form>表单设置的method属性值,默认为Get请求

GET请求和POST请求的区别:

  • GET请求:

    • 请求参数会在浏览器的地址栏中显示,所以不安全;

    • 请求参数长度限制长度在1K之内;

    • GET请求没有请求体,无法通过request.setCharacterEncoding()来设置参数的编码;

  • POST请求:

    • 请求参数不会显示浏览器的地址栏,相对安全;

    • 请求参数长度没有限制;

1.获取请求参数方法:

String getParameter(String name):通过指定名称获取参数值;  

@WebServlet(name = "AServlet",value = "/AServlet")
public class AServlet extends HttpServlet {
    public void doGet(HttpServletRequest request, HttpServletResponse response)		throws ServletException, IOException {
        String v1 = request.getParameter("user");
        String v2 = request.getParameter("passname");
        System.out.println("p1=" + v1);
        System.out.println("p2=" + v2);
    }
    public void doPost(HttpServletRequest request, HttpServletResponse response)		throws ServletException, IOException {
        String v1 = request.getParameter("p1");
        String v2 = request.getParameter("p2");
        System.out.println("p1=" + v1);
        System.out.println("p2=" + v2);
    }
}

 

 2.请求转发

        客户一个请求,都表示由多个Servlet共同来处理一个请求。例如Servlet1来处理请求,然后Servlet1又转发给Servlet2来继续处理这个请求。

public  class AServlet extends HttpServlet {	       
    public void doGet(HttpServletRequest request, HttpServletResponse response)		throws ServletException, IOException {		
        System.out.println("AServlet");		
        RequestDispatcher rd = request.getRequestDispatcher("/BServlet");
        rd.forward(request, response);	
    }
}
public class BServlet extends HttpServlet {	       
    public void doGet(HttpServletRequest request, HttpServletResponse response)		throws ServletException, IOException {		
        System.out.println("BServlet");	
    }
}

 Request总结

  • 如果在AServlet中请求转发到BServlet,那么在AServlet中就不允许再输出响应体,即不能再使用response.getWriter()和response.getOutputStream()向客户端输出,这一工作应该由BServlet来完成;如果是使用请求包含,那么没有这个限制;

  • 请求转发虽然不能输出响应体,但还是可以设置响应头的,例如:response.setContentType(”text/html;charset=utf-8”);

  • 请求请求大多是应用在Servlet中,转发目标大多是JSP页面;

5.Response概述

response是Servlet.service方法的一个参数,类型为javax.servlet.http.HttpServletResponse。在客户端发出每个请求时,服务器都会创建一个response对象,并传入给Servlet.service()方法。response对象是用来对客户端进行响应的,这说明在service()方法中使用response对象可以完成对客户端的响应工作。

response对象的功能分为以下四种:

  • 设置响应头信息;

  • 发送状态码;

  • 设置响应正文;

  • 重定向;

response响应正文

response是响应对象,向客户端输出响应正文(响应体)可以使用response的响应流,repsonse一共提供了两个响应流对象:

  • PrintWriter out = response.getWriter():获取字符流;

  • ServletOutputStream out = response.getOutputStream():获取字节流;

    当然,如果响应正文内容为字符,那么使用response.getWriter(),如果响应内容是字节,例如下载时,那么可以使用response.getOutputStream()。

注意,在一个请求中,不能同时使用这两个流!也就是说,要么你使用repsonse.getWriter(),要么使用response.getOutputStream(),但不能同时使用这两个流。不然会抛出illegalStateException异常。

  • 字符编码

    在使用response.getWriter()时需要注意默认字符编码为ISO-8859-1,如果希望设置字符流的字符编码为utf-8,可以使用response.setCharaceterEncoding(“utf-8”)来设置。这样可以保证输出给客户端的字符都是使用UTF-8编码的!

    但客户端浏览器并不知道响应数据是什么编码的!如果希望通知客户端使用UTF-8来解读响应数据,那么还是使用response.setContentType("text/html;charset=utf-8")方法比较好,因为这个方法不只会调用response.setCharaceterEncoding(“utf-8”),还会设置content-type响应头,客户端浏览器会使用content-type头来解读响应数据。

  • 缓冲区

    response.getWriter()是PrintWriter类型,所以它有缓冲区,缓冲区的默认大小为8KB。也就是说,在响应数据没有输出8KB之前,数据都是存放在缓冲区中,而不会立刻发送到客户端。当Servlet执行结束后,服务器才会去刷新流,使缓冲区中的数据发送到客户端。

    如果希望响应数据马上发送给客户端:

    • 向流中写入大于8KB的数据;

    • 调用response.flushBuffer()方法来手动刷新缓冲区;

设置响应头信息

 

可以使用response对象的setHeader()方法来设置响应头!使用该方法设置的响应头最终会发送给客户端浏览器!

  • response.setHeader(“content-type”, “text/html;charset=utf-8”):设置content-type响应头,该头的作用是告诉浏览器响应内容为html类型,编码为utf-8。而且同时会设置response的字符流编码为utf-8,即response.setCharaceterEncoding(“utf-8”);

  • response.setHeader("Refresh","5; URL=http://baidu.com"):5秒后自动跳转到百度主页。

设置状态码及其他方法

  • response.setContentType("text/html;charset=utf-8"):等同与调用response.setHeader(“content-type”, “text/html;charset=utf-8”);

  • response.setCharacterEncoding(“utf-8”):设置字符响应流的字符编码为utf-8;

  • response.setStatus(200):设置状态码;

  • response.sendError(404, “您要查找的资源不存在”):当发送错误状态码时,Tomcat会跳转到固定的错误页面去,但可以显示错误信息。

重定向

        当你访问http://www.sun.com时,你会发现浏览器地址栏中的URL会变成http://www.www.oracle.com/it-infrastructure/,这就是重定向了。重定向是服务器通知浏览器去访问另一个地址,即再发出另一个请求。

 

重定向小结

  • 重定向是两次请求;

  • 重定向的URL可以是其他应用,不局限于当前应用;

  • 重定向的响应头为302,并且必须要有Location响应头;

  • 重定向就不要再使用response.getWriter()或response.getOutputStream()输出数据,不然可能会出现异常;

请求转发与重定向比较

  • 请求转发是一个请求,而重定向是两个请求;

  • 请求转发后浏览器地址栏不会有变化,而重定向会有变化,因为重定向是两个请求;

  • 请求转发的目标只能是本应用中的资源,重定向的目标可以是其他应用;

  • 请求转发对AServlet和BServlet的请求方法是相同的,即要么都是GET,要么都是POST,因为请求转发是一个请求;

  • 重定向的第二个请求一定是GET;

  • 请求转发是在服务端内部执行的,而重定向是在客户端执行的.

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Servlet 的Request和Response 的相关文章

  • 在 HTTP 请求中指定端口号 (node.js)

    使用请求模块发出 HTTP 请求时是否可以指定端口号 我在文档中没有看到任何有关此内容的信息 var request require request this works request method GET url http exampl
  • Cypress:如何等待所有请求完成

    我正在使用 cypress 来测试我们的 Web 应用程序 在某些页面中 有不同的端点请求被执行多次 例如GET A GET B GET A 为了等待所有请求完成并保证页面已完全加载 赛普拉斯的最佳实践是什么 我不想用很多cy wait 命
  • 从 C# 级别将带有数据的 POST 请求发送到 PHP 脚本

    所以我有一个 php 脚本 其名称是 wiadomosci php 代码如下
  • Request.UserAgent 和 Request.Browser 有什么区别?

    下面是我的代码 User Info Add string IsNullOrEmpty Request UserAgent Request UserAgent string Empty 4 UserAgent HttpBrowserCapab
  • Java 放气响应

    大家好 我想为 tomcat 创建一个过滤器来压缩某些 MIME 类型的所有响应 有什么指导方针吗 String ae request getHeader accept encoding if ae null ae indexOf defl
  • 如何在scrapy中发出请求之前更改请求url?

    我需要在下载响应之前修改我的请求网址 但我无法改变它 即使使用修改请求网址后request replace url new url the process response打印未修改的 url 这是中间件的代码 def process re
  • 动态创建 Laravel Request 对象

    我正在一个控制器中处理数据 并希望将其进一步传递到另一个控制器中以避免重复代码 有没有办法设置另一个控制器中需要的 Request 对象store 方法 我追踪了 Request 继承并找到了 Symfony 的 Request 对象 它有
  • 从 onResponse Retrofit 返回变量

    我对网络服务器进行 API 调用 并在 onResponse 方法中获取 ID 现在我想保存这个ID并在doLogin方法的返回中返回这个ID 如何在 return 语句中获取该变量 ID 这是我的代码 public class Login
  • 使用逻辑运算符进行 Laravel 表单验证

    当用户填写消息 文本区域 时 他 她无法填写日期 时间 地点值 仅当 Message 为空且所有这三个字段均已填充时 才会考虑这三个字段 如何使用 Laravel 表单验证来做到这一点 是否可以在Request的规则方法中定义这些逻辑 我是
  • Python urllib2 响应头

    我正在尝试提取 URL 请求的响应标头 当我使用firebug分析URL请求的响应输出时 它返回 Content Type text html 但是当我使用 python 代码时 urllib2 urlopen URL info 结果输出返
  • 单元测试 Laravel FormRequest

    我正在尝试对各种自定义进行单元测试FormRequest输入 我找到的解决方案是 建议使用 this gt call 方法并断言response与预期值 答案链接 https stackoverflow com questions 2979
  • PHP 表单从 id 发送值而不是值

    我通常在带有隐藏字段的表单中做类似的事情
  • Solidity有HTTP请求功能吗?

    我正在使用以太坊制作一个项目 在这个项目中 我正在签订一份名为 A 的合同 当我向 A 发送消息时 我希望 A 发出网络请求 Solidity 是否可以使用 http 请求 方法 GET POST 以太坊区块链无法与外界交互 否则它将不再是
  • Request.UserHostAddress返回负载均衡器的IP地址

    我的网站中有一行关键代码可以在我们的开发环境中运行 但不能在生产环境中运行 好吧 我说它在开发中起作用 但事实是它给了 1 这是 IPv6 环回地址 无论如何 我想要做的是捕获访问该站点的用户的 IP 地址 因此 我使用Request Us
  • RSpec 请求 - 如何为所有请求设置 http 授权标头

    我正在使用 rspec 请求来测试 JSON API 该 API 需要在每个请求的标头中包含 api key 我知道我可以这样做 get v1 users janedoe json HTTP AUTHORIZATION gt Token t
  • 在 Angular 中处理多部分响应主体

    我在 Angular 中收到多部分响应正文 但应用程序未正确处理响应 事实证明 Angular 中的 HttpClient 无法正确解析多部分响应主体 请参阅这个问题在 GitHub 上 https github com angular a
  • 在获得响应之前发出多个请求

    当并行发送多个请求时 在获得响应之前 我无法理解 HTTP 的工作原理 有两种情况 1 With Connection Keep Alive 根据HTTP规范 http www w3 org Protocols rfc2616 rfc261
  • Response.WriteFile / Response.BinaryWrite / Response.TransmitFile (ASP.NET) 出现问题

    我有一个简单的网页 可以生成一个 CSV 文件 我希望用户在创建完成后能够下载该文件 我的情况总结如下 CSV 文件可以在内存中或磁盘上创建 对我来说没关系 完成 CSV 文件传输后 我不希望它继续驻留在磁盘上 我尝试过使用 Respons
  • 使用python将json和文件发送到flask

    我遇到这个问题 我试图在单个函数中向 Flask API 发送 接收一些文件和 JSON 在我的客户端 发件人 上我有 my json to be sent datas var1 var1 var2 var2 my file to be s
  • 使用 python requests 模块时出现 HTTP 503 错误

    我正在尝试发出 HTTP 请求 但当前可以从 Firefox 浏览器访问的网站响应 503 错误 代码本身非常简单 在网上搜索一番后我添加了user Agent请求参数 但也没有帮助 有人能解释一下如何消除这个 503 错误吗 顺便说一句

随机推荐

  • 各种seq ribo-seq rna-seq pipelines

    SPR WorkFlow Collection sysPipe
  • tinyarray 相关性cor.full

    R Documentation cor test for one variable with all variables Description cor test for all variables each two columns Usa
  • Elasticsearch中FST与前缀搜索

    FST的基本概念 FST xff08 Finite State Transducer xff09 是一种有限状态自动机 xff0c 可以将一组输入符号映射为一组输出符号 FST由一组状态和一组转移组成 xff0c 状态可以是起始状态 接受状
  • zabbix邮箱告警的三种方式

    zabbix邮箱告警的三种方式 1 在web界面配置邮箱告警2 在本地邮箱配置邮箱告警 43 脚本3 在第三方邮箱配置邮箱告警 43 脚本 1 在web界面配置邮箱告警 添加媒介 我们以126邮箱为示例 先打开POP3 SMTP服务 xff
  • NanoStringQCPro: Quality metrics and data processing methods for NanoString mRNA gene expression dat

    addCodesetAnnotationAdd NanoString codeset annotation to an RccSetaddQCFlagsAdd sample QC flags to an rccSetallSumPlotal
  • Python爬虫编程7——多线程爬虫

    目录 一 多线程基本介绍 程序中模拟多任务 二 多线程的创建 三 主线程与子线程的执行关系 四 查看线程数量 五 线程间的通信 xff08 多线程共享全局变量 xff09 六 线程间的资源竞争 互斥锁和死锁 互斥锁 死锁 七 Queue线程
  • SCL 和 SDA 是 I2C 总线上的两个信号线。 c++ 模拟数据

    I2C xff08 Inter Integrated Circuit xff0c 又称为 IIC 或 TWI xff09 是一种串行通信协议 xff0c 用于在微控制器和外围设备之间进行数据传输 I2C 协议只需要两根信号线 xff1a S
  • Python 代码中三种波浪线和 PEP8

    红色 红色波浪线是代码的错误 必须处理 代码才能执行 注意 在后续课程中 某些代码没有写完 也会出现红色波浪线 灰色 灰色波浪线 xff0c 不会影响代码的正常执行 xff0c 基本上所有的灰色 浪线都是PEP8 造成的PEP8 是Pyth
  • 阶乘累加求和

    项目场景 xff1a 入门练习题 问题描述 xff1a 提示 xff1a 这里描述项目中遇到的问题 xff1a 请用函数编程实现 求和 1 43 2 43 3 xff01 43 n xff
  • python爬虫之数据解析(BeautifulSoup)

    BeautifulSoup也是python爬虫常用的一种数据解析方法 xff0c 主要就两步 1 实例化一个Beautifulsoup对象 xff0c 平且将页面源码数据加载到该对象中 2 通过调用Beautifulsoup对象中相关的属性
  • 解决Ubuntu不能上网以及无法远程连接Ubuntu

    本文环境 物理机OS xff1a Windows10 专业版 虚拟机平台 xff1a VMware Workstation 16 Pro 虚拟机OS xff1a Ubuntu 20 04 相信大家在使用Ubuntu中也有遇到不能上网 xff
  • Python实现地方天气查询并语音播报。

    续上次篇程序 xff0c 有老哥说做个续集 xff0c 那我就做个续集和优化 xff0c 升级 上篇文章 xff1a Python获取城市天气 详细介绍用api获取城市的天气赶快收藏起来 xff01 Pymili的博客 CSDN博客 pyt
  • JAVA 实参和形参

    形参 xff1a 是指在定义函数 时使用的参数 xff0c 目的是用于接收调用该函数时传入的参数 简单理解 xff0c 就是所有函数 xff08 即方法 xff09 的参数都是形参 实参 xff1a 在调用有参函数时 xff0c 主调函数和
  • JAVA 包装类

    1 概念 Java是一个面向对象的编程语言 xff0c 但是Java中的八种基本数据类型却是不面向对象的 xff0c 为了使用方便和解决这个不足 xff0c 在设计类时为每个基本数据类型设计了一个对应的类进行代表 xff0c 这样八种基本数
  • swagger被拦截器拦截

    配置swagger文档 xff0c 被拦截器拦截不能使用 拦截器中添加以下配置 xff0c 适当修改即可使用 重写addInterceptors registry addInterceptor new UserInterceptor add
  • JAVA之JDBC连接数据库

    前景说明 xff1a 在我们刚开始使用数据库的时候 xff0c 发现只能在mysql编辑器里面使用sql语句来完成对数据库的操作 xff0c 那我们怎么来通过Java来操控数据库呢 xff1f 这个时候就有了JDBC的出现 1 什么是JDB
  • Css margin 和 float浮动

    1 浮动 定义 浮动是css里面布局最多的一个属性 xff0c 也是很重要的一个属性 float xff1a 表示浮动的意思 它有四个值 none 表示不浮动 xff0c 默认right xff1a 表示右浮动left 表示左浮动 floa
  • Java Servlet组件

    1 什么是Servlet xff1f 从广义上来讲 xff0c Servlet规范是Sun公司制定的一套技术标准 xff0c 包含与Web应用相关的一系列接口 xff0c 是Web应用实现方式的宏观解决方案 而具体的Servlet容器负责提
  • JAVA 之 Ajax

    1 什么是Ajax xff1f AJAX xff08 Asynchronous Javascript And XML xff09 翻译成中文就是 异步Javascript和XML 即是用Javascript语言与服务器进行异步交互 xff0
  • Servlet 的Request和Response

    1 Request和Response概述 1 Request 获取请求数据 浏览器会发送HTTP请求到后台服务器 Tomcat HTTP的请求中会包含很多请求数据 请求行 43 请求头 43 请求体 后台服务器 Tomcat 会对HTTP请