response&request
一、ServletContext
1. ServletContext介绍
讲解
ServletContext介绍
- ServletContext:Servlet上下文对象。它是把一个web应用的信息对象。当Tomcat启动时,会把web应用的信息封装成一个ServletContext对象
- ServletContext特性:
- 一个web应用里:只有一个ServletContext对象
- 当服务器启动时,ServletContext会被Tomcat创建
获取ServletContext
- 在Servlet类里(继承HttpServlet方式的),可以使用方法:
ServletContext context = getServletContext();
小结
- ServletContext对象:是把一个web应用的信息封装成的对象
- ServletContext对象的特征:
- 一个web应用里,只有一个ServletContext对象
2. ServletContext作用
分析
- ServletContext有两个常用作用:
- 可以读取web应用里的资源
- 是一个域对象
讲解
读取web应用里的资源【重点】
- 如果要读取src里的资源,可以使用类加载器
InputStream is = 类名.class.getClassLoader().getResourceAsStream("src里的文件名");
- 如果要读取web里的资源,可以使用ServletContext
InputStream is = servletContext.getResourceAsStream("web里的文件名");
是一个域对象【面试】
- 什么是域对象:由Servlet规范提供的,可以存取数据的对象。域对象里的数据,在其作用范围里可以共享。
- 有哪些域对象:ServletContext, HttpSession, ServletRequest, PageContext
- 域对象的共同点:都可以存取数据,并且存取数据的方法都是:
- 存数据:
setAttribute(String name, Object value)
- 取数据:
getAttribute(String name)
- 删数据:
removeAttribute(String name)
- 存数据:
- 域对象的不同点:共享范围不同
- ServletContext:
- 何时创建:服务器启动时
- 何时销毁:服务器关闭时
- 作用范围:整个web应用
- ServletContext:
小结
-
读取资源文件:
- 如果要读取src里的资源:用类加载器
InputStream is = 类加载器.getResourceAsStream("src里的资源文件名");
- 如果要读取web里的资源:用ServletContext
InputStream is = servletContext.getResourceAsStream("web里的资源文件名");
-
是一个域对象
- 域对象:由Servlet规范提供的,可以存取数据的对象。域对象里的数据,在其作用范围里可以共享
- 域对象的共同点:都可以存取数据,方法都是:
- 存数据:
setAttribute(String name, Object value)
- 取数据:
getAttribute(String name)
- 删数据:
removeAttribute(String name)
- 存数据:
- 域对象的不同点:作用范围不同(共享范围不同)
- ServletContext:
- 何时创建:服务器启动时
- 何时销毁:服务器关闭时
- 作用范围:整个web应用
- ServletContext:
二、request和response的原理
讲解
request和response对象介绍
-
request:代表HTTP请求的对象,
HttpServletRequest
,ServletRequest
HttpServletRequest
extendsServletRequest
HttpServletRequest
功能更强,我们开发中使用的通常是这个对象
-
response:代表HTTP响应的对象,
HttpServletResponse
,ServletResponse
HttpServletResponse
extendsServletResponse
HttpServletResponse
功能更强,我们开发中使用的通常是这个对象
-
Tomcat创建的response对象,在调用Servlet的方法时,作为实参传递给Servlet
-
我们可以向response里设置数据,这些数据最终被Tomcat转换成HTTP响应的格式,返回了客户端
小结
三、response操作http响应
1. response简介
代表响应的对象,是HttpServletResponse
的实例对象,用来向客户端响应数据。
ServletResponse
:在Servlet接口里有HttpServletResponse
:是ServletResponse的子接口,功能更强
2. 设置响应行
讲解
- response对象提供了方法
方法 | 参数 | 返回值 |
---|---|---|
setStatus(int code) | code:响应状态码(通常是非错误码,1xx,2xx,3xx) | |
sendError(int code) | code:响应状态码(通常是错误码, 4xx, 5xx) |
- 使用示例
@WebServlet(urlPatterns="/line")
public class Demo02ResponseLineServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//设置响应行
//1. 设置响应状态码:setStatus方法,通常用于设置功能性的响应码 2xx,3xx
response.setStatus(302);
//2. 设置响应状态码:sendError方法,通常用于设置错误的响应码 4xx, 5xx
//response.sendError(404);
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
小结
- 设置响应状态码:
- 非错误码:
response.setStatus(int code)
- 错误码:
response.sendError(int code)
- 非错误码:
3. 设置响应头
讲解
- response对象提供了方法
方法 | 说明 | 参数 | 返回值 |
---|---|---|---|
setHeader(String name, String value) | 设置响应头 | name:响应头名称 value:响应头的值 | |
sendRedirect(String path) | 重定向跳转 | path:跳转的路径 |
重定向跳转的参数写法:
/项目路径/资源访问路径
-
示例:
假如当前项目的路径是
/day09
@WebServlet(urlPatterns="/header")
public class Demo03ResponseHeaderServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//设置响应头
//覆盖式设置响应头
response.setHeader("name", "tom");
//追加响应头,不会覆盖已有的头
response.addHeader("name", "jerry");
//重定向跳转【重点】。比如:登录成功之后,让浏览器跳转到首页
response.sendRedirect("/day09/index.html");
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
小结
- 设置响应头:
response.setHeader(String name, String value)
- 【重点】让浏览器跳转(重定向):
response.sendRedirect("跳转的路径")
4. 设置响应体【重点】
讲解
- response对象提供了方法:
方法 | 说明 | 参数 | 返回值 |
---|---|---|---|
getWriter() | 获取response的字符型输出流 | PrintWriter 对象 | |
getOutputStream() | 获取response的字节型输出流 | ServletOutputStream 对象 |
字符型响应体示例:
- 字符型响应体中文乱码,解决:
- 在
getWriter()
方法之前,先执行:response.setContentType("text/html;charset=utf-8")
@WebServlet(urlPatterns="/charBody")
public class Demo04ResponseCharBodyServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//字符型响应体
response.setContentType("text/html;charset=utf-8");
PrintWriter writer = response.getWriter();
writer.print("你好,2哥");
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
字节型响应体示例:
@WebServlet(urlPatterns="/byteBody")
public class Demo05ResponseByteBodyServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//字节型 设置响应体。
//要求:给客户端返回一张图片,显示到客户端浏览器页面上
//1.得到输出流
ServletOutputStream os = response.getOutputStream();
//2.得到输入流:使用ServletContext,从web里读取
ServletContext context = this.getServletContext();
InputStream is = context.getResourceAsStream("WEB-INF/files/a.jpg");
//3.读取数据,写到输出流
byte[] buffer = new byte[1024*8];
int len = -1;
while ((len = is.read(buffer)) != -1) {
os.write(buffer, 0, len);
}
//4.关闭流
os.close();
is.close();
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
小结
- 字符型响应体:
//解决中文响应体乱码问题
response.setContentType("text/html;charset=utf-8");
//输入字符串内容
PrintWriter writer = response.getWriter();
writer.print("显示到浏览器上的内容");
- 字节型响应体:
ServletOutputStream os = response.getOutputStream();
四、request获取http请求数据
1. request简介
- 代表请求的对象,是
HttpServletRequest
的实例对象,用来接收客户端提交的数据。
2. request获取请求行
讲解
API
方法 | 说明 | 参数 | 返回值 |
---|---|---|---|
getMethod() | 获取请求方式 | String | |
getContextPath() | 获取项目路径 | String |
示例
@WebServlet(urlPatterns="/line", name="Demo02RequestLineServlet")
public class DemoLineServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取请求方式。
String method = request.getMethod();
System.out.println("请求方式:" + method);
//获取项目路径
String contextPath = request.getContextPath();
System.out.println("项目路径:" + contextPath);
//代码中需要使用项目路径的地方,要使用request.getContextPath()动态获取
//response.sendRedirect(contextPath + "/index.jsp");
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
路径的写法
-
如果要请求一个资源,就必须要写资源的访问路径
这里总结是的资源的请求/访问路径,而不是IO读取的路径
补充知识
-
什么样的请求是GET?什么样的请求是POST?
- 默认是GET。只有指定了是POST,才是POST。(到目前为止,只用到表单的method可以设置请求方式)
-
如果代码里路径,写死了项目路径该怎样处理?
- 在Servlet里:动态获取项目路径,拼接进去。比如重定向时:
- 原本写法:
response.sendRedirect("/web16/index.html")
: - 修改成:
response.sendRedirect(request.getContextPath() + "/index.html")
- 原本写法:
- 在html里,使用相对路径代替绝对路径(可以避免出现项目路径了)
- 在Servlet里:动态获取项目路径,拼接进去。比如重定向时:
小结
- 获取请求方式:
request.getMethod()
- 获取项目路径:
request.getContextPath()
3. request获取请求头
讲解
API
方法 | 说明 | 参数 | 返回值 |
---|---|---|---|
getHeader(name) | 获取请求头的值 | name:请求头的名称 | String |
getIntHeader(name) | 获取请求头的值,转换为int给我们 | int | |
getDateHeader(name) | 获取请求头的值,转换为long给我们 | long |
示例
@WebServlet(urlPatterns="/header", name="Demo03RequestHeaderServlet")
public class DemoHeaderServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取请求头 Referer:本次请求是从哪个页面发起的
String referer = request.getHeader("Referer");
System.out.println(referer);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
小结
- 获取请求头:
request.getHeader(String name)
4. request获取请求参数
目标
- 能够使用request获取请求参数
- 能够解决中文参数乱码问题
讲解
API
- request对象提供的方法:
方法 | 说明 | 参数 | 返回值 |
---|---|---|---|
getParameter(name) | 获取一个表单项的值 | name:表单项名称 | String |
getParameterValues(name) | 获取一个表单项的值 | String[] | |
getParameterMap() | 获取所有表单项的值 | Map<String,String[]> |
解决中文参数乱码
-
请求的中文乱码:
request.setCharacterEncoding("utf-8")
要在第一次获取参数之前,先解决请求乱码
示例
- 页面表单
<form action="param1" method="post">
用户名:<input type="text" name="username"><br>
爱好:
<input type="checkbox" name="hobby" value="eat">吃
<input type="checkbox" name="hobby" value="drink">喝
<input type="checkbox" name="hobby" value="play">玩
<br>
<input type="submit" value="post提交">
</form>
- Servlet里接收表单参数
@WebServlet(urlPatterns="/param1", name="Demo04RequestParam1Servlet")
public class DemoParamServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//解决 中文请求参数乱码
request.setCharacterEncoding("utf-8");
//获取username的值
String username = request.getParameter("username");
System.out.println(username);
System.out.println("----------------------");
//获取hobby的值
String[] hobbies = request.getParameterValues("hobby");
for (String hobby : hobbies) {
System.out.println(hobby);
}
System.out.println("----------------------");
//获取所有表单参数
Map<String, String[]> map = request.getParameterMap();
for (String key : map.keySet()) {
String[] values = map.get(key);
System.out.println(key + ": " + Arrays.toString(values));
}
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
小结
- 接收单值表单项:
String value = request.getParameter(String name)
- 接收多值表单项:
String[] values = request.getParameterValues(String name)
- 接收所有表单项:
Map<String,String[]> map = request.getParameterMap()
- 解决中文表单参数的乱码:要在第一次接收参数之前,先执行:
- 通常是在Servlet里最前边,加以下边两行代码:
//解决请求的中文表单参数乱码
request.setCharacterEncoding("utf-8");
//解决响应的中文内容乱码
response.setContentType("text/html;charset=utf-8");
五、request其它作用
1. 是一个域对象
讲解
- 域对象:由Servlet规范提供的,能临时存储数据的对象;在其作用范围里,数据可以共享
- 所有域对象都可以存储数据:
- 存数据:
setAttribute(String name, Object value)
- 取数据:
getAttribute(String name)
- 删数据:
removeAttribute(String name)
- 存数据:
- 使用域对象进行数据共享的原则:在满足要求的情况下,使用小的域对象
- 不同域对象的区别是:作用范围不同
- ServletContxt:
- 何时创建:服务器启动时
- 何时销毁:服务器关闭时
- 作用范围:整个web项目
- request:
- 何时创建:一次请求开始
- 何时销毁:一次请求结束(开始响应时)
- 作用范围:一次请求中
- ServletContxt:
小结
2. 请求转发跳转
讲解
请求转发和重定向的区别
-
请求转发有1次请求;重定向有2次请求
-
请求转发地址栏不变;重定向地址栏会变
-
请求转发是服务器跳转;重定向是浏览器跳转
-
什么时候用请求转发跳转?
- 如果跳转时,有数据要传递给下一个资源,就使用请求转发
-
什么时候用重定向跳转?
- 没有数据要传递,就使用重定向
API实现请求转发跳转
//请求转发,是服务端跳转
request.getRequestDispatcher("/资源路径").forward(request, response);
//回顾:重定向,是浏览器跳转
response.sendRedirect("/项目路径/资源路径");
注意:
- 请求转发时,资源路径前边 不要加项目路径(是服务端跳转)
- 重定向时,资源路径前边,必须加项目路径(是浏览器跳转)
小结
-
请求转发跳转:
request.getRequestDispatcher("/scope2").forward(request, response);
-
重定向跳转:
response.sendRedirect("/day08/scope2"); response.sendRedirect(request.getContextPath() + "/scope2");