一. HttpServletRequest
1. 什么是HttpServletRequest对象?
HttpServletRequest对象代表客户端的请求,当客户端通过HTTP协议访问服务器时,HTTP请求头中的所有信息
都封装在这个对象中,开发人员通过这个对象的方法,可以获得客户这些信息。也就是说所有的请求信息都封装
在这里,由服务器负责封装。
2. HttpServletRequest对象的作用是用于获取请求数据。
3. Request常用方法
(1) 获取请求行信息:
① request.getMethod(); 获取请求的方式
② request.getRequestURI(); / request.getRequestURL(); 获取请求的资源
③ request.getProtocol(); 获取请求的http协议版本
public class ExampleDemo1 extends HttpServlet {
/**
* (1)tomcat服务器接收到浏览器发送的请求数据,然后封装到HttpServletRequest对象
* (2)tomcat服务器调用doGet方法,然后把request对象传入到Servlet中。
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
/**
* (3)从request对象取出请求数据。
*/
t1(request);
}
private void t1(HttpServletRequest request) {
System.out.println("请求的方式:" + request.getMethod());// 请求方式
System.out.println("URI:" + request.getRequestURI());// 请求资源
System.out.println("URL:" + request.getRequestURL());// 也是获取请求资源,只是两种不同的表现形式
System.out.println("http协议版本:" + request.getProtocol());// http协议
}
}
运行结果如下图所示:
(2) 获取请求头信息:
① request.getHeader("名称"); 根据请求头获取请求值
② request.getHeaderNames(); 获取所有的请求头名称
public class ExampleDemo2 extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
t2(request);
}
private void t2(HttpServletRequest request) {
/*
* 获取请求头 request.getHeader("头名称");根据头名称拿到请求头的内容。
*/
String host = request.getHeader("Host");
System.out.println(host);
// 遍历所有请求头
Enumeration<String> enums = request.getHeaderNames();// 得到所有的请求头名称列表
while (enums.hasMoreElements()) { // 判断是否有下一个元素
String headerName = enums.nextElement();// 取出下一个元素,结果仍然是一个头名称,我们可以用头名称拿到它对应的值。
String headerValue = request.getHeader(headerName);
System.out.println(headerName + ":" + headerValue);
}
}
}
运行结果如下图所示:
(3) 获得实体内容
request.getInputStream(); 获取实体内容数据
public class ExampleDemo3 extends HttpServlet {
// 为了接受post方式提交的请求。如果是post方式提交的请求一定要用doPost方法
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
/*
* 获取请求的实体内容
*/
InputStream in = request.getInputStream(); // 得到实体内容
byte[] buf = new byte[1024];
int len = 0;
while ((len = in.read(buf)) != -1) {
String str = new String(buf, 0, len);
System.out.println(str);
}
}
}
运行结果如下图所示:
4. 表单传递的请求参数如何获取?
(1) 请求参数存在的位置:
① 如果是GET请求方式,参数放在URI的后面。
② 如果是POST请求方式,参数放在实体内容中。
(2) 获取参数的方式:
① 获取GET请求的参数的方式:request.getQueryString();
② 获取POST请求的参数的方式:request.getInputStream();
(3) 存在的问题:以上两种方式不通用,而且获取到的参数还需要进一步的解析,所以可以采用统一方便的获取参
数的方式。
(4) 统一获取参数的方式:
① request.getParameter("参数名"); 根据参数名获取参数值(注意,只能获取一个参数的参数值)
② request.getParameterValue("参数名“); 根据参数名获取参数值(可以获取多个参数的参数值)
③ request.getParameterNames(); 获取所有参数名称列表
/*
* 获取GET方式和POST方式提交的参数
*/
public class RequestDemo2 extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
/*
* 统一方便的获取请求参数的方法
*/
// getparameter根据参数名得到参数值(但是只能获取一个值的参数,不能获取多选框的值)
String name = request.getParameter("name");
String password = request.getParameter("password");
System.out.println("用户名:" + name + " 密码:" + password);
System.out.println("=================================");
// 返回的是一个迭代器,可以遍历所有的参数
Enumeration<String> enums = request.getParameterNames();
while (enums.hasMoreElements()) {
String paraName = enums.nextElement();
/*
* getParameterValues(name):根据参数名获取参数值(可以获取同名参数名的多个参数值)
*/
// 如果参数名是hobit,则调用getParameterValues
if ("hobit".equals(paraName)) {
System.out.println(paraName + ":");
String[] hobits = request.getParameterValues("hobit");
for (String h : hobits) {
System.out.println(h + ",");
}
} else {
String paraValue = request.getParameter(paraName);
System.out.println(paraName + ":" + paraValue);
}
}
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 调用doGet方式
this.doGet(request, response);
}
}
运行结果如下图所示:
5. request常见应用:
(1) 获取浏览器类型;
(2) 防盗链;
(3) 各种表单输入项数据的获取,比如:text、password、radio、checkbox、file、select、textarea、
hidden、imge、button;
(4) 请求参数的中文乱码问题。
二. HttpServletResponse
1. 简介
(1) Web服务器收到客户端的http请求,会针对每一次请求,分别创建一个用于代表请求的request对象,和代表
响应的response对象。
(2) request对象和response对象既然代表请求和响应,那我们要获取客户端提交过来的数据,只需要找request
对象就行了;如果要向客户端输出数据,只需要找response对象即可。
2. HttpServletResponse对象
HttpServletResponse对象代表了服务器的响应。这个对象中封装了向客户端发送数据、发送响应头、发送响应
状态码的方法,该对象的作用是用来设置响应数据。
3. HttpServletResponse对象修改响应信息
(1) 修改响应行信息:
response.setStatus(); 设置状态码
(2) 修改响应头信息:
response.setHeader("name","value"); 设置响应头
(3) 修改实体内容:
response.getWriter().writer(); 发送字符实体内容
response.getOutputStream().writer(); 发送字节实体内容
4.实例:
/*
* 设置响应的信息
*/
public class ResponseDemo1 extends HttpServlet {
/*
* (1)tomcat服务器把请求信息封装到HttpServletRequest对象中,并且把响应信息封装到HttpServletresponse中去
* (2)tomcat服务器先调用service方法,在service方法中调用doGet方法。传入request和response对象
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
/*
* (3)通过response对象改变响应信息。
*/
// 3.1响应行
// response.setStatus(404);//修改状态码,会影响浏览器的行为
response.sendError(404);// 发送404的状态码+404的错误页面。但是发404是没有意义的。
// 3.2改变响应头
response.setHeader("server", "JBoss");
// 3.3改变实体内容:实体内容就是我们页面看的到的部分(浏览器直接能够看到的内容就是实体内容)。
// 两种改变方式
response.getWriter().write("01.hello world");// writer里面是字符串,所以发送的内容也是字符内容。
response.getOutputStream().write("02.hello world".getBytes());// 发送的是字节内容。
}
/*
* (4)tomcat服务器把response对象的内容转换成响应格式内容,再发送给浏览器解析
*/
}
5. Response细节:
(1) getOutputStream和getWriter方法分别用于得到输出二进制数据、输出文本数据的ServletOuputStream、
Printwriter对象。
(2) getOutputStream和getWriter这两个方法互相排斥,调用了其中的任何一个方法后,就不能再调用另一方
法。
(3) Servlet程序向ServletOutputStream或PrintWriter对象中写入的数据将被Servlet引擎从response里面获
取,Servlet引擎将这些数据当作响应消息的正文,然后再与响应状态行和各响应头组合后输出到客户端。
(4) Serlvet的service方法结束后,Servlet引擎将检查getWriter或getOutputStream方法返回的输出流对象是否
已经调用过close方法,如果没有,Servlet引擎将调用close方法关闭该输出流对象。
三. response常见应用
1. 案例一 请求重定向(Location)
(1) 请求重定向是指:一个Web资源收到客户端请求后,通知客户端去访问另外一个Web资源,这称之为请求重
定向。
(2) 应用场景:用户注册。
(3) 实现方式:response.sendRedirect();
(4) 实现原理:
发送一个302状态码和location的响应头即可实现重定向。
(5) 原理图及分析:
① 浏览器发送一个请求到服务器请求一个资源,tomcat服务器中有一个ResponseDemo2,当浏览器发送请
求,它就会产生一个响应,这个Servlet就会发送状态码和响应头给浏览器;
② 浏览器是认识302状态码的,当浏览器得到302状态码之后,会再次自动向服务器发出一个请求,请求的地址
就是location的value值的地址,所以location的地址值是:/zw_http/adv.html,当浏览器得到302状态码之
后,会自动向浏览器发送一个请求,就请求这个资源,服务器中有这个资源就会做出响应。所以就看到请求重定
向的效果;
③ 请求重定向浏览器一共向服务器发出2次请求;
④ 它的地址栏是由第二次请求决定的,用第二次的地址决定浏览器应该显示什么。也就相当于浏览器在地址栏中
输入adv.html的地址。
(6) 实例:
public class ResponseDemo2 extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
/*
* response.setStatus(302);//发送一个302状态码 response.setHeader("location",
* "/zw_http/adv.html");//location的响应头采用的是URI的写法。
*/
response.sendRedirect("/zw_http/adv.html");// 简写
}
}
2. 案例二 使用Refresh实现定时跳转(定时刷新)
(1) 实现原理:
浏览器认识Refresh响应头,得到Refresh响应头之后重新再请求当前资源。比如:注册完一个网站用户后,3秒
之后跳转到首页。
(2) 实例:
public class ResponseDemo3 extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// response.setHeader("refresh", "1");//每隔1秒刷新此页面
response.setHeader("refresh", "3;url=/zw_http/adv.html");// 隔3秒之后跳转到adv.html
}
}
3. 案例三 使用content-Type实现向浏览器输出图片
/*
* 案例三:content-Type的作用:
* 服务器发送给浏览器的数据类型及内容编码
*/
public class ResponseDemo4 extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
/*
* 1.服务器发送给浏览器的数据类型
*/
/*
* //response.setHeader("content-type","text/html");
* //response.setContentType("text/html");//和上面代码等价,推荐使用此方法。
* response.getWriter().write(
* "<html><head><title>this is title</title></head><body>this is body</body></html>"
* );
*/
response.setContentType("image/jpg");
/*
* 发送图片
*/
FileInputStream in = new FileInputStream(new File("e:/mm.jpg"));// 先把图片读进来
// 边读边写
byte[] buf = new byte[1024];
int len = 0;
while ((len = in.read(buf)) != -1) {
response.getOutputStream().write(buf, 0, len);
}
}
}