1、关于响应
响应简单来说就是服务端收到了客户端的请求,把处理结果再发生回客户端。
Servlet中定义了协议相关的对象 ServletReponse
接口和协议无关的对象 HttpServletResponse
接口
2、常见状态码
状态码 | 说明 |
---|---|
200 | 执行成功 |
302 | 它和307一样,都是用于重定向的状态码。只是307目前已不再使用 |
304 | 请求资源未改变,使用缓存。 |
400 | 请求错误。最常见的就是请求参数有问题 |
404 | 请求资源未找到 |
405 | 请求方式不被支持 |
500 | 服务器运行内部错误 |
状态码首位含义
状态码 | 说明 |
---|---|
1xx | 消息 |
2xx | 成功 |
3xx | 重定向 |
4xx | 客户端错误 |
5xx | 服务器错误 |
3、常用方法
1)字节流响应消息
返回值 | 方法名 | 说明 |
---|---|---|
ServletOutputStream | getOutputStream() | 获取响应字节输出对象 |
void | serContentType("text/html;charset=UTF-8") | 设置响应内容类型,解决中午乱码问题 |
tips: 会存在乱码 idea的字符集是UTF-8 而chrome和ie浏览器默认字符集是GB2312
解决办法:
-
修改浏览器编码
-
向页面输出一个标签,设置字符集
<meta http-equiv="content-type" content="text/html;charset=UTF-8">
-
设置响应消息头,告知浏览器响应正文的MIME类型和字符集
-
推荐办法,本质是设置一个响应头消息
@WebServlet("/servletDemo02")
public class servletDemo02 extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1.获取字节流输出对象
ServletOutputStream outputStream = resp.getOutputStream();
//2.定义一个消息
String str = "你好 outputStream";
//3.通过字节流对象输出 getBytes 默认根据系统平台选择编码格式 winds默认gbk
//同时设置浏览器编码
//outputStream.write(str.getBytes("UTF-8"));
//未生效
//outputStream.write("<meta http-equiv='content-type' content='text/html;charset=UTF-8'>".getBytes());
//生效
//resp.setHeader("Content-Type","text/html;charset=UTF-8");
//推荐使用
resp.setContentType("text/html;charset=UTF-8");
outputStream.write(str.getBytes("UTF-8"));
}
}
2)字符流响应消息
返回值 | 方法名 | 说明 |
---|---|---|
PrintWritet | getWritet() | 获取响应字符输出对象 |
void | serContentType("text/html;charset=UTF-8") | 设置响应内容类型,解决中午乱码问题 |
@WebServlet("/servletDemo02")
public class servletDemo02 extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html;charset=UTF-8");
//1.获取字节流输出对象
PrintWriter writer = resp.getWriter();
//2.定义一个消息
String str = "你好 writer";
//3.通过字符流对象输出
writer.write(str);
}
}
tips: resp.setContentType("text/html;charset=UTF-8"); 放在开头否则不生效
4、响应图片
@WebServlet("/servletDemo02")
public class servletDemo02 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 通过文件的相对路径获取绝对路径
String realPath = getServletContext().getRealPath("/images/head.png");
System.out.println(realPath);
//1.创建字节输出流对象,关联图片路径
BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream(realPath));
//2.通过响应对象获取字节输出流对象
ServletOutputStream outputStream = resp.getOutputStream();
//3.循环读取
byte[] arr = new byte[1024];
int len;
while ((len = bufferedInputStream.read(arr)) != -1){
outputStream.write(arr,0,len);
}
}
}
路径是关键
5、缓存
对于不常变化的资源,设置合理的缓存时间,可以避免频繁访问服务器,提升效率。
返回值 | 方法名 | 说明 |
---|---|---|
void | setDateHeader(String name,long time) | 设置消息头添加缓存 |
@WebServlet("/servletDemo02")
public class servletDemo02 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String name = "hello ";
//设置编码格式
resp.setContentType("text/html;charset=UTF-8");
//设置缓存
resp.setDateHeader("Expires",System.currentTimeMillis() + 60*60*1000);
//写出数据
resp.getWriter().write(name);
//判断是否访问服务器
System.out.println("servletDemo02");
}
}
- Date:
Sat, 03 Sep 2022 01:25:02 GMT
- Expires:
Sat, 03 Sep 2022 02:25:02 GMT
6、定时刷新
过了指定时间,页面自动刷新
返回值 | 方法名 | 说明 |
---|---|---|
void | setHeader(String name,String value) | 设置消息头定时刷新 |
@WebServlet("/servletDemo02")
public class servletDemo02 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String name = "三秒后跳转注册页面";
//设置编码格式
resp.setContentType("text/html;charset=UTF-8");
//写出数据
resp.getWriter().write(name);
//定时刷新
resp.setHeader("refresh","3;URL=/crm/regist.html");
}
}
7、重定向
客户端接收到请求需要其他Servlet来完成
与请求转发相比,浏览器地址会发生变化,请求域对象数据不能共享,可以重定向到其他服务器
重定向实现原理
- 设置状态码为302
- resp.setStatus(302);
- 设置响应的资源路径(通过响应头location指定)
返回值 | 方法名 | 说明 |
---|---|---|
void | sendRedirect(Srting name) | 设置重定向 |
public class PeopleServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("PeopleServlet");
Object encoding = req.getAttribute("encoding");
System.out.println(encoding+"people");
}
}
@WebServlet("/servletDemo02")
public class servletDemo02 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("servletDemo02");
req.setAttribute("encoding","css");
//req.getContextPath() 获取虚拟路径
resp.sendRedirect(req.getContextPath()+"/peopleServlet");
}
}
servletDemo02
PeopleServlet
nullpeople
可以发现数据无法共享
8、文件下载
@WebServlet("/servletDemo02")
public class servletDemo02 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//创建字节输入流,关联读取的文件
String realPath = getServletContext().getRealPath("/images/head.png");
BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream(realPath));
//设置响应消息头支持的类型
resp.setHeader("Content-Type","application/octet-stream");
//设置响应消息头以下载方式打开资源
//attachment;filename=hm.png 消息头参数 附件形式进行处理 指定下载文件的名称
resp.setHeader("Content-Disposition","attachment;filename=hm.png");
//通过响应对象获取字节输出流对象
ServletOutputStream outputStream = resp.getOutputStream();
//循环读写
byte[] arr = new byte[1024];
int len;
while ((len = bufferedInputStream.read(arr))!=-1){
outputStream.write(arr,0,len);
}
//释放资源
bufferedInputStream.close();
}
}