1. request
代表HTTP请求。
a. HTTP请求由四部分组成:
请求行 get 请求资源名称 HTTP协议版本
多个请求头
一个空行
请求实体内容 请求参数
b. 请求的继承结构
ServletRequest
|
|----HttpServletRequest 在原有接口之上添加了HTTP协议相关的API,更善于HTTP协议相关开发。
2. 请求的功能
a. 获取请求资源
getRequestURL方法 -- 返回客户端发出请求完整URL
getRequestURI方法 -- 返回请求行中的资源名部分
getQueryString方法 -- 返回请求行中的参数部分
getRemoteAddr方法 -- 返回发出请求的客户机的IP地址
getMethod -- 得到客户机请求方式
!!getContextPath -- 获得当前web应用虚拟目录名称 -- 在写路径时不要将web应用的虚拟路径的名称写死, 应该在需要写web应用的名称的地方通过getContextPath方法动态获取
public class RequestDemo1 extends HttpServlet { // getRequestURL方法 -- 返回浏览器发出请求完整URL // getRequestURI方法 -- 返回请求行中的资源名部分 // getQueryString方法 -- 返回请求行中的参数部分 // getRemoteAddr方法 -- 返回发出请求的客户机的IP地址 // getMethod -- 得到浏览器请求方式 // !!getContextPath -- 获得当前web应用虚拟目录名称 -- 在写路径时不要将web应用的虚拟路径的名称写死, 应该在需要写web应用的名称的地方通过getContextPath方法动态获取 public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //请求的URL 路径是http://localhost:8080/day08-servlet/servlet/RequestDemo1?username=xwq&password=123456 StringBuffer url = request.getRequestURL(); System.out.println("url:"+url.toString()); //url:http://localhost:8080/day08-servlet/servlet/RequestDemo1 String uri = request.getRequestURI(); System.out.println("uri:"+uri); //uri:/day08-servlet/servlet/RequestDemo1 String qs = request.getQueryString(); System.out.println("qs:"+qs);//qs:username=xwq&password=123456 String ip = request.getRemoteAddr(); System.out.println("ip:"+ip);//ip:127.0.0.1 String method = request.getMethod(); System.out.println("method:"+method);//method:GET String cp = request.getContextPath(); System.out.println("path:"+cp);//path:/day08-servlet } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
b. 获取请求头
getHeader(name)方法 --- String
getHeaders(String name)方法 --- Enumeration<String>
getHeaderNames方法 --- Enumeration<String>
getIntHeader(name)方法 --- int
getDateHeader(name)方法 --- long(日期对应毫秒)
// getHeader(name)方法 --- String // getHeaders(String name)方法 --- Enumeration<String> // getHeaderNames方法 --- Enumeration<String> // getIntHeader(name)方法 --- int // getDateHeader(name)方法 --- long(日期对应毫秒) public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //根据请求头的名称获取对应值的操作 String header = request.getHeader("Host"); System.out.println("header:"+header); //根据请求头的名称获取对应值的操作--多个相同名称的请求头就好像多选框 Enumeration<String> headers = request.getHeaders("host"); while (headers.hasMoreElements()) { String name = headers.nextElement(); System.out.println("name:"+name); } //获取全部请求头的名称 Enumeration<String> headerNames = request.getHeaderNames(); while (headerNames.hasMoreElements()) { String head = (String) headerNames.nextElement();//获取的请求头名称 String value = request.getHeader(head); //根据请求头获取对应的值 System.out.println("headername:"+head+">>value:"+value); } //如果指定的一个 头数据不能转化为整数,则抛出异常NumbereFormatException int intHeader = request.getIntHeader(""); System.out.println(intHeader); //返回一个Unix时间戳(毫秒),如果头数据不能转化为日期,则抛出异常IllegalArgumentException long dateHeader = request.getDateHeader(""); System.out.println(dateHeader); //获取请求内容的字符编码 String characterEncoding = request.getCharacterEncoding(); System.out.println(characterEncoding);
c. 获取请求实体内容
getParameter(String name) --- String 通过name获得值
getParameterValues(String name) --- String[ ] 通过name获得多值 checkbox
getParameterMap() --- Map<String,String[ ]> key :name value: 多值 将查询的参数保存在一个Map中
getParameterNames() --- Enumeration<String> 获得所有name
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //必须放在获取请求参数的代码之前,推荐放在所有代码之前。 //通知服务器使用utf-8接收数据post请求有效。get请求无效 // request.setCharacterEncoding("utf-8"); //将?编码 String username = request.getParameter("username"); byte[] bytes = username.getBytes("iso8859-1"); //再重新解码 username = new String(bytes,"utf-8"); System.out.println("username:"+username); //username:徐旺骑 //getParameterValues 根据请求参数名获取一组请求参数值 String[] likes = request.getParameterValues("like"); System.out.println("likes:"+Arrays.toString(likes)); //likes:[lanqiu, zuqiu] 传过来的是多选框上面的values //getParameterMap 将所有请求参数获取到map中 Map<String,String[]> map = request.getParameterMap(); //getparameterNames 获取全部请求参数的名称 Enumeration<String> names = request.getParameterNames(); while (names.hasMoreElements()) { String name = (String) names.nextElement(); String[] values = request.getParameterValues(name); System.out.println("name:"+name+"values:"+Arrays.toString(values)); } }
i. 在获取请求参数时,如果获取中文数据,则会出现乱码。
ii. 乱码产生的原因:
编码和解码字符集不统一。
iii. 浏览器负责发送数据,在发送数据时会对数据编码,发送数据时所使用的字符集是页面加载时的字符集,为utf-8。
iv. 接收数据的是服务器,服务器在接收数据时会采用默认字符集iso8859-1解码数据。
v. 发送与接收字符集不同意,所以出现了乱码。由于iso8859-1中没有中文,所以应该将两者统一为utf-8。修改服务器的字符集。
vi. 如果是post提交,可以进行如下修改:
在所有获取请求参数的代码之前,书写:
request.setCharacterEncoding("utf-8");
这句话仅能处理请求实体内容中的请求参数乱码,所以只对post请求有效。get请求无效。
vii. 如果是get请求,则需要在获取参数之后,先使用iso8859-1编码,在使用utf-8解码。
1) 代码如下:
new String(username.getBytes("iso8859-1"),"utf-8"); //就是将url上获得的参数先转成二进制数据后将二进制数据在进行重新编码。
这种形式,既可以解决get提交的乱码,也可以解决post提交的乱码。
3. request功能--请求转发
请求转发是一种资源跳转方式,发生的服务器内部。
a 代码实现
package cn.tedu.request; import java.io.IOException; import javax.servlet.RequestDispatcher; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class RequestDemo4 extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //创建一个调度器 RequestDispatcher rd = request.getRequestDispatcher("/servlet/RequestDemo5"); //利用调度器实现请求转发 rd.forward(request, response); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
b. 请求转发细节:
i. 请求转发之前如果向response缓冲区中写入数据,这些数据在请求转发是会被清空。
ii. 如果冲刷缓冲区,会造成一次响应,导致请求转发失败.所以不能冲刷缓冲区.
iii. 请求转发可以多重转发,但是不能在同一个servlet内多次请求转发.
iv. 在请求转发前后的代码也会正常执行.
v.在请求转发之前,如果response缓冲区中有数据,
则在请求转发的时候会将这些数据清空。
多个请求转发会组成一个请求链,请求链的执行顺序是先执行所有请求转发之前的代码,在反向指向全部请求转发之后的代码.
4start 5start 6start -> 6end 5end 4end
4. request功能--请求包含
可以将两个servlet结果合并为一个结果输出.
public class RequestDemo8 extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //请求包含 response.getWriter().write("this is RequestDemo8"); request.getRequestDispatcher("/servlet/RequestDemo9").include(request, response); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
5. request功能--作为域对象使用,上面的是requst请求对象
a. 什么是域对象?
i. 如果一个对象身上有一个可以被看见的范围,在这个范围内利用对象身上的map,实现数据的共享,这个对象就可以叫做域对象。
b. 在域对象身上可以设有域属性,操作域属性的api如下:
设置域属性:setAttribute(String name,Object obj);
获取域属性:getAttribute(String name);
删除域属性:removeAttribute(String name);
获取全部域属性的名称:getAttributeNames();
注意:
请求参数是Parameter,会随着form表单发送到服务器,通过getparameter()及其相关api获取.没有setparameter()
域属性是request对象作为域对象使用时,特有的属性。通过setAttribute设置,getAttribute获取。
域属性和请求参数是两个不同的数据,API不能混用。
c. 练习:在servlet中设置域属性,在index.jsp页面获取域属性。
RequestDemo10.java package cn.tedu.request; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; //request作为域对象使用 public class RequestDemo10 extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //在servlet中设置域属性 request.setAttribute("name", "曹洋"); request.setAttribute("age",18); request.setAttribute("gender", "女"); request.setAttribute("wife", "丽丽"); //为了能够让当前servlet和index.jsp页面共享一个范围,需要实现请求转发 request.getRequestDispatcher("/index.jsp").forward(request, response); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
index.jsp: <%@ page language="java" import="java.util.*" pageEncoding="utf-8"%> <!DOCTYPE HTML> <html> <head> </head> <body> <h3>在index.jsp页面获取域属性</h3> 姓名:<%=request.getAttribute("name") %><br> 年龄:<%=request.getAttribute("age") %><br> 性别:<%=request.getAttribute("gender") %><br> 伴侣:<%=request.getAttribute("wife") %><br> </body> </html>
d. 生命周期:
当请求链开始的时候,request对象创建,
当请求链结束的时候request对象销毁。
e. 作用范围:
整个请求链。
f. 主要功能:
在整个请求链中共享数据。