HttpServletRequest
The servlet container creates an HttpServletRequest object and passes it as an argument to the servlet’s service methods (doGet, doPost, etc).
servlet容器创建一个HttpServletRequest对象并将它作为参数的servlet的service方法(doGet,doPost,等)。
HttpServletRequest的对象
HttpServletRequest是一个接口,将请求和它所有的数据封装成一个对象,这个对象就是HttpServletRequest的实现类。
HTTP请求的组成:
1) 请求行:请求的方式 URI 协议和版本 GET /day37 HTTP/1.1
2) 请求头:由多个键值对组成
3) 请求体:GET方法没有,POST数据在请求体中发送
获取请求行相关的方法
HttpServletRequest对象的方法
- String getMethod() 得到请求的方式:GET或POST
- String getRequestURI()
得到请求的URI,统一资源标识符
- StringBuffer getRequestURL()
得到请求的URL,统一资源定位符
- String getProtocol()
得到协议和版本
- String getQueryString()
得到查询字符串,问号后面的字符串
- String getContextPath()
得到上下文的访问路径(当前项目的访问名字) - String getRemoteAddr()
得到客户端访问的IP地址,如果使用localhost,返回的是本机的ipv6地址 - String getServerName()
得到服务器的名字,如果没有名字则得到的是服务器的IP地址 - int getServerPort()
得到服务器的端口号 - String getSchema()
得到协议 - String getServletPath()
得到Servlet的访问地址
示范
代码:
out.print("请求方式:" + request.getMethod() + "<br/>");
out.print("URI:" + request.getRequestURI() + "<br/>");
out.print("URL:" + request.getRequestURL() + "<br/>");
out.print("协议和版本:" + request.getProtocol() + "<br/>");
out.print("得到查询字符串:" + request.getQueryString() + "<br/>");
out.print("上下文路径:" + request.getContextPath() + "<br/>");
out.print("客户端的IP地址:" + request.getRemoteAddr() + "<br/>");
out.print("得到服务器的名字:" + request.getServerName() + "<br/>");
out.print("得到服务器的端口号:" + request.getServerPort() + "<br/>");
out.print("得到协议:" + request.getScheme() + "<br/>");
out.print("得到Servlet的访问地址:" + request.getServletPath() + "<br/>");
获取请求头相关的方法
请求头
方法:
- String getHeader(String headName)
- 通过请求头的名字得到请求值
- Enumeration getHeaderNames()
- 得到所有请求的头的名字,返回Enumeration枚举类,他的方法:hasMoreElements()、nextElement()
示范:
代码:
//得到其中一个请求头
out.print("得一个请求头host: " + request.getHeader("host") + "<br/>");
out.print("得一个请求头accept-encoding: " + request.getHeader("accept-encoding"));
out.print("<hr />");
//得到所有的请求头
Enumeration<String> names = request.getHeaderNames();
while (names.hasMoreElements()) {
String name = names.nextElement();
out.print("请求头名" + name + "-- " + "值:" + request.getHeader(name) + "<br/>");
}
获取请求参数的方法
String getParameter(String name)
- 指定参数的名字得到参数值
- 1) 通过表单
- 2) 通过查询字符串
- 指定参数的名字得到参数值
String[] getParameterValues(String name)
指定一组同名的参数,得到一组值,返回字符串数组
一般用于多选下拉列表和复选框
Enumeration getParameterNames()
- 得到所有参数的名字,返回枚举类
Map
代码
getParameterMap方法(获得所有的键值map的方法):
//得到所有的名字和值,封装成Map
Map<String, String[]> map = request.getParameterMap();
//得到所有键的集合
Set<String> keySet = map.keySet();
for (String key : keySet) {
String[] values = map.get(key);
out.print("键:" +key + ",值:" + Arrays.toString(values) + "<br/>");
}
输出:
键:name,值:[asd]
键:gender,值:[男]
键:city,值:[广州]
键:hobby,值:[上网, 上学]
getParameterNames方法:(获得所有的参数的名字然后遍历获得对应的值)
Enumeration<String> names = request.getParameterNames();
while (names.hasMoreElements()) {
//得到名字
String name = names.nextElement();
//得到值
String value = request.getParameter(name);
out.print("名字: " + name + ", 值:" + value + "<br/>" );
}
名字: name, 值:asd
名字: gender, 值:男
名字: city, 值:广州
名字: hobby, 值:上网
表单:
<body>
<h2>用户注册</h2>
<form action="demo5" method="post">
用户名: <input type="text" name="name"><br/>
性别: <input type="radio" name="gender" value="男" checked="checked"/>男
<input type="radio" name="gender" value="女"/>女 <br/>
城市:
<select name="city">
<option value="广州">广州</option>
<option value="深圳">深圳</option>
<option value="珠海">珠海</option>
</select>
<br/>
爱好:
<input type="checkbox" name="hobby" value="上网"/>上网
<input type="checkbox" name="hobby" value="上学"/>上学
<input type="checkbox" name="hobby" value="上车"/>上车
<input type="checkbox" name="hobby" value="上吊"/>上吊
<br/>
<input type="submit" value="注册"/>
</form>
</body>
案例
应用案例:得到浏览器的类型,判断是:Edge、Chrome、Safari、Firefox或IE浏览器
原理:得到user-agent请求头,判断请求值是否包含指定的字符串
/**
* 得到浏览器的类型
* @author NewBoy
*
*/
public class Demo3UserAgentServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
//得到请求头
String browser = request.getHeader("user-agent");
out.print(browser + "<hr/>");
out.print("您的浏览器是:");
//包含指定的字符串
if (browser.contains("Edge")) {
out.print("Edge");
}
else if (browser.contains("Chrome")) {
out.print("Chrome");
}
else if(browser.contains("Safari")) {
out.print("Safari");
}
else if (browser.contains("Firefox")) {
out.print("Firefox");
}
else {
out.print("IE或其它");
}
out.close();
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
应用案例:防盗链
- 需求:当我们去访问某个页面的时候,首先会跳转到一个广告页面,看了广告以后才可以访问资源。
- 原理:通过得到请求头Referer, 获取当前页面的从哪里来的。
1) 如果是从广告页面过来的,则可以继续访问。
2) 如果为null,表示没有上一个页面。
3) 如果没有访问广告,跳转到广告页面。 - 页面:adv.html 是广告页面
- Demo4ResourceServlet :判断当前页面从哪里跳转过来的,如果从广告页面过来,则正常访问,否则跳转到广告页面!
- 其它的页面:other.html盗链页面
/**
* 精彩内容
* @author NewBoy
*
*/
public class Demo4ResourceServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
//得到上一个访问的页面
String url = request.getHeader("referer");
//得到null,表示直接访问的
System.out.println(url);
//1. 直接访问url为null 2. 不是直接访问,但上一个页面不包含广告页面
if (url == null || !url.contains("/day37-request/adv.html")) {
//跳转到广告页面
response.sendRedirect(request.getContextPath() + "/adv.html");
}
//来至于广告页面
else {
out.print("<h1>这就是精彩内容</h1>");
out.print("<img src='img/girl.jpg'/>");
}
out.close();
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
adv.html
<h2>我的广告</h2>
<img src="img/adv.jpg" width="300"/><hr/>
<a href="demo4">访问精彩内容</a>
盗链页面
<body>
<h2>我是小偷</h2>
<a href="demo4">访问精彩内容</a>
</body>