Servlet系列:(HttpServletRequest、HttpServletResponse、ServletContext、ServletConfig)详解
HttpServletRequest
HttpServletRequest 对象:主要作用是用来接收客户端发送过来的请求信息,例如:请求的参数,发送的头信息等都属于客户端发来的信息,service()方法中形参接收的是 HttpServletRequest 接口的实例化对象,表示该对象主要应用在 HTTP 协议上,该对象是由 Tomcat 封装好传递过来。
HttpServletRequest 是 ServletRequest 的子接口,ServletRequest 只有一个子接口,就是HttpServletRequest。既然只有一个子接口为什么不将两个接口合并为一个?
从长远上讲:现在主要用的协议是 HTTP 协议,但以后可能出现更多新的协议。若以后想要支持这种新协议,只需要直接继承 ServletRequest 接口就行了。
在 HttpServletRequest 接口中,定义的方法很多,但都是围绕接收客户端参数的。但是怎么拿到该对象呢?不需要,直接在 Service 方法中由容器传入过来,而我们需要做的就是取出对象中的数据,进行分析、处理。
接收请求
常用方法
- getMethod():获取请求的HTTP方法,例如GET、POST等。
- getRequestURL():获取请求的URL地址。
- getRequestURI():获取请求的URI部分。
- getPathInfo():获取请求的路径信息,即URL中“/”之后的部分。
- getQueryString():获取请求的查询参数,即URL中“?”后面的部分。
- getHeader():获取请求头中的指定字段的值。
- getParameter():获取请求参数的值。如果参数不存在,则返回null。
- getParameterValues():获取请求参数的所有值。如果参数不存在,则返回null。
- getInputStream()和getReader():获取请求的输入流或读取器,用于读取请求的内容。
- getSession()和getSession(boolean create):获取与当前请求关联的HttpSession对象。如果当前请求没有关联的HttpSession对象,则可以创建新的HttpSession对象。
- getServletPath():获取当前请求的Servlet路径。
示例
// 获取客户端请求的完整URL (从http开始,到?前面结束)
String url = request.getRequestURL().toString();
System.out.println("获取客户端请求的完整URL:" + url);
// 获取客户端请求的部分URL (从站点名开始,到?前面结束)
String uri = request.getRequestURI();
System.out.println("获取客户端请求的部分URL:" + uri);
// 获取请求行中的参数部分
String queryString = request.getQueryString();
System.out.println("获取请求行中的参数部分:" + queryString);
// 获取客户端的请求方式
String method = request.getMethod();
System.out.println("获取客户端的请求方式:" + method);
// 获取HTTP版本号
String protocol = request.getProtocol();
System.out.println("获取HTTP版本号:" + protocol);
// 获取webapp名字 (站点名)
String webapp = request.getContextPath();
System.out.println("获取webapp名字:" + webapp);
请求乱码问题
由于现在的 request 属于接收客户端的参数,所以必然有其默认的语言编码,主要是由于在解析过程中默认使用的编码方式为 ISO-8859-1(此编码不支持中文),所以解析时一定会出现乱码。要想解决这种乱码问题,需要设置 request 中的编码方式,告诉服务器以何种方式来解析数据。或者在接收到乱码数据以后,再通过相应的编码格式还原。
方式一:
这种方式只针对 POST 有效(必须在接收所有的数据之前设定)
request.setCharacterEncoding("UTF-8");
方式二:
new String(request.getParameter(name).getBytes("ISO-8859-1"),"UTF-8")
借助了String 对象的方法,该种方式对任何请求有效,是通用的。
Tomcat8起,以后的GET方式请求是不会出现乱码的。
请求转发
请求转发,是一种服务器的行为,当客户端请求到达后,服务器进行转发,此时会将请求对象进行保存,地址栏中的 URL 地址不会改变,得到响应后,服务器端再将响应发送给客户端,从始至终只有一个请求发出。
实现方式如下,达到多个资源协同响应的效果。
request.getRequestDispatcher(url).forward(request,response);
request作用域
通过该对象可以在一个请求中传递数据,作用范围:在一次请求中有效,即服务器跳转有效
// 设置域对象内容
request.setAttribute(String name, String value);
// 获取域对象内容
request.getAttribute(String name);
// 删除域对象内容
request.removeAttribute(String name);
request 域对象中的数据在一次请求中有效,则经过请求转发,request 域中的数据依然存在,则在请求转发的过程中可以通过 request 来传输/共享数据。
HttpServletResponse
Web服务器收到客户端的http请求,会针对每一次请求,分别创建一个用于代表请求的 request 对象和代表响应的 response 对象。
request 和 response 对象代表请求和响应:获取客户端数据,需要通过 request 对象;向客户端输****出数据,需要通过 response 对象。
HttpServletResponse 的主要功能用于服务器对客户端的请求进行响应,将 Web 服务器处理后的结果返回给客户端。service()方法中形参接收的是 HttpServletResponse 接口的实例化对象,这个对象中封装了向客户端发送数据、发送响应头,发送响应状态码的方法。
响应数据
接收到客户端请求后,可以通过 HttpServletResponse 对象直接进行响应,响应时需要获取输出流。
有两种形式:
getWriter() 获取字符流(只能响应回字符)
// 字符输出流
PrintWriter writer = response.getWriter();
writer.write("Hello");
writer.write("<h2>Hello</h2>");
getOutputStream() 获取字节流(能响应一切数据)
// 字节输出流
ServletOutputStream out = response.getOutputStream();
out.write("Hello".getBytes());
out.write("<h2>Hello</h2>".getBytes());
响应回的数据到客户端被浏览器解析。
注意:两者不能同时使用
设置响应类型,默认是字符串
// 设置响应MIME类型
response.setHeader("content-type","text/html"); // html
响应乱码问题
在响应中,如果我们响应的内容中含有中文,则有可能出现乱码。这是因为服务器响应的数据也会经过网络传输,服务器端有一种编码方式,在客户端也存在一种编码方式,当两端使用的编码方式不同时则出现乱码。
getWriter()的字符乱码
对于 getWriter()获取到的字符流,响应中文必定出乱码,由于服务器端在进行编码时默认会使用 ISO-8859-1 格式的编码,该编码方式并不支持中文。
要解决该种乱码只能在服务器端告知服务器使用一种能够支持中文的编码格式,比如我们通常用的"UTF-8"。
response.setCharacterEncoding("UTF-8");
此时还只完成了一半的工作,要保证数据正确显示,还需要指定客户端的解码方式。
response.setHeader("content-type", "text/html;charset=UTF-8");
两端指定编码后,乱码就解决了。一句话:保证发送端和接收端的编码一致
// 设置服务端的编码
response.setCharacterEncoding("UTF-8");
// 设置客户端的响应类型及编码
response.setHeader("content-type","text/html;charset=UTF-8");
// 得到字符输出流
PrintWriter writer = response.getWriter();
writer.write("<h2>你好</h2>");
以上两端编码的指定也可以使用一句替代,同时指定服务器和客户端
注意:使用set的方法必须在getWriter()方法之前
getOutputStream()字节乱码
对于 getOutputStream()方式获取到的字节流,响应中文时,由于本身就是传输的字节, 所以此时可能出现乱码,也可能正确显示。当服务器端给的字节恰好和客户端使用的编码方式一致时则文本正确显示,否则出现乱码。无论如何我们都应该准确掌握服务器和客户端使用的是那种编码格式,以确保数据正确显示。
指定客户端和服务器使用的编码方式一致。
response.setHeader("content-type","text/html;charset=UTF-8");
// 设置客户端的编码及响应类型
ServletOutputStream out = response.getOutputStream();
response.setHeader("content-type","text/html;charset=UTF-8");
out.write("<h2>你好</h2>".getBytes("UTF-8"));
同样也可以使用一句替代
// 设置客户端与服务端的编码
response.setContentType("text/html;charset=UTF-8");
总结:要想解决响应的乱码,只需要保证使用支持中文的编码格式。并且保证服务器端 和客户端使用相同的编码方式即可
重定向
重定向是一种服务器指导,客户端的行为。客户端发出第一个请求,被服务器接收处理后,服务器会进行响应,在响应的同时,服务器会给客户端一个新的地址(下次请求的地址response.sendRedirect(url);),当客户端接收到响应后,会立刻、马上、自动根据服务器给的新地址发起第二个请求,服务器接收请求并作出响应,重定向完成。
从描述中可以看出重定向当中有两个请求存在,并且属于客户端行为。
// 重定向跳转到index.jsp
response.sendRedirect("index.jsp");
通过观察浏览器我们发现第一次请求获得的响应码为 302,并且含有一个 location 头信息。并且地址栏最终看到的地址是和第一次请求地址不同的,地址栏已经发生了变化。
请求转发与重定向的区别
请求转发和重定向比较:

