request、response 的复习总结
文章目录
概述
servlet最主要的作用就是处理客户端的请求,并及时向客户端做出响应。为此,对于servlet的每次请求,服务器在调用 service()
方法之前,都会创建两个对象 — 即 HttpServletRequest 对象和 HttpServletResponse 对象。
其中,HttpServletRequest 用于封装 http 请求消息,称为 request 对象;HttpServletResponse 用于封装 http 响应消息,称为 response 对象。
注:服务器运行阶段,每个servlet都只会创建一个实例对象。但对于每次的http请求都会调用该servlet实例的 service(HttpServletRequest request, HttpServletResponse response
方法重新创建一个 request 对象和 response 对象。
1.request 对象
1.1 HttpServletRequest 简介
在servlet中,HttpServletRequest 接口继承自 ServletRequest 接口,专门用于封装 http 请求消息。对应于 http 请求消息的请求行、请求消息头和请求消息体,HttpServletRequest 接口中定义了获取请求行、请求消息头和请求消息体的方法。
1.2 获取请求行相关方法
在 http 请求行中,包含请求方法、请求资源名、请求路径等等信息,对应这些消息, HttpServletRequest 接口定义了一系列用于获取请求行的方法:
方法 | 功能描述 | 注意 |
---|---|---|
String getMethod() | 获取http请求消息的请求方式(如get,post等) | GET/POST |
String getRequestURI() | 获取请求行中的资源名称 | 地址栏主机和端口之后,参数之前的内容 |
String getQueryString() | 获取请求行中的参数内容 | 请求地址(?)以后的所有内容 |
String getContextPath() | 获取请求URL中属于WEB应用程序的路径(返回上下文路径),这个路径以’/'开头,表示相对于整个WEB站点的根目录 | 应用较多** |
String getServletPath() | 获取当前Servlet的名称或Servlet映射的路径 | |
String getRemoteAddr() | 获取请求客户端的IP地址 | IPV4或IPV6地址 |
String getRemoteHost() | 获取请求客户端的完整主机名(如果无法解析出客户端的完整主机名,将返回客户端的IP地址) | |
int getRemotePort() | 获取请求客户端网络连接的端口号 | |
String getServletName() | 获取当前请求所指向的主机名 | |
String getServletPort() | 获取当前请求所连接的服务器端口号 | |
String getScheme() | 获取请求的协议名 | http,https,ftp等 |
StringBuffer getRequestURL() | 获取客户端发出请求时完整URL,包括协议,服务器名、端口号、资源路径等信息,但不包括参数 | 注意区分URL和URI |
说着简单,动手实践一下比什么都清楚:
方法使用:
直接在地址栏输入:http://localhost:8888/MyServletTest01/Test00Servlet?name=zhangsan 带参数访问Test00Servlet
1.3 获取请求消息头相关方法
http 请求消息中,需要通过请求头向服务器传递附加信息,如:客户端可以接收的数据类型(以便设置相应消息的数据),请求消息体的字符集编码等,HttpServletRequest 接口也定义有一系列用于获取 http 请求头字段的方法:
1)String getHeader(String name)
此方法用于获取一个指定头字段的值(类似于key-value),如果请求中没有相应的头字段,返回 null;如果请求消息中包含有多个指定名称的头字段,返回其中第一个头字段的值。
2)Enumeration getHeaders(String name)
此方法返回一个 Enumeration 集合对象,该集合对象由请求消息中出现的某个指定名称的所有头字段的值组成(大多数情况下,一个头字段在请求消息中只出现一次,但有时可能会出现多次)。此方法去除 参数 name 即可用于获取请求头消息中所有头字段的值(同样返回 Enumeration 集合对象)
3)int getIntHeader(String name)
用于获取指定名称的头字段,并且将其值转化为 int 类型;若指定名称的头字段不存在,返回值为-1;若获取到的头字段的值不能转化为 int 类型,则报错(异常)
4)String getContentType()
获取 Content-Type 头字段的值,结果为 String 类型;如果请求是GET,那么这个方法返回null
5)int getContentLength()
获取 Content-Length 头字段的值,结果为 int 类型;GET请求没有请求体,返回-1
6)String getCharacterEncoding()
此方法返回请求消息的实体部分的字符集编码,通常是从 Content-Type 头字段中进行提取,结果为 String 类型;对于GET而言,没有请求体!所以此方法只能对POST请求中的参数有效
1.3 获取请求参数相关方法(重点:拿小本本记着)
在实际开发中,经常需要获取用户提交的表单数据,或者链接中的参数,为了方便获取这些参数,HttpServletRequest 接口的父类 ServletRequest 中定义了一系列获取请求参数的方法:
1)String getParameter(String name)
获取某个指定名称的参数值;若请求消息中没有包含指定名称的参数,返回null;若指定名称的参数存在但没有设置值,返回空字符串(与null不同);若请求消息中包含多个该指定名称的参数,则返回第一个出现的参数值
2)String[] getParameterValues(String name)
http 请求消息中可以有多个相同名称的参数(如表单的多选框等),如果要获取请求消息中同一个名称所对应的所有参数值,即可使用
String[] getParameterValues(String name)
。此方法返回一个 String 类型的数组
3)Enumeration getParameterNames()
返回一个包含请求消息中所有参数名的 Enumeration 对象。通过此方法,可以对请求消息中的所有参数进行遍历处理
4)Map getParameterMap()
此方法将请求消息中的所有参数名和对应的值装入一个 Map 对象中,并返回此 Map 对象
5)InputStream getInputStream()
返回的一个代表实体内容的输入流对象,其类型为
javax.servlet.ServletInputStream
6)BufferedReader getReader()
返回的一个代表实体内容的 BufferedReader 对象,返回的 BufferedReader 对象将实体内容中的字节数据按照请求消息中指定的字符集编码转换成文本字符串
注:getParameter、getInputStream、getReader 都是从selvlet中request对象得到提交的数据,但是用途不同;要根据 form 表单提交数据的编码方式( form表单的一个关键属性:enctype)选择不同的方法。
1.enctype=application/x- www-form-urlencoded
是表单默认的编码方式,编码后的结果通常是field1=value1&field2=value2&… 的形式,如 name=aaaa&password=bbbb…
通常的表单都是采用这种方式进行编码,此时只需要简单地通过 getParameter 方法即可获取用户表单提交的数据
2.multipart/form-data
此编码方式用于传输大块的二进制数据,客户端将表单内的数据和文件放在一起发送。
以这种方式编码的表单,则需要使用 getInputStream 或 getReader 方法(getParameter 无法获取这种编码方式下提交的数据)
3.这3种方法是有冲突的(表单中提交的数据以流形式被读取,流只能被读一次);在第一种编码方式下,3种方法都有冲突,只能使用其中一种方法(建议使用 getParameter);在第二种编码方式下,因为 getParameter 无法读取数据,故只有 getInputStream 和 getReader 方法之间存在冲突,只能使用一种方法读取
2.response 对象
2.1 HttpServletResponse 简介
在servlet中,HttpServletResponse 接口继承自 ServletResponse 接口,专门用于封装 http 响应消息。对应于 http 响应消息的状态行、响应消息头和消息体,HttpServletResponse 接口中定义了向客户端发送响应状态码、响应消息和响应消息体的方法。
2.2 发送状态码相关方法
当 servlet 向客户端返回响应消息时,需要在响应消息中设置状态码。对此,HttpServletResponse 中定义了发送状态码的方法:
1)setStatus(int sc)
方法
该方法用于设置 http 响应消息的状态码,并生成响应状态行(包括http协议的版本和状态描述信息),状态行的状态描述信息直接与状态码相关,而http协议的版本由服务器直接确定,所以,只需要通过 setStatus(int sc) 方法设置了状态码即可实现状态行的生成)。
正常情况下,服务器会默认产生一个状态码为200的状态行,即 — HTTP/1.1 200 OK
2)sendError(int sc)
方法
该方法用于发送表示错误信息的状态码,如,404表示找不到客户端请求的资源。在 response 对象中,提供了两个重载的 sendError 方法:
1.public void sendError(int sc)
2.public void sendError(int sc, String msg)
第一个方法只发送错误信息的状态码;第二个方法除了发送状态码外,还增加了一条用于提示说明的 String 字符串信息(将出现在发送给客户端的正文内容中)
2.3 发送响应消息头相关方法
当 servlet 向客户端发送响应消息时,对应 http 协议的多种响应字段,HttpServletResponse 接口定义有一系列设置 http 响应头字段的方法:
1)addHeader(String name,String value)
setHeader(String name,String value)
上述两个方法用于设置 HTTP 协议的响应头字段,其中 name 指定响应头字段名称,value 指定对应的值(好比 key-value 形式),addHeader 方法可以增加同名的响应头字段(key是可以重复的),而 setHeader 方法则会覆盖同名的头字段(修改原来的)
2)addIntHeader(String name,int value)
setIntHeader(String name,int value)
这两个方法专用于设置包含整数值的响应头(避免前二个方法使用时需要将int类型转换为String类型)
3)setContentLength(int len)
该方法用于设置响应消息的实体内容的大小,单位是字节。对于 http 协议,这个方法就是设置Content-Length 响应头字段的值
4)setContentType(String type)
此方法用于设置Servlet输出内容的MIME类型;对于 http 协议,就是设置 Content-Type 响应头字段的值。例如:如果发送到客户端的内容是 .jpg 格式的图像数据,就需要将 Content-Type 设置为 “image/jpg”;如果响应的内容(如Servlet的输出内容)为文本,
setContentType(String type)
方法用于设置字符编码,如:“text/html;charset=UTF-8”(等同与调用response.setHeader(“content-type”, “text/html;charset=utf-8”)
)
5)setCharacterEncoding(String charset)
此方法用于设置输出内容使用的字符集编码,对 http 协议来说,就是设置 Content-Type 字段中的字符编码部分。如果没有设置 Content-Type 字段,
setCharacterEncoding(String charset)
方法设置的字符集编码就不会出现在 http 响应头消息中。另外,setCharacterEncoding(String charset)
的优先级高于setContentType(String type)
,它的设置结果将覆盖setContentType(String type)
方法设置的字符集编码
2.4 发送响应消息体相关方法
在响应消息中,ServletResponse(HttpServletResponse 的父接口)定义有两个IO流输出方法:
1)getOutputStream()
此方法所获取的字节输出流对象为
ServletOutputStream
类型。ServletOutputStream
是OutputStream
的子类,它也可以直接输出字节数组中的二进制数据(若想输出二进制格式的响应正文,可以使用getOutputStream()
方法获取 ServletOutputStream 对象),并通过write()
方法输出。
2)getWriter()
正如 IO 流的字节输出流和字符输出流,ServletResponse 也定义有字符输出流对象 PrintWriter,PrintWriter 类型的对象对应的获取方法正是
getWriter()
,它可以直接获取字符文本内容(若要输出内容为字符文本的响应正文,可以使用getWriter()
方法),并通过write()
方法输出。
注:需要注意的是,getOutputStream()
方法和 getWriter()
方法不能同时使用,其原因是因为调用 response.getWriter()
之前必须先调用 response.getOutputStream()
方法。
对于 request 、response 编码时产生的乱码,见 传送门 !!!