4.1 request对象
本节介绍request对象的作用范围及其常用的方法。用户每访问一个页面,就会产生一个HTTP请求。这些请求中一般都包含了请求所需的参数值或者信息,如果将request对象看作是客户请求的一个实例,那么这个实例就包含了客户请求的所有数据。因此,可以通过request来获取客户端和服务器端的信息,如IP地址、传递的参数名和参数值、应用系统名、服务器主机名等等。
4.1.1 request对象的常用方法
request对象的常用方法参见表4.1。
表4.1 request对象常用方法
续表
4.1.2 使用request对象接收请求参数
request对象有两种方法获得请求参数值,一个是getParameter(),另一个是getParameterValues()。下面演示使用getParameter()方法获取页面请求参数。
【例4.1】获取网页请求参数
getParameter.jsp是获取页面参数值,代码如下:
----------------- getParameter.jsp ---------------- 01 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> 02 <! DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 03 <html> 04 <head> 05 <title>' getParameter.jsp'</title> 06 <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> 07 </head> 08 <body > 09 <center> 10 <% 11 String name= request.getParameter("name"); 12 String city = request.getParameter("city"); 13 if(name! =null&&city! =null) 14 { 15 %> 16 <p>Welcome <%=name %>,您所在的城市是<%=city %></p> 17 <% 18 }else{ 19 %> 20 <p>欢迎访问本页面!</p> 21 <% 22 } 23 %> 24 </center> 25 </body> 26 </html>
上述代码中,第11、12行代码分别获得参数name、city的参数值。
在访问地址上输入http://localhost:8080/ch04/getParameter.jsp? name=John&city=Beijing后页面效果如图4.1所示。
图4.1 例4.1的运行结果
提示
在URL参数传递时,在页面地址后使用“? ”连接请求参数,参数由“=”相连表示参数名和参数值,一个请求携带多个参数用“&”连接。
实际上,上述传递参数的方法在实际的开发中相比表单提交参数要少用,因为这种提交参数的方法完全将参数暴露出来,不利于隐私保护,所以开发中一般是采取表单提交的方式传递参数。
在表单form中,有两个非常重要的属性action和method。属性action指明表单提交后的数据跳转到指定页面并处理参数。method有两个值,分别是get和post,通常指定为post,因为用get时,在表单中设定的参数和参数值将附加到页面地址的末尾以参数的形式提交,这样会暴露参数值,不安全;而指定为post,提交表单时,表单中的参数将被作为请求头部中的信息发送,不会在目标地址中添加任何参数,这样也就不会暴露出参数值。所有出于安全考虑,一般会选择post提交。
【例4.2】表单post提交获取网页请求参数
【程序结构】
ex4_1.jsp页面将用户填写的内容提交给getParameter.jsp。页面关系如图4.2所示。
图4.2 例4.2的页面关系图
ex4_1.jsp是用户提交页面,源代码如下:
----------------- ex4_1.jsp ---------------- 01 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> 02 <! DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 03 <html> 04 <head> 05 <title>'ex4_1.jsp'</title> 06 <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> 07 </head> 08 09 <body > 10 <center> 11 <form action="getParameter.jsp" method="post"> 12 <table> 13 <tr> 14 <td>姓名</td> 15 <td><input type="text" name="name" value=""/></td> 16 </tr> 17 <tr> 18 <td>城市</td> 19 <td><input type="text" name="city" value=""/></td> 20 </tr> 21 <tr> 22 <td><input type="submit" value="提交"/></td> 23 <td><input type="reset" value="重置"/></td> 24 </tr> 25 </table> 26 </form> 27 </center> 28 </body> 29 </html>
上述代码中,代码第11~26行用表单form提交,其中action为getParameter.jsp, methode方法为post,代码第12~25行用输入框装载姓名和城市。getParameter.jsp与【例4.1】中的getParameter.jsp代码一样。
在浏览器中访问ex4_1.jsp并在“姓名”和“城市”输入框中输入值“John”和“Beijing”,单击“提交”按钮后,可以看到显示的结果与例4.1的结果是一样的。
提示
在测试时,读者可以设定method的两个值并分别进行测试,查看地址栏的变化情况。
4.1.3 请求中文乱码的处理
在上述例子中,请求信息中的参数值都是用英文,但在实际开发中,请求信息通常是包含中文的。但在上述的例子中,要是使用中文,例如在表单的姓名输入框中输入中文字符,在提交之后显示的值不是中文而是“? ”或者其他字符,如图4.3所示。
图4.3 显示奇怪的字符
产生这种原因是由于请求信息所使用的字符集与页面使用的字符集的不同,有3种方法可以解决这个问题。
(1)一种方法是在接受请求的页面中规定请求字符编码的代码,例如在例子4.2的getParameter.jsp页面中添加语句“request.setCharacterEncoding(“utf-8”)”即可。
(2)另一种方法是在取得参数值后,通过转码的方式将参数值转为合适的字符集。例如,将前面的例子中获得参数的代码修改为如下形式:
String name= new String(request.getParameter("name").getBytes("ISO-8859-1"), "utf-8") String city= new String(request.getParameter("city").getBytes("ISO-8859-1"), "utf-8");
通过上述两种方法都可以解决中文乱码问题,但是在代码维护方便带来很大麻烦,因为它不仅增加了代码量,而且移植性也差。
(3)第3种方法,通过编写一个Servlet过滤器来解决中文乱码问题,并可以通过配置过滤器解决所有请求处理字符集的问题,请求处理页面就不用关心字符集的处理了。第3种方法可以有效的防止上述的问题且移植性强。如何编写过滤器将在第5章中详细介绍。
4.1.4 获取请求的头部信息
请求的头部信息在实际中也是有其重要作用的,这些信息有时候对服务器的响应特别有用,而且也能查看到服务器中的相关信息。
请求头部信息的相关方法除了4.1.1节提到的getHeaders()外,还有以下方法:
●String getHeader(String name):获取字符串型的表头信息
●int getIntHeader(String name):获取整型的表头信息
【例4.3】获取请求中所有的头名称和对应的值。
getHeaders.jsp页面用于获取请求中的所有头名称和对应的值,其源代码如下:
----------------- getHeaders.jsp ---------------- 01 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> 02 <! DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 03 <html> 04 <head> 05 <title>'getHeaders.jsp'</title> 06 <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> 07 </head> 08 09 <body > 10 <% 11 Enumeration<String>enumeration=request.getHeaderNames(); 12 while(enumeration.hasMoreElements()){ 13 String name = enumeration.nextElement(); 14 String value = request.getHeader(name); 15 if(value==null||"".equals(value)){ 16 value="空字符串"; 17 } 18 %> 19 <p>表头名称:<%=name %>  ;对应的值:<%=value %></p> 20 <%} %> 21 </body> 22 </html>
上述代码中,代码第11~17行获取请求的Header信息,并循环遍历输出。在浏览器中直接输入页面地址,效果如图4.4所示。这些头信息的含义说明如下:
图4.4 网页的请求头信息
●accept:客户端能接收的MIME类型
●accept-language:浏览器的首选语言
●user-agent:客户端程序的相关信息,例如:浏览器版本,操作系统类型等
●host:表示服务器的主机名和端口号
●ua-cpu:CPU类型
●connection:判断客户端是否可以持续性的连接HTTP
●accept-encoding:指明客户端能够处理的编码类型有哪些
●cookie:会话的信息,每个会话都有一个会话ID或者其他信息
以上是通过直接在地址栏中输入页面地址获得到的头文件信息。如果通过post方式跳转的页面,那么头文件信息会稍微多些。例如,在一表单中将method的属性指定为post,然后action指定为例4.3的跳转页面,则显示结果如图4.5所示。
图4.5 post方式获取的请求头信息
从结果对比看,增加了以下几个信息:
●referer:向页面发起请求的地址。
●content-type:指明表单的MIME编码类型,一般值为text/plain, multipart/form-data, application/x-www-form-urlencoded。默认为application/x-www-form-urlencoded,如果表单上传一个文件,则表单中enctype设置为multipart/form-data。
●content-length:提交的请求中数据的长度。表单中提交的数据越多,长度就越大。
●cache-control:网页缓存控制。默认值为no-cache,表明每次访问都从服务器中获取页面。
在一般的开发中,不需要关注请求的头信息,针对不同的需求,在网页中设置相关的属性值就可以。但当我们了解了它们之后,在解决某些问题上将起到关键的作用。
4.1.5 获取主机和客户机信息
获取主机和客户机的信息,一般通过以下几个方法:
●getRemoteAddr():获取客户主机IP
●getRemoteHost():获取客户主机名称
●getLocalAddr():获取本地主机IP
●getLocalHost():获取本地主机名称
●getServerName ():获取服务器主机名称
●getServerPort():获取服务器端口
【例4.4】获取客户机和主机信息
getHostInfo.jsp是获取客户机和本地主机信息的页面,其源代码如下:
----------------- getHostInfo.jsp ---------------- 01 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> 02 <! DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 03 <html> 04 <head> 05 <title>'getHostInfo.jsp'</title> 06 <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> 07 </head> 08 09 <body > 10 <p> 11 本地机器IP:<%=request.getLocalAddr() %><br> 12 本地机器名称:<%=request.getLocalName() %><br> 13 本地机器端口:<%=request.getLocalPort() %><br> 14 </p> 15 <p> 16 客户主机IP:<%=request.getRemoteAddr() %><br> 17 客户主机名称:<%=request.getRemoteHost() %><br> 18 客户主机端口:<%=request.getRemotePort()%><br> 19 </p> 20 <p> 21 服务器IP:<%=request.getServerName() %><br> 22 服务器端口:<%=request.getServerPort() %><br> 23 </p> 24 </body> 25 </html>
上述代码中,第11~13行获取本地机器信息,第16~18行获取客户主机信息,代码第21~23行获取服务器信息。页面效果如图4.6所示。
图4.6 获取主机信息
提示
一般而言,服务器主机名与本地机器IP应该是相同的,端口号也应一样。