7.7 request对象

7.7.1 获取请求参数

问题1、什么是请求参数?

通过浏览器向服务器发送请求时,
在请求中可以携带一些数据,
这些数据就称之为<mark>请求参数</mark>,

例如:
http://localhost/day10/RequestDemo1?<mark>user=张三</mark>&<mark>like=篮球</mark>&<mark>like=足球</mark>&<mark>age=18</mark>
中的
user=张三&like=篮球&like=足球&age=18

问题2、如何获取请求参数?

request.getParameter(String paramName);-- 通过请求参数的名字,
											获取对应的参数值。
												返回值是一个字符串。
												
request.getParameterValues(String paramName);-- 通过请求参数的名字,
													获取对应的所有参数值组成的数组。

因此,
以后获取<mark>单值</mark>的参数时,推荐<mark>使用getParameter方法</mark>。
如果获取的<mark>多值</mark>的参数(即一个参数名对应多个参数值),推荐<mark>使用getParameterValues方法</mark>

示例:

//获取请求参数(user和like)
String user = request.getParameter("user");
System.out.println("user="+user);

String like = request.getParameter("like");
System.out.println("like="+like);

String[] likes = request.getParameterValues("like");
System.out.println( "likes="+ Arrays.toString( likes ) );

问题3、获取请求参数时的中文乱码问题?

  • 如果是GET提交,并且<mark>tomcat服务器是8.0及以后的版本,GET提交的中文参数是没有乱码问题的</mark>。
    (因为tomcat自8.0版本以后,已经处理了GET提交的中文参数乱码问题!)
  • 如果是GET提交,并且tomcat服务器是7.0及以前的版本,GET提交的中文参数也会有乱码问题。
    如何处理??
    在服务器的server.xml文件中的修改端口的Connector标签上添加一个属性, URIEncoding="utf-8",如下:
<Connector connectionTimeout="20000" port="80" protocol="HTTP/1.1" redirectPort="8443" URIEncoding="utf-8"/>

这样,在tomcat7.0及以前的版本中,GET提交也没有乱码问题!

  • 如果是POST提交,<mark>无论是哪个版本</mark>的tomcat服务器,<mark>POST提交的中文参数都会有乱码</mark>。
    处理方式如下:
//在任何获取请求参数的代码之前,加上一行代码:
request.setCharacterEncoding("utf-8");
//获取请求参数...
...

protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		// TODO Auto-generated method stub
		//response.getWriter().append("Served at: ").append(request.getContextPath());
		//不加这个,有中文,一定乱码
		response.setContentType("text/html;charset=utf-8");
		request.setCharacterEncoding("utf-8");
		PrintWriter out = response.getWriter();
		String user = request.getParameter("user");
		String[] ls = request.getParameterValues("like");
		System.out.println("user=["+user+"] like="+Arrays.toString(ls)+"");
	}

7.7.2 实现请求转发

请求转发是服务器内部资源的一种跳转方式,
即:
<mark>当浏览器发送请求访问服务器中的某一个资源时,该资源将请求转交给另外一个资源进行处理的过程</mark>,就叫做<mark>请求转发</mark>。

<mark>请求转发</mark>和<mark>重定向</mark>都是<mark>资源的跳转方式</mark>,但是跳转的过程有所不同。

请求转发的特点

  • 请求转发前后是<mark>一次请求、一次响应</mark>
  • 请求转发前后,浏览器地址栏<mark>地址不会发生变化</mark>
    (转发是服务器内部的跳转,浏览器看不到)
  • 请求转发前后的<mark>request对象是同一个</mark>
    (因为<mark>请求只有一次</mark>,
    服务器根据一次请求,<mark>只会创建一个request对象</mark>,
    <mark>转发前后都需要request</mark>,
    <mark>所以只能在转发时,将request对象传递给转发后的那个资源</mark>)。
  • <mark>只能在同一个web应用内部中的两个资源之间进行转发</mark>。
    即转发前后的两个资源必须属于同一个web应用。

请求转发实现:

request.getRequestDispatcher("转发到资源的路径").forward(req, res);

Dispatcher - 派遣

7.7.3 作为域对象使用

request在实现转发时,通过request.setAttribute方法和request.getAttribute方法<mark>带数据到目的地</mark>时,
就是通过request对象中的<mark>map集合带数据</mark>,
这个request对象上的map集合以及request对象所在的范围即称之为是一个<mark>域对象</mark>。

域对象…

  • pageContext - 访问时存在,访问后消失
  • request - 多次转发,同一个请求
  • session - 一次对话,包含多次请求(request
  • application - 包含一个web程序

例子

Servlet

/** * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response) */
	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		// TODO Auto-generated method stub
		//response.getWriter().append("Served at: ").append(request.getContextPath());
		//不加这个,有中文,一定乱码
		response.setContentType("text/html;charset=utf-8");
		PrintWriter out = response.getWriter();
		request.setAttribute("name", "刘德华");
		
		//将请求转发到 index.jsp
		request.getRequestDispatcher("index.jsp").
			forward(request, response);
	}

jsp

<%@page import="java.util.Date"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>主页 ^(* ̄(oo) ̄)^</title>
</head>
<body>
	<h1>day10...index.jsp...</h1>
	
	<!-- 执行程序,不会直接输出 -->
	<%
		String name = request.getRemoteAddr(); 
		Object port = request.getRemotePort() ; 
		Object user = request.getAttribute("name"); 
		out.print("Remote Info : " + name +":" + port + " --> "+user);
	%>
	
	<!-- 直接输出,但只能一个表达式 -->
	<%="<p>"+new Date() +"</p>"%>
	
	<hr>
	<p>JSP(全称JavaServer Pages)是由Sun Microsystems公司主导创建的一种***页技术标准。</p>
</body>
</html>

chrome

<mark>如果一个对象具备可以被访问的范围,通过这个对象上的map集合可以在整个范围内实现数据的共享。
这样的对象就叫做域对象</mark>。

在request对象上提供了往域对象中存数据的方法以及取数据的方法:

request.setAttribute(String attrName, Object attrValue);
			-- 添加一个域属性,将属性存入request域中(request对象的map集合里)
							属性名 - attrName - 只能是字符串,
							属性值 - attrValue - 可以是任意类型。
								
request.getAttribute(String attrName)
			-- 根据 属性名 从request域中获取对应的 属性值 
				返回值是一个Object。

request域对象所具备 - 三大特征:

  • 生命周期:(什么时候出生、什么时候死亡)
    一次请求<mark>开始</mark>时,会<mark>创建</mark>代表请求的request对象,
    一次请求<mark>结束</mark>时(响应已完成),会<mark>销毁</mark>request对象。

  • 作用范围
    一次请求范围内
    (
    由于请求转发前后是一次请求,
    所以在请求转发前后可以通过request域带数据到目的地;
    如果是重定向,由于重定向前后是两次请求,request对象也不是同一个,因此在重定向前后不能通过request域带数据。
    )

  • 主要功能
    和转发配合使用,带数据到目的地。