ServletResponse

To send binary data in a MIME body response, use the ServletOutputStream returned by getOutputStream()). To send character data, use the PrintWriter object returned by getWriter()).

设置响应报文

响应行

响应头

响应体

传输字符数据中文乱码

锟斤拷烫烫烫 —— utf-8 gbk

  1. ?????? 表示压根不支持中文

服务器处理响应体使用的编码格式压根不支持中文,ISO-8859-1

  1. 浣犲ソ锛侊紒锛侊紒
  1. package com.cskaoyan.response;
  2. import javax.servlet.ServletException;
  3. import javax.servlet.annotation.WebServlet;
  4. import javax.servlet.http.HttpServlet;
  5. import javax.servlet.http.HttpServletRequest;
  6. import javax.servlet.http.HttpServletResponse;
  7. import java.io.IOException;
  8. @WebServlet("/response2")
  9. public class ResponseServlet2 extends HttpServlet {
  10. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  11. }
  12. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  13. //设置响应报文
  14. //设置了该API之后,说明服务器设置的编码格式已经生效,这个时候如果还是乱码,只能说明一个问题
  15. //浏览器使用的不是utf-8进行解码
  16. //浏览器使用的是gbk(1.和你的平台编码--操作系统的编码 2.和你的语言有关)
  17. //将这个改成gbk不是正确的处理流程,假设一台浏览器使用的默认编码格式不是gbk,不是又乱码了吗
  18. //浏览器其实是支持很多种编码格式的,不管服务器采用那种编码格式,那么你设置了之后,告诉浏览器不就行了吗
  19. //response.setCharacterEncoding("utf-8");
  20. //如何告诉浏览器呢?1.响应头 2.响应体
  21. //这个头其实有两层含义:1.设置服务器编码格式utf-8 2发送响应头,告诉浏览器使用的是utf-8
  22. response.setHeader("Content-Type","text/html;charset=utf-8");
  23. response.getWriter().println("你好!!!!");
  24. }
  25. }

方式二

  1. package com.cskaoyan.response;
  2. import javax.servlet.ServletException;
  3. import javax.servlet.annotation.WebServlet;
  4. import javax.servlet.http.HttpServlet;
  5. import javax.servlet.http.HttpServletRequest;
  6. import javax.servlet.http.HttpServletResponse;
  7. import java.io.IOException;
  8. @WebServlet("/response4")
  9. public class ResponseServlet4 extends HttpServlet {
  10. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  11. }
  12. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  13. //中文乱码问题,解决方案二
  14. //response.setContentType("text/html;charset=utf-8");
  15. //设置响应体的编码格式utf-8,还需要将编码格式告诉给浏览器
  16. //可以通过响应头,也可以通过响应体
  17. //可以在代码里面写入html标签以及css、js代码,普通的文本
  18. //只是这些文本对于浏览器来说,她们具有特殊的含义
  19. response.setCharacterEncoding("utf-8");
  20. response.getWriter().println("<!DOCTYPE html>\n" +
  21. "<html lang=\"en\">\n" +
  22. "<head>\n" +
  23. " <meta charset=\"UTF-8\">\n" +
  24. " <title>Title</title>\n" +
  25. "</head>\n" +
  26. "<body>");
  27. response.getWriter().println("你好!!!!");
  28. response.getWriter().println("</body>\n" +
  29. "</html>");
  30. }
  31. }

输出字节数据到客户端

字节数据,二进制数据,文本、图片、音视频等

就是把二进制数据写入到响应体中,传输给客户端,客户端拿到之后进行解析,渲染出来

写入到响应体的API:

response.getWriter().prinltn()这个是写字符的,写字节的话需要使用另外一个API

response.getOutputStream()

ServletResponse - 图1

第一个是将流写入到文件中

