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
域带数据。
) -
主要功能:
和转发配合使用,带数据到目的地。