两者都可进行跳转,根据实际需求选取即可。
ServletContext
每一个 web 应用都有且仅有一个ServletContext 对象,又称 Application 对象,从名称中可知,该对象是与应用程序相关的。在 WEB 容器启动的时候,会为每一个 WEB 应用程序创建一个对应的ServletContext 对象。
该对象有两大作用:
- 第一、作为域对象用来共享数据,此时数据在整个应用程序中共享;
- 第二、该对象中保存了当前应用程序相关信息。例如可以通过 getServerInfo() 方法获取当前服务器信息 ,getRealPath(String path) 获取资源的真实路径等。
ServletContext 对象的获取
获取 ServletContext 对象的途径有很多。比如:
通过 request 对象获取
@Override
public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException,
IOException {
ServletContext servletContext = request.getServletContext();
}
通过 session 对象获取
@Override
public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException,
IOException {
ServletContext servletContext = request.getSession().getServletContext();
}
通过 servletConfig 对象获取,在 Servlet 标准中提供了 ServletConfig 方法
@Override
public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException,
IOException {
ServletContext servletContext = getServletConfig().getServletContext();
}
直接获取,Servlet 类中提供了直接获取 ServletContext 对象的方法
@Override
public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException,
IOException {
ServletContext servletContext = getServletContext();
}
常用方法
// 获取项目存放的真实路径
String realPath = request.getServletContext().getRealPath("/");
// 获取当前服务器的版本信息
String serverInfo = request.getServletContext().getServerInfo();
ServletContext域对象
ServletContext 也可当做域对象来使用,通过向 ServletContext 中存取数据,可以使得整个应用程序共享某些数据。当然不建议存放过多数据,因为 ServletContext 中的数据一旦存储进去没有手动移除将会一直保存。
// 获取ServletContext对象
ServletContext servletContext = request.getServletContext();
// 设置域对象
servletContext.setAttribute("name","zhangsan");
// 获取域对象
String name = (String) servletContext.getAttribute("name");
// 移除域对象
servletContext.removeAttribute("name");
Servlet的三大域对象
- request域对象
在一次请求中有效。请求转发有效,重定向失效。
- session域对象
在一次会话中有效。请求转发和重定向都有效,session销毁后失效。
- servletContext域对象
在整个应用程序中有效。服务器关闭后失效。
ServletConfig
ServletConfig对象是它所对应的Servlet对象的相关配置信息 ,每一个servlet对象都有一个ServletConfig对象和它相对应
getInitParameter(String name) 返回一个初始化变量的值
getInitParameterNames() Enumeration 返回servlet初始化参数的所有名称
getServletContext() 获取ServletContext对象 后面的课程具体讲解ServletContext
getServletName() 获取Servlet的name配置值
@Override
public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException,
IOException {
ServletConfig servletConfig = getServletConfig();
servletConfig.getInitParameter("userName"); //
}
定义
@WebServlet(value = "/context",initParams = {
@WebInitParam(name="userName",value = "robin")
})
Servlet系列:(HttpServletRequest、HttpServletResponse、ServletContext、ServletConfig)详解的更多相关文章
- mvc-servlet---ServletConfig与ServletContext对象详解(转载)
ServletConfig与ServletContext对象详解 一.ServletConfig对象 在Servlet的配置文件中,可以使用一个或多个<init-param>标签为s ...
- ServletConfig详解 (转载)
ServletConfig详解 (转载) 容器初始化一个servlet时,会为这个servlet建一个唯一的ServletConfig.容器从DD读出Servlet初始化参数,并把这些参数交给S ...
- 深入浅出Mybatis系列(四)---配置详解之typeAliases别名(mybatis源码篇)
上篇文章<深入浅出Mybatis系列(三)---配置详解之properties与environments(mybatis源码篇)> 介绍了properties与environments, ...
- Android Studio系列教程五--Gradle命令详解与导入第三方包
Android Studio系列教程五--Gradle命令详解与导入第三方包 2015 年 01 月 05 日 DevTools 本文为个人原创,欢迎转载,但请务必在明显位置注明出处!http://s ...
- 构建安全的Xml Web Service系列之wse之错误代码详解
原文:构建安全的Xml Web Service系列之wse之错误代码详解 WSE3.0现在还没有中文版的可以下载,使用英文版的过程中,难免会遇到各种各样的错误,而面对一堆毫无头绪的错误异常,常常会感到 ...
- [js高手之路] es6系列教程 - 对象功能扩展详解
第一:字面量对象的方法,支持缩写形式 //es6之前,这么写 var User = { name : 'ghostwu', showName : function(){ return this.nam ...
- [转帖]Linux系列之SAR命令使用详解
Linux系列之SAR命令使用详解 sar是System Activity Reporter(系统活动情况报告)的缩写.这个工具所需要的负载很小,也是目前linux中最为全面的性能分析工具之一.此款工 ...
- SpringBoot系列(十二)过滤器配置详解
SpringBoot(十二)过滤器详解 往期精彩推荐 SpringBoot系列(一)idea新建Springboot项目 SpringBoot系列(二)入门知识 springBoot系列(三)配置文件 ...
- ServletConfig与ServletContext对象详解
一.ServletConfig对象 在Servlet的配置文件中,可以使用一个或多个<init-param>标签为servlet配置一些初始化参数.(配置在某个servlet标签或者整个w ...
- Servlet中Web.xml的配置详解
1 定义头和根元素 部署描述符文件就像所有XML文件一样,必须以一个XML头开始.这个头声明可以使用的XML版本并给出文件的字符编码. DOCYTPE声明必须立即出现在此头之后.这个声明告诉服务器适用 ...
随机推荐
- 吉特日化MES-日化生产相关设备区分
在化妆品生产过程中约到各种各样的设备,对日化生产设备做一些简单的整理汇总,便于学习(其中设备根据其所在的产品以及领域会有一定的不同) 从产品的角度可以将产品划分为: (1) 乳化剂类产品 (2) 分类 ...
- [ABC263G] Erasing Prime Pairs
Problem Statement There are integers with $N$ different values written on a blackboard. The $i$-th v ...
- IDEA创建Springboot项目在application.yml配置文件配置了nacos远程注册中心,启动项目还是找localhost的问题
项目结构如下: 报错如下: 解决办法: # 错误的 #spring.cloud.nacos.config.server-addr=192.168.137.137:8848 #spring.cloud. ...
- MySQL运维7-Mycat水平分表
一.水平分表场景 在业务系统中,有一张日志表,业务系统每天都会产生大量的日志数据,单台服务器的数据存储即处理能力是有限的,可以对数据库表进行拆分,这时候就可以使用水平分表的策略 说明1:水平分表,每个 ...
- rust 过程宏
简介 Rust 编程语言里面有两种宏系统,一种是声明宏(Declarative Macros),另一种为过程宏(Procedural Macros).声明宏和过程宏是两种基本上完全不一样的宏系统,编写 ...
- Halo新年灯笼-halonewyaer
title: Halo新年灯笼 date: 2021-12-29 15:49:34.665 updated: 2022-03-10 16:00:53.189 url: https://www.yby6 ...
- 微软真是活菩萨,面向初学者的机器学习、数据科学、AI、LLM课程统统免费
微软真是活菩萨,面向初学者的机器学习.数据科学.AI.LLM课程统统免费 大家好,我是老章 推荐几个质量上乘且完全免费的微软开源课程 面向初学者的机器学习课程 地址:https://microsoft ...
- 如何从零开始实现TDOA技术的 UWB 精确定位系统(2)
这是一个系列文章<如何从零开始实现TDOA技术的 UWB 精确定位系统>第2部分. 重要提示(劝退说明): Q:做这个定位系统需要基础么?A:文章不是写给小白看的,需要有电子技术和软件编程 ...
- Centos7 Zabbix3.2安装(yum)
http://repo.zabbix.com/zabbix/3.2/rhel/7/x86_64/ #官网下载地址(只包含zabbix的应用包) ftp://47.104.78.123/zabbix/ ...
- Spring 中循环依赖的处理
Spring 提供了十分强大的依赖注入功能,使得我们不再需要手动去管理对象的依赖项.然而,在实际的使用场景中,可能会遇到类似下面的依赖异常: Exception encountered during ...