第二个是将流写入到response的缓冲区中,目的地不同,写入方式完全相同

  1. package com.cskaoyan.response;
  2. import javax.servlet.ServletException;
  3. import javax.servlet.ServletOutputStream;
  4. import javax.servlet.annotation.WebServlet;
  5. import javax.servlet.http.HttpServlet;
  6. import javax.servlet.http.HttpServletRequest;
  7. import javax.servlet.http.HttpServletResponse;
  8. import java.io.File;
  9. import java.io.FileInputStream;
  10. import java.io.IOException;
  11. @WebServlet("/stream")
  12. public class StreamServlet extends HttpServlet {
  13. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  14. }
  15. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  16. String realPath = getServletContext().getRealPath("1.jpg");
  17. //String realPath = getServletContext().getRealPath("WEB-INF/1.html");
  18. FileInputStream inputStream = new FileInputStream(new File(realPath));
  19. ServletOutputStream outputStream = response.getOutputStream();
  20. int length = 0;
  21. byte[] bytes = new byte[1024];
  22. while ((length = inputStream.read(bytes)) != -1){
  23. outputStream.write(bytes, 0, length);
  24. }
  25. //应该关闭流
  26. inputStream.close();
  27. //输出流可以关闭也可以不关闭,如果不关闭的话,tomcat会帮我们关闭
  28. outputStream.close();
  29. }
  30. }

作业:

要求你在当前应用下实现一个缺省Servlet。

url-pattern必须是/。

静态资源文件就不能正常显示了,你需要做的事情,是静态资源文件还可以正常的显示出来。

  1. package com.cskaoyan.response;
  2. import javax.servlet.ServletException;
  3. import javax.servlet.annotation.WebServlet;
  4. import javax.servlet.http.HttpServlet;
  5. import javax.servlet.http.HttpServletRequest;
  6. import javax.servlet.http.HttpServletResponse;
  7. import java.io.IOException;
  8. @WebServlet("/")
  9. public class MyDefaultServlet extends HttpServlet {
  10. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  11. }
  12. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  13. System.out.println("/");
  14. //关于路径相关的API
  15. String requestURI = request.getRequestURI();
  16. String requestURL = request.getRequestURL().toString();
  17. //该API返回当前应用的应用名
  18. String contextPath = request.getContextPath();
  19. //返回的路径: servletPath相对部署根目录的一个相对路径
  20. // servletPath = requestURI - contextPath
  21. String servletPath = request.getServletPath();
  22. System.out.println(requestURI);
  23. System.out.println(requestURL);
  24. System.out.println(contextPath);
  25. System.out.println(servletPath);
  26. }
  27. }

其他两种页面跳转技术

refresh响应头

  1. package com.cskaoyan.response;
  2. import javax.servlet.ServletException;
  3. import javax.servlet.annotation.WebServlet;
  4. import javax.servlet.http.HttpServlet;
  5. import javax.servlet.http.HttpServletRequest;
  6. import javax.servlet.http.HttpServletResponse;
  7. import java.io.IOException;
  8. import java.text.SimpleDateFormat;
  9. import java.util.Date;
  10. @WebServlet("/refresh")
  11. public class RefreshServlet extends HttpServlet {
  12. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  13. }
  14. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  15. //refresh是一个响应头,
  16. //页面会一直刷新,动态显示时间 Mon Nov 30 10:14:17 CST 2020
  17. // 希望将时间改成这种格式 2020-11-30 10:13:00
  18. SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  19. String formateDate = format.format(new Date());
  20. response.getWriter().println(formateDate);
  21. //表示每隔指定秒数刷新当前页面
  22. //response.setHeader("refresh", "1");
  23. //表示经过指定描述之后跳转至url,然后结束
  24. // response.setHeader("refresh","3;url=http://www.baidu.com");
  25. response.setHeader("refresh","3;url=" + request.getContextPath() + "/load.html");
  26. }
  27. }

重定向

302、307 www.bing.com

