HttpServletRequest类 请求类的理解
HttpServletRequest类的作用
每次有请求发送到Tomcat服务器,Tomcat会将请求中的HTTP信息解析并封装到一个Request对象中,然后传递到service方法(doGet和doPost方法)中给我们使用,我们可以通过HttpServletRequeset获得所有请求的信息
HttpServletRequest类常用的方法
- getMethod() 获取请求的方式
- getRequestURI() 获取请求的统一资源标识符
- getRequestURL() 获取请求的统一资源定位符
- getRemoteHost() 获取客户端的地址
- getHeader() 获取请求头信息
public class RequestServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//HttpServletRequest 常用的方法:
//getRequestURI() 获取统一资源标识符
System.out.println("统一资源标识: "+req.getRequestURI());
//getRequestURL() 获取统一资源定位符
System.out.println("统一资源路径: "+req.getRequestURL());
//getRemoteHost() 获取客户端的ip
System.out.println("客户端ip: "+req.getRemoteHost());
//getHeader() 获取请求头
System.out.println("User-Agent: "+req.getHeader("User-Agent"));
//getMethod() 获取请求的方式
System.out.println("请求方式: "+req.getMethod());
}
}
测试结果
- getParameter() 获取请求的参数 一个值使用
- getParameterValues() 获取请求的参数 多个值使用
- getParameterMap() 获取请求的集合
先创建表单HTML代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>
Title</title>
</head>
<body>
<form action="http://localhost:8080/07_Servlet/parameterServlet" method="post">
用户名:<input type="text" name="username"><br/>
密码:<input type="password" name="password"><br/>
<input type="checkbox" name="lang" value="cpp">C++
<input type="checkbox" name="lang" value="Java">Java
<input type="checkbox" name="lang" value=".net">.Net
<input type="checkbox" name="lang" value="csharp">C#
<input type="checkbox" name="lang" value="JS">JavaScript<br/>
<input type="submit">
</form>
</body>
</html>
这是表单的网页,当我们点击提交时会将表单内的数据提交到
http://localhost:8080/07_Servlet/parameterServlet
程序,我们通过Java代码获取请求的参数
Java代码获取请求的参数
public class ParameterServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//getParameter() 获取请求的参数, 只能请求一个值
System.out.println("用户名: "+request.getParameter("username"));
System.out.println("密码: "+request.getParameter("password"));
System.out.println("语言: "+request.getParameter("lang"));
//getParameterValues() 获取请求的参数, 多个值使用
String[] langs = request.getParameterValues("lang");
System.out.println(Arrays.asList(langs));
//getParameterMap() 获取请求的参数的集合
Map<String, String[]> parameterMap = request.getParameterMap();
Set<Map.Entry<String, String[]>> entries = parameterMap.entrySet();
Iterator<Map.Entry<String, String[]>> iterator = entries.iterator();
while (iterator.hasNext()) {
Map.Entry<String, String[]> next = iterator.next();
System.out.println("key: "+ next.getKey() + ", value: " +Arrays.asList(next.getValue()));
}
}
}
测试结果
当我们在输入框中输入中文是会出现乱码
我们需要在获取请求的代码前加上设置编码集的request.setCharacterEncoding("UTF-8");
代码重新进行部署即可, 一般来说有POST请求时会出现乱码,而GET不会
public class ParameterServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//使用POST请求时,出些乱码,需要在这之前设置字符编码集
request.setCharacterEncoding("UTF-8");
//getParameter() 获取请求的参数, 只能请求一个值
System.out.println("用户名: "+request.getParameter("username"));
System.out.println("密码: "+request.getParameter("password"));
System.out.println("语言: "+request.getParameter("lang"));
//getParameterValues() 获取请求的参数, 多个值使用
String[] langs = request.getParameterValues("lang");
System.out.println("语言: "+Arrays.asList(langs)+"\n");
System.out.println("以下是通过集合获取参数");
//getParameterMap() 获取请求的参数的集合
Map<String, String[]> parameterMap = request.getParameterMap();
Set<Map.Entry<String, String[]>> entries = parameterMap.entrySet();
Iterator<Map.Entry<String, String[]>> iterator = entries.iterator();
while (iterator.hasNext()) {
Map.Entry<String, String[]> next = iterator.next();
System.out.println("key: "+ next.getKey() + ", value: " +Arrays.asList(next.getValue()));
}
}
}
测试结果
- setAttribute() 设置域数据
- getAttribute() 获取域数据
public class AttributeServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//HttpServletRequest的域数据方法
//setAttribute() 设置域数据
request.setAttribute("computer","ROG");
request.setAttribute("company","country");
//getAttribute() 获取域数据
System.out.println(request.getAttribute("company"));
System.out.println(request.getAttribute("computer"));
}
}
当我们访问Servlet程序时request会创建域数据,域数据是以键值对形式出现,然后我们将它的值数据到控制台
测试结果
什么是请求转发?
请求转发, 服务器在一个资源路径中获取到的请求转发到另一个资源路径,而两个路径会共同处理获取到的请求就叫请求转发
请求转发的特点:
1、浏览器转发后的路径不变
2、他们是一次性转发
3、两者共享Request的域数据
4、能够转发到WEB-INF目录下
5、只能访问工程以内的资源
getRequestDispatcher() 获取请求转发的对象
转发请求的程序
public class DispatcherServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//设置当前程序的域数据,当转发到另能调用到当前程序的域数据,说明请求转发成功
request.setAttribute("username","zhf");
/*
请求转发必须以以'/'打头, 表示服务器解析/后的路径为: http://ip:port/工程路径/ ,映射到IDEA代码的webapp目录下
dispatcherServlet2 是被转发的资源路径 表示在http://ip:port/工程路径/dispatcherServlet2
*/
RequestDispatcher dispatcher = request.getRequestDispatcher("/dispatcherServlet2");
System.out.println("程序1获取的username: "+request.getAttribute("username"));
//走向dispatcherServlet2, 并将当前资源的请求与响应转发给dispatcherServlet2路径
dispatcher.forward(request,response);
}
}
被转发请求的程序
public class DispatcherServlet2 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取请求的参数
String pwd = request.getParameter("pwd");
System.out.println("程序2中的pwd参数: "+pwd);
//验证是否转发过来
System.out.println("程序2获取的username: "+request.getAttribute("username"));
//处理自己的业务
System.out.println("程序2 处理自己的业务 ");
}
}
测试转发结果
Base标签的作用
创建一个的转发的dispatcher.html页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>dispatcher</title>
</head>
<body>
dispatcher页面
<a href="http://localhost:8080/07_Servlet/dispatcherServlet">请求转发到c.html</a>
</body>
</html>
创建一个转发的扩展了HttpServlet
public class DispatcherServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
RequestDispatcher dispatcher = request.getRequestDispatcher("/a/b/c.html");
dispatcher.forward(request,response);
}
}
创建一个接收的c.html页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>c</title>
</head>
<body>
这里是c.html
<a href="../../dispatcher.html">跳转回dispatcher.html</a>
</body>
</html>
当我们点击a标签的时候,则页面会跳转到dispatcherServlet的程序中,而程序会转发到c.html的页面中
而程序转发红藕的页面,由于请求转发的特性,转发后的资源路径没有变为:http://localhost:8080/07_Servlet/a/b/c.html
而是原来的链接: http://localhost:8080/07_Servlet/dispatcherServlet
而当点击a标签跳转回dispatcher.html页面时,出现404
这个问题是由于当dispatcher.html的a标签在点击前的时候,原来的链接是: http://localhost:8080/07_Servlet/dispatcher.html
点击后的链接是: http://localhost:8080/07_Servlet/dispatcherServlet
而跳转回dispatcher.html的链接是通过相对路径的方式进行跳转
../../
表示后退两级目录
当 http://localhost:8080/07_Servlet/dispatcherServlet 退两级目录后,变成_ http://localhost:8080/_ 所以就找不到c.html
base的作用是在跳转的目录下使用绝对路径的方式进行跳转
在head标签内使用base标签,表示,忽略当前的浏览器路径,使用base的路径
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>c</title>
<base href="http://localhost:8080/07_Servlet/a/b/">
</head>
<body>
这里是c.html
<a href="../../dispatcher.html">跳转回dispatcher.html</a>
</body>
</html>
在Web中的相对路径与绝对路径
JavaWeb中, 路径分为相对路径和绝对路径
相对路径:
. 当前目录
.. 上一级目录
资源名 表示当前目录/路径名
绝对路径:
http://ip:port/工程路径/资源名
在实际的开发中都使用绝对路径,一般不简单使用相对路径
- 绝对路径
- 相对路径+base标签
Web中 /
斜杠的不同意义
在Web中,斜杠是一种绝对路径
/
被浏览器解析, 表示: http://ip:port/
/
被服务器解析, 表示: http://ip:porrt/工程路径/