这里写目录标题
1.简介
- Web服务器收到客户端的http请求,会针对每一次请求,分别创建一个用于代表请求的request对象、和代表响应的response对象。
- request和response对象即然代表请求和响应,那我们要获取客户机( 浏览器)提交过来的数据,只需要找request对象就行了。要向浏览器(客户端)输出数据,只需要找response对象就行了。
- HttpServletRequest对象代表客户端的请求,当客户端通过HTTP协议访问http服务器时,HTTP请求头(正文)中的所有信息都封装在这个对象中,开发人员通过这个对象的方法,可以获得客户这些信息。
- 我们之前说,客户端可以发送很多协议的请求,http协议、ajp协议等,http协议的请求报文和ajp协议的请求报文肯定有不同的地方,但是肯定也有相同的地方。
(1)共性的地方是不是可以写在ServletRequest中,个性的部分写在每个协议的报文所对应的request中,其中http所特有的性质就应该出现再HttpServletRequest中。
(2)但是对于一般情况下而言,我们99%场景下使用的都是浏览器去发送请求,浏览器发送的全部都是HTTP请求,所以你几乎可以将HttpServletRequest和ServletRequest做一个等号。
2.request常用方法介绍
2.1获得客户机信息
- getRequestURL:方法返回客户端发出请求时的完整URL
- getRequestURI:方法返回请求行中的资源名部分
- getQueryString: 方法返回请求行中的参数部分
- getRemoteAddr:方法返回发出请求的客户机的IP地址
- getRemoteHost:方法返回发出请求的客户机的完整主机名
- getRemotePort:方法返回客户机所使用的网络端口号
- getLocalAddr:方法返回WEB服务器的IP地址
- getLocalName:方法返回WEB服务器的主机名
- getMethod:得到客户机请求方式
2.2 获得客户机请求头
- getHeader(name)方法
- getHeaders(String name)方法
- getHeaderNames方法
2.3 获得客户机请求参数(客户端提交的数据)
- getParameter(name)方法
- getParameterValues(String name)方法
- getParameterNames方法
RequestServlet1.java
@WebServlet("/request1")
public class RequestServlet1 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取HTTP请求报文的各个部分
String method = request.getMethod();
String requestURI = request.getRequestURI();
String requestURL = request.getRequestURL().toString();
String protocol = request.getProtocol();
System.out.println("Method:"+method);
System.out.println("RequestURI:"+requestURI);
System.out.println("RequestURL:"+requestURL);
System.out.println("Protocol:"+protocol);
System.out.println("\r\n");
// requestURI URL 要比URI长一些 访问协议,主机,端口号
System.out.println(method + " " + requestURI + " " + protocol);
System.out.println(method + " " + requestURL + " " + protocol);
System.out.println("\r\n");
//获得客户机请求头
Enumeration<String> headerNames = request.getHeaderNames();
while (headerNames.hasMoreElements()){
String headerName = headerNames.nextElement();
String headerValue = request.getHeader(headerName);
System.out.println(headerName + ":" + headerValue);
}
System.out.println("\r\n");
//获取请求体的方法
//ServletInputStream inputStream = request.getInputStream();
//黑名单 拦截 filter
String remoteAddr = request.getRemoteAddr();
int remotePort = request.getRemotePort();
String localAddr = request.getLocalAddr();
int localPort = request.getLocalPort();
System.out.println("客户机:" + remoteAddr + "端口号:" + remotePort + "访问了服务器:" + localAddr + "端口号:" + localPort);
}
}
结果输出:
3.Request应用
3.1 各种表单输入项数据的获取
各种表单输入项数据的获取
- text、password、radio、checkbox、
- file、select、textarea、 hidden、
form.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
usename=xxx&password=xxx&gender=xxx&....
<form action="http://localhost:80/app/submit" method="post">
<input type="text" name="username"><br>
<input type="password" name="password"><br>
<input type="radio" name="gender" value="male">男
<input type="radio" name="gender" value="female">女<br>
<input type="checkbox" name="hobby" value="java">java
<input type="checkbox" name="hobby" value="python">python
<input type="checkbox" name="hobby" value="c++">c++<br>
<select name="province">
<option value="wuhan">武汉</option>
<option value="beijing">北京</option>
<option value="shanghai">上海</option>
</select>
<input type="submit">
</form>
</body>
</html>
SubmitServlet.java
@WebServlet("/submit")
public class SubmitServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//如何获取form表单提交的各种类型的请求参数
String username = request.getParameter("username");
String password = request.getParameter("password");
//如果提交的参数是checkbox,使用该方法可能获取的结果不全
String gender = request.getParameter("gender");
//String hobby = request.getParameter("hobby");
String province = request.getParameter("province");
String[] hobbies = request.getParameterValues("hobby");
System.out.println(username);
System.out.println(password);
System.out.println(gender);
//System.out.println(hobby);
System.out.println(province);
//获取checkbox类型的数据
System.out.println(Arrays.toString(hobbies));
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
}
结果:
3.2 请求参数的中文乱码问题
- 浏览器是什么编码就以什么编码传送数据
- 解决:request.setCharacterEncoding(“UTF-8”);//POST有效
3.3 request对象实现请求转发
请求转发指一个web资源收到客户端请求后,通知服务器去调用另外一个web资源进行处理
3.4 getRequestDispatcher
request对象提供了一个getRequestDispatcher方法,该方法返回一个RequestDispatcher对象,调用这个对象的forward方法可以实现请求转发
3.5 作为域对象
request对象同时也是一个域对象,开发人员通过request对象在实现转发时,把数据通过request对象带给其它web资源处理:
setAttribute方法
getAttribute方法
removeAttribute方法
getAttributeNames方法
4.转发和包含
4.1 转发和包含
一个Servlet对象无法获得另一个Servelt对象的引用;如果需要多个Servet组件共同协作(数据传递),只能使用Servelt规范为我们提供的两种方式:
- 请求转发:Servlet(源组件)先对客户请求做一些预处理操作,然后把请求转发给**其他web组件(目标组件)**来完成包括生成响应结果在内的后续操作。
- 包含:Servelt(源组件)把其他web组件(目标组件)生成的响应结果包含到自身的响应结果中。
转发和包含的共同点:
- 源组件和目标组件处理的都是同一个客户请求,源组件和目标组件共享同一个ServeltRequest和ServletResponse对象
- 目标组件都可以为Servlet、JSP或HTML文档
- 都依赖 javax.servlet.RequestDispatcher接口
4.2 RequestDispather(请求分发器)
4.2.1 有两个方法
- forward():把请求转发给目标组件
public void forward(ServletRequest request,ServletResponse response)
throws ServletException,java.io.IOException
- include():包含目标组件的响应结果
public void include(ServletRequest request,ServletResponse response)
throws ServletException,java.io.IOException
4.2.2 得到RequestDispatcher对象
- 1、ServletContext对象的getRequestDispather(String path1)
Path1 必须即以”/”开头,若用相对路径会抛出异常IllegalArgumentException - 2、ServletRequest对象的getRequestDispatcher(String path2)
path2可以用绝对路径也可以用相对路径
4.3 转发
4.3.1 dispatcher.forward(request,response)的处理流程:
- 清空用于存放响应正文数据的缓冲区
- 如果目标组件为Servlet或JSP,tomcat就调用它们,把它们产生的响应结果发送到客户端;如果目标组件为文件系统中的静态HTML文档,tomcat就读取文档中的数据并把它发送给客户端。
4.3.2 特点:
- 1、由于forward()方法先清空用于存放响应正文数据的缓冲区,因此源组件生成的响应结果(无论转发前后)不会被发送到客户端,只有目标组件生成的响应结果才会被送到客户端。
- 2、如果源组件在进行请求转发之前,已经提交了响应结果(如调用了response的flush或close方法),那么forward()方法会抛出IllegalStateException。为了避免该异常,不应该在源组件中提交响应结果。
4.4 请求转发的运行流程
第一步:
第二步:
第三步:
第四步:
第五步:
第六步:
第七步:
第八步:
第九步:
第十步:
第十一步:
第十二步:
第十三步:
4.5 包含
include()方法的处理流程:
- 如果目标组件为Servlet或JSP,就执行它们,并把它们产生的响应正文添加到源组件的响应结果中;如果目标组件为HTML文档,就直接把文档的内容添加到源组件的响应结果中。
- 特点:
源组件与被包含的目标组件的输出数据都会被添加到响应结果中
在目标组件中对响应状态代码或者响应头所做的修改都会被忽略
4.6 请求范围
- web应用范围内的共享数据作为ServeltContext对象的属性而存在(setAttribute),只要共享ServletContext对象也就共享了其数据
- 请求范围内的共享数据作为ServletRequest对象的属性而存在(setAttribute),只要共享ServletRequest对象也就共享了其数据