需要状态码以及一个Location响应头

  1. package com.cskaoyan.response;
  2. import javax.servlet.ServletException;
  3. import javax.servlet.annotation.WebServlet;
  4. import javax.servlet.http.HttpServlet;
  5. import javax.servlet.http.HttpServletRequest;
  6. import javax.servlet.http.HttpServletResponse;
  7. import java.io.IOException;
  8. @WebServlet("/redirect")
  9. public class RedirectServlet extends HttpServlet {
  10. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  11. }
  12. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  13. //先根据重定向的定义以及之前学习的API自己先实现一下重定向
  14. //response.setStatus(302);
  15. //response.setHeader("Location", "http://www.baidu.com");
  16. //JavaEE规范给我们提供了一个API来实现重定向
  17. response.sendRedirect(request.getContextPath() + "/load.html");
  18. }
  19. }
  1. package com.cskaoyan.response;
  2. import javax.servlet.ServletException;
  3. import javax.servlet.annotation.WebServlet;
  4. import javax.servlet.http.HttpServlet;
  5. import javax.servlet.http.HttpServletRequest;
  6. import javax.servlet.http.HttpServletResponse;
  7. import java.io.IOException;
  8. @WebServlet("/login")
  9. public class LoginServlet extends HttpServlet {
  10. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  11. response.setContentType("text/html;charset=utf-8");
  12. String username = request.getParameter("username");
  13. String password = request.getParameter("password");
  14. if("admin".equals(username) && "admin".equals(password)){
  15. //表示登录成功
  16. //跳转的方式可以有如下三种:1.转发 2.定时刷新 3 重定向
  17. //request.getRequestDispatcher("/success.html").forward(request, response);
  18. // response.getWriter().println("登录成功,即将跳转至登录成功页面,如果没有跳转," +
  19. // "可以点击<a href='" + request.getContextPath() + "/success.html" +"'>当前链接</a>手动跳转");
  20. // response.setHeader("refresh", "10;url=" + request.getContextPath() + "/success.html");
  21. response.sendRedirect(request.getContextPath() + "/success.html");
  22. }
  23. }
  24. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  25. }
  26. }

几种页面跳转技术的区别

转发、重定向、定时刷新

转发是一次请求,可以共享request域;其他两个是两次请求,不可以共享request域

转发只能转发到当前应用下;其他两种技术不受限制

转发是request介导的;其他两种是response介导的

转发是服务器介导的;其他两种是浏览器介导的

下载

先说浏览器的行为。

浏览器对于可以打开的文件执行打开操作,对于无法打开的文件默认执行下载操作。但是如果对于这部分浏览器可以打开的,如果希望浏览器执行下载,可以使用响应头,告诉浏览器执行下载操作,而不是打开。

  1. package com.cskaoyan.response;
  2. import javax.servlet.ServletException;
  3. import javax.servlet.ServletOutputStream;
  4. import javax.servlet.annotation.WebServlet;
  5. import javax.servlet.http.HttpServlet;
  6. import javax.servlet.http.HttpServletRequest;
  7. import javax.servlet.http.HttpServletResponse;
  8. import java.io.File;
  9. import java.io.FileInputStream;
  10. import java.io.IOException;
  11. @WebServlet("/download")
  12. public class DownloadServlet extends HttpServlet {
  13. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  14. }
  15. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  16. //把1.jpg下载到本地
  17. response.setHeader("Content-Disposition", "attachment;filename=1.jpg");
  18. String realPath = getServletContext().getRealPath("1.jpg");
  19. //String realPath = getServletContext().getRealPath("WEB-INF/1.html");
  20. FileInputStream inputStream = new FileInputStream(new File(realPath));
  21. ServletOutputStream outputStream = response.getOutputStream();
  22. int length = 0;
  23. byte[] bytes = new byte[1024];
  24. while ((length = inputStream.read(bytes)) != -1){
  25. outputStream.write(bytes, 0, length);
  26. }
  27. //应该关闭流
  28. inputStream.close();
  29. //输出流可以关闭也可以不关闭,如果不关闭的话,tomcat会帮我们关闭
  30. outputStream.close();
  31. }
  32. }