Servlet_5th_request对象

本文详细介绍了如何利用HttpServletRequest对象处理客户端发送的HTTP请求,包括获取客户端IP、请求方式、头部信息及表单数据等内容。

HttpServletRequest是一个接口,request对象指的是HttpServletRequest的实现类对象,该对象封装了客户端的请求信息,由服务器将request对象传递给servlet。

一、request对象
1)服务器将客户端请求的信息封装在HttpServletRequest对象中。
①请求行
②请求头
③实体内容

在J2EE的API手册中,找到javax.servlet,在Interface Summary中找到:
ServletRequest,API介绍这个接口说:Defines an object to provide client request information to a servlet.
All Known Subinterfaces:
HttpServletRequest
看一下HttpServletRequest的介绍:
All Known Implementing Classes:
HttpServletRequestWrapper

Extends the ServletRequest interface to provide request information for HTTP servlets.

The servlet container creates an HttpServletRequest object and passes it as an argument to the servlet's service methods (doGet, doPost, etc).

总结:
①ServletRequest及其子接口、子接口实现类:



②HttpServletRequest有什么用?

HttpServletRequest继承了ServletRequest,用于为通过http协议访问的servlet提供请求信息。

③具体是怎样为servlet提供请求信息的?
服务器会创建一个request对象,作为service方法的参数(doGet、doPost等方法)传递给servlet。


二、获取网络信息
1)ServletRequest接口中定义了一些方法用于获取网络信息:

getRemoteAddr()	//获取客户端IP
getRemotePort()	//客户端端口
getLocalAddr()	//服务器端IP
getLocalPort()	//服务器端端口
注意:这里的local是指服务器,调用这些方法时候是在服务器端的servlet中调用的,所以服务器是本地,客户端才是远程。

2)测试获得网络信息

写一个servlet来测试网络信息的获取:

package com.hpe.servlet;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class TestRequestServlet extends HttpServlet {

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) 
			throws ServletException, IOException {
		testGetNetInfo(req);
	}
	/**
	 * 获得网络信息
	 * @param req
	 */
	void testGetNetInfo(HttpServletRequest req) {
		System.out.println("客户的IP:" + req.getRemoteAddr());
		System.out.println("客户的Port:" + req.getRemotePort());
		System.out.println("服务器IP:" + req.getLocalAddr());
	}
}

以下是从两个不同客户端分别对服务器的访问,一个是我同桌的电脑、一个是我自己的电脑(服务器在我电脑上):


培训班老师自己写了一个servlet,service方法中打印service,叫我们访问他的服务器,我们下面就一顿敲http://localhost:8080/ServletDemo1/ServletDemo,我没敲,觉着有问题,因为localhost是本地的端口,我们远程的电脑是无法用localhost来访问他的服务器的,我就问老师的IP地址是多少,他ipconfig查了下是:172.16.0.128

拿到IP地址后我就在浏览器敲:http://172.16.0.128/ServletDemo1/ServletDemo,结果连了半天浏览器说连接已重置。

老师说了句可能是内网没开,然后不了了之了。

课间老师离开了,我想之前应该是网段不同的原因,因为我发现学员的IP地址都是192.168.0.xxx,而他是172开头的,我给他电脑换了根网线,然后查了下他IP变成192.168.0.16了,我把他电脑上eclipse中的Tomcat服务器重启了,然后自己这边敲了http://192.168.0.16/ServletDemo1/ServletDemo,还是没反应,他那边没打印service,我在网上查了下,无意中看到了localhost换成192.xxx.xxx.xxx之类的话,忽然想起只要把localhost替换成IP地址就可以了,我把端口号给漏了,于是再敲http://192.168.0.16:8080/ServletDemo1/ServletDemo,成功让老师电脑上的服务器从控制台打印service。

为了符合大众口味,笔者又将自己电脑上服务器的端口号改回8080了,下面的例子都是通过8080这个端口号来访问的。


3)获取请求行信息

①通过以下方法访问请求行信息:

package com.hpe.servlet;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class TestRequestServlet extends HttpServlet {

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) 
			throws ServletException, IOException {
		//testGetNetInfo(req);
		testGetURL(req, resp);
	}
	/**
	 * 获得网络信息
	 * @param req
	 */
	void testGetNetInfo(HttpServletRequest req) {
		System.out.println("客户的IP:" + req.getRemoteAddr());
		System.out.println("客户的Port:" + req.getRemotePort());
		System.out.println("服务器IP:" + req.getLocalAddr());
	}
	
	/**
	 * 获取请求行信息
	 * @throws IOException
	 */
	void testGetURL(HttpServletRequest req, HttpServletResponse resp) throws IOException {
		PrintWriter out = resp.getWriter();
		out.println("请求方式:" + req.getMethod());
		out.println("协议:" + req.getScheme());
		out.println("web应用目录Contextpath:" + req.getContextPath());
		out.println("URI:" + req.getRequestURI());
		out.println("URL:" + req.getRequestURL());
		out.println("参数:" + req.getQueryString());
	}
}


②从浏览器访问服务器:


③按F12查看元素,并点击重写载入或直接刷新页面:



④可以看到页面中多了一条网页的通信信息:



⑤点击该条通信信息,多出一个框,详细介绍了一些信息:




4)获取头部信息

可以直接通过getHeader()方法直接获取指定名字的头部信息,如果不知道头部信息的名字,也可以通过getHeaderNames()方法获取所有头部信息名字的Enumeration<String>集合:

