request请求对象
概述
request对象代表浏览器端的请求,当浏览器端通过HTTP协议访问服务器时,HTTP请求中的所有
信息(行 头 体)都封装在这个对象中,开发人员通过这个对象的api,可以获得客户通过浏览器传递过来的数据
作用
作用:封装获取浏览器的请求数据(请求行 请求头 请求体)
1 在servlet端通过request获取请求行数据
2 在servlet端通过request获取请求头数据
3 在servlet端通过request获取请求体数据
4 作为容器在多个servlet之间进行数据传递
---servletContext request
1) 获取请求行数据的api概述(请求方式 访问的资源 协议版本)
1.String getMethod() 获取请求方式
2.(了解)String getRequestURI() 获取请求行中的资源名部分
3.StringBuffer getRequestURL() 获取客户端请求完整URL
4.(重要)getContextPath() 获取当前的项目名路径
代码展示
package cn.itheima.web;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet(name = "ServletDemo1",urlPatterns = "/sd1")
public class ServletDemo1 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 获取请求行代码的数据
//1 获取提交方式
System.out.println("提交方式:"+request.getMethod());
//2 获取请求的资源名
System.out.println("请求的资源名:"+request.getRequestURI());
//3 获取资源名的完整路径
System.out.println("资源名的完整路径:"+request.getRequestURL());
//获取当前项目的虚拟名路径 /day06
System.out.println(request.getContextPath());
//response.sendRedirect(request.getContextPath()+"/demo2.html");
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request,response);
}
}
2) 获取请求头数据的api概述 (键值对key/value的数据)
1.(重要)getHeader(String key) 根据请求头的key获取value
例如:Referer可以获取到来源地址(没有来源为null:直接访问) --防盗链
例如:User-Agent可以获取用户的浏览器版本信息 ---下载必备
2.(了解)Enumeration getHeaderNames() 返回此请求包含的所有头名称
代码展示
package cn.itheima.web;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Enumeration;
@WebServlet(name = "ServletDemo2",urlPatterns = "/sd2")
public class ServletDemo2 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 获取请求头代码的数据
String value1 = request.getHeader("host");
String value2 = request.getHeader("connection");
System.out.println(value1);
System.out.println(value2);
// 后期我们要用的一些头数据:掌握
//1 获取用户的浏览器版本 (下载)
String value3 = request.getHeader("user-agent");
if(value3.contains("Firefox")){
System.out.println("用户使用的火狐浏览器--base64");
}else{
System.out.println("别的浏览器---utf8");
}
System.out.println(value3);
//2 获取用户访问资源的上一个页面来源(防资源被盗链) 如果没有资源 返回值是null
String value4 = request.getHeader("referer");
System.out.println("我是由"+value4+"资源过来的");
//3 获取请求的所有头
Enumeration<String> names = request.getHeaderNames();
while (names.hasMoreElements()){
System.out.println(names.nextElement());
}
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request,response);
}
}
3) (很重要)获取请求体数据api概述(所有浏览器提交的表单数据)
1.String getParameter("name的属性名") 获取单一name对应的value值
2.String[] getParameterValues("name的属性值") 获取name对应的多个value值
3.Map<String,String[]> getParameterMap() 获取页面所有的value值
注意:key:对应的是表单中name属性名 value对应的的是表单的name属性的value值
代码展示
package cn.itheima.web;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Arrays;
import java.util.Map;
@WebServlet(name = "ServletDemo3",urlPatterns = "/sd3")
public class ServletDemo3 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 获取请求体代码的数据
// 收集页面数据(单一值)
String username = request.getParameter("username"); //收集单一的数据
String password = request.getParameter("password");
System.out.println("用户填写的用户名是:"+username+".密码是:"+password);
String hobby = request.getParameter("hobby");
System.out.println("用户的爱好是:"+hobby);
System.out.println("-----------------------------------------------");
// 收集页面数据(多值)
String[] hobbys = request.getParameterValues("hobby");
System.out.println(Arrays.toString(hobbys));
// 简便方式获取页面数据
//key:页面的name属性名
//value:这个属性名对应的value值(单一/多值)
Map<String, String[]> map = request.getParameterMap();
for(String key:map.keySet()){
System.out.println("map的key是:"+key);
System.out.println("页面用户填写的数据一口气获取了:"+Arrays.toString(map.get(key)));
}
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request,response);
}
}
在提交表单的过程中,如果有中文 get提交没问题 但是post提交会乱码
解决方案:request.setCharacterEncoding("utf-8");
注意:需要放在获取数据之前
4) request请求对象的其它作用
作为容器数据存取删的方法:(request也被称为域对象)
1.void setAttribute(String name, Object o) 存储数据
2.Object getAttribute(String name) 获取数据
3.void removeAttribute(String name) 移除数据
注意:request这3个方法也可以做多个servlet之间的数据传递?
问题:当我们浏览器访问2个不同的servlet的时候,发现并不能得到我们想要的获取数据效果
原因:请求一次就创建一个request对象,响应就销毁,要想用同一个request对象,得学习请求转发
解决:使用请求转发
请求转发:可以在一个servlet中访问另外一个servlet(保证多个servlet之间使用的是同一个request对象)
request.getRequestDispatcher("/servlet的地址").forward(request,response);
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pWMTbRmw-1642247337551)(img\04-request域对象的概述.png)]
response对象
概述
是服务器用来给浏览器写内容的一个对象
服务器给浏览器响应任何数据都得通过响应行 响应头 响应体
操作响应行(知道响应行中状态码的含义)
格式:协议/版本 状态码 例如:HTTP/1.1 200
看懂状态码的意义:
分类 分类描述
1** 信息,服务器收到请求,需要请求者继续执行操作
2** 成功,操作被成功接收并处理
3** 重定向,需要进一步的操作以完成请求
4** 客户端错误,请求包含语法错误或无法完成请求
5** 服务器错误,服务器在处理请求的过程中发生了错误
常见状态码
200 请求响应已成功
302 重定向
304 去找缓存数据
403 服务器拒绝执行 (文件或文件夹加了权限)
404 请求的资源没找到
405 请求的方法不存在
500 服务器错误 (代码写的有问题)
api方法:response的
setStatus(int sc) 设置响应的状态代码(一般用来设置 1xx 2xx 3xx)
sendError(int sc) 设置响应的状态代码(一般用来设置 4xx 5xx)
ps:我们一般是不操作状态码的 但需要知道一些状态码的含义
操作响应头
格式:key:value
api方法:
setHeader(String key,String value):设置键值对形式的响应头
掌握的响应头:
1 content-type: 通知浏览器响应的内容是什么类型的 并且用什么编码解析内容
(了解)response.setHeader("content-type","文件的类型;charset=utf-8");
(掌握)简写:response.setContentType("文件的类型;charset=utf-8");
----- 解决响应回去的中文乱码问题
2 location:重定向
(了解)response.setHeader("location", "/day31/sd4"); //操作响应头
response.setStatus(302); //操作响应行的状态码
(掌握)简写:response.sendRedirect(request.getContextPath()+"/sd8");
面试题:请求转发和重定向的区别?
1 请求转发是request对象方法 重定向是response对象方法
2 请求转发只有一次请求 地址不会发生改变 重定向多次请求 地址栏会发生改变
3 请求转发只能访问内部资源 重定向既可以访问内部资源也可以访问外部资源
3 refresh:定时刷新
response.setHeader("refresh","秒数;url=跳转的路径");
4 content-disposition:通知浏览器写回去的东西要以附件形式打开 (只用于下载)
// 默认情况下都是页面直接展示写回去的数据
(掌握)response.setHeader("content-disposition","attachment;filename="+1.jpg);
操作响应体
页面上默认要展示的内容
api方法:
PrintWriter getWriter();字符流
ServletOutputStream getOutputStream():字节流 (二进制)
特点:
1 若是能写的出来的内容用字符流,其他全用字节流(下载专用)
2 不能同时出现
3 服务器会自动帮我们关闭这2个流.
package cn.itcast.web;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
@WebServlet(name = "ServletDemo12",urlPatterns = "/sd12")
public class ServletDemo12 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
//字符流写回给浏览器数据--除了下载 都选用字符流做输出
PrintWriter writer = response.getWriter();
writer.print("abcd");
// 字节流写回给浏览器数据--下载
ServletOutputStream outputStream = response.getOutputStream();
outputStream.print("bbbb");
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request,response);
}
}