package com.hpe.servlet;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Enumeration;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class TestRequestServlet extends HttpServlet {

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) 
			throws ServletException, IOException {
		//testGetNetInfo(req);
		//testGetURL(req, resp);
		testGetHeader(req, resp);
	}
	/**
	 * 获得网络信息
	 * @param req
	 */
	void testGetNetInfo(HttpServletRequest req) {
		System.out.println("客户的IP:" + req.getRemoteAddr());
		System.out.println("客户的Port:" + req.getRemotePort());
		System.out.println("服务器IP:" + req.getLocalAddr());
	}
	
	/**
	 * 获取请求行信息
	 * @throws IOException
	 */
	void testGetURL(HttpServletRequest req, HttpServletResponse resp) throws IOException {
		PrintWriter out = resp.getWriter();
		out.println("请求方式:" + req.getMethod());
		out.println("协议:" + req.getScheme());
		out.println("web应用目录Contextpath:" + req.getContextPath());
		out.println("URI:" + req.getRequestURI());
		out.println("URL:" + req.getRequestURL());
		out.println("参数:" + req.getQueryString());
	}
	
	void testGetHeader(HttpServletRequest req, HttpServletResponse resp) {
		String str = req.getHeader("Accept-Language");
		System.out.println("Accept-Language:" + str + "\n");
		
		/* 获取头信息中每条信息的名字 */
		Enumeration<String> e = req.getHeaderNames();
		while(e.hasMoreElements()) {
			String temp = e.nextElement();
			System.out.println(temp+ "---" + req.getHeader(temp));
		}
	}
}

通过不同的浏览器访问到的头部信息是不同的,以下是该servlet被调用后,在服务器控制台中打印的头部信息:
Firefox浏览器:
Accept-Language:zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3

host---localhost:8080
user-agent---Mozilla/5.0 (Windows NT 10.0; WOW64; rv:52.0) Gecko/20100101 Firefox/52.0
accept---text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
accept-language---zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
accept-encoding---gzip, deflate
connection---keep-alive
upgrade-insecure-requests---1

IE浏览器:
Accept-Language:zh-Hans-CN,zh-Hans;q=0.5

accept---text/html, application/xhtml+xml, image/jxr, */*
accept-language---zh-Hans-CN,zh-Hans;q=0.5
user-agent---Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko
accept-encoding---gzip, deflate
host---localhost:8080
connection---Keep-Alive

总结:
①不同浏览器的头部信息是不同的,头部信息的名字顺序、数量不一定相同。


5)获取参数(表单数据)

String getParameter("uname") //得到表单域的值
String getParameterValues("") //多个同名不同值的参数
Enumeration getParameterNames() //用得很少

①写一个index.html,使用get方式来传输这个简单的表单,提交到testReq,这是web.xml中<url-pattern>/testReq</url-pattern>指定的路径,注意在action中不要加"/",直接写testReq。

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<form action="testReq" method="get" name="myForm">
		用户名:<input type="text" name="uname" /><br>
		密码:<input type="password" name="pwd" /><br>
		<input type="submit" value="注册" />	
	</form>
</body>
</html>


②TestRequestServlet类中加上testGetParameter()方法如下:
void testGetParameter(HttpServletRequest req) {
	String u = req.getParameter("uname");
	String p = req.getParameter("pwd");
	System.out.printf("客户端用户的用户名是:%s, 密码是:%s\n", u, p);
}
doGet()方法中调用testGetParameter()方法:

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) 
		throws ServletException, IOException {
	//testGetNetInfo(req);
	//testGetURL(req, resp);
	//testGetHeader(req, resp);
	testGetParameter(req);
}


③浏览器打开index.html,输入表单数据,点击注册:



④Tomcat服务器在控制台打印了一句:


总结:

a、servlet程序可以通过getParameter()方法获取到表单中指定name对应的value值,getParameter()这个方法相当于让客户端与服务器"连接"了起来。

b、也可以通过这个方法来获取单选按钮radio(如:性别(男/女))的值


⑤现在在表单中添加几个复选框,另外,在添加之前,把提交方式改为post,两种方式我们都测试下,现对index.html改动如下:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<form action="testReq" method="post" name="myForm">
		用户名:<input type="text" name="uname" /><br>
		密码:<input type="password" name="pwd" /><br>
		2016年最受欢迎的手机:<br>
		<input type="checkbox" name="smartphone" value="iPhone7" />苹果iPhone7<br>
		<input type="checkbox" name="smartphone" value="s7edge" />三星s7edge<br>
		<input type="checkbox" name="smartphone" value="Mate9" />华为Mate9<br>
		<input type="checkbox" name="smartphone" value="Mi5" />小米5<br>
		<input type="submit" value="注册" />	
	</form>
</body>
</html>

⑥要获取复选框中的值,但是习惯上将复选框的name都取为一致的名字,getParameter()方法就不管用了,需要使用另一个方法getParameterValues()来获取name相同的多个value,对testGetParameter()方法改动如下:

void testGetParameter(HttpServletRequest req) {
	String u = req.getParameter("uname");
	String p = req.getParameter("pwd");
	System.out.printf("客户端用户的用户名是:%s, 密码是:%s\n", u, p);
	
	String[] smartphones = req.getParameterValues("smartphone");
	for (String str : smartphones) {
		System.out.println(str);
	}
}


⑦由于我们这次使用的是post方式,service方法会调用doPost方法,为了观察测试效果,需要重写doPost方法,简便起见,让doPost调用调用doGet()方法即可:

@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) 
	throws ServletException, IOException {
	doGet(req, resp);
}

⑧重新加载index.html,填好表单数据,点击注册:




⑨控制台打印如下信息,成功读取到复选框的内容:




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值