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
?????? 表示压根不支持中文
服务器处理响应体使用的编码格式压根不支持中文,ISO-8859-1
浣犲ソ锛侊紒锛侊紒
package com.cskaoyan.response;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("/response2")public class ResponseServlet2 extends HttpServlet {protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {}protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//设置响应报文//设置了该API之后,说明服务器设置的编码格式已经生效,这个时候如果还是乱码,只能说明一个问题//浏览器使用的不是utf-8进行解码//浏览器使用的是gbk(1.和你的平台编码--操作系统的编码 2.和你的语言有关)//将这个改成gbk不是正确的处理流程,假设一台浏览器使用的默认编码格式不是gbk,不是又乱码了吗//浏览器其实是支持很多种编码格式的,不管服务器采用那种编码格式,那么你设置了之后,告诉浏览器不就行了吗//response.setCharacterEncoding("utf-8");//如何告诉浏览器呢?1.响应头 2.响应体//这个头其实有两层含义:1.设置服务器编码格式utf-8 2发送响应头,告诉浏览器使用的是utf-8response.setHeader("Content-Type","text/html;charset=utf-8");response.getWriter().println("你好!!!!");}}
方式二
package com.cskaoyan.response;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("/response4")public class ResponseServlet4 extends HttpServlet {protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {}protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//中文乱码问题,解决方案二//response.setContentType("text/html;charset=utf-8");//设置响应体的编码格式utf-8,还需要将编码格式告诉给浏览器//可以通过响应头,也可以通过响应体//可以在代码里面写入html标签以及css、js代码,普通的文本//只是这些文本对于浏览器来说,她们具有特殊的含义response.setCharacterEncoding("utf-8");response.getWriter().println("<!DOCTYPE html>\n" +"<html lang=\"en\">\n" +"<head>\n" +" <meta charset=\"UTF-8\">\n" +" <title>Title</title>\n" +"</head>\n" +"<body>");response.getWriter().println("你好!!!!");response.getWriter().println("</body>\n" +"</html>");}}
输出字节数据到客户端
字节数据,二进制数据,文本、图片、音视频等
就是把二进制数据写入到响应体中,传输给客户端,客户端拿到之后进行解析,渲染出来
写入到响应体的API:
response.getWriter().prinltn()这个是写字符的,写字节的话需要使用另外一个API
response.getOutputStream()

第一个是将流写入到文件中
第二个是将流写入到response的缓冲区中,目的地不同,写入方式完全相同
package com.cskaoyan.response;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.File;import java.io.FileInputStream;import java.io.IOException;@WebServlet("/stream")public class StreamServlet extends HttpServlet {protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {}protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {String realPath = getServletContext().getRealPath("1.jpg");//String realPath = getServletContext().getRealPath("WEB-INF/1.html");FileInputStream inputStream = new FileInputStream(new File(realPath));ServletOutputStream outputStream = response.getOutputStream();int length = 0;byte[] bytes = new byte[1024];while ((length = inputStream.read(bytes)) != -1){outputStream.write(bytes, 0, length);}//应该关闭流inputStream.close();//输出流可以关闭也可以不关闭,如果不关闭的话,tomcat会帮我们关闭outputStream.close();}}
作业:
要求你在当前应用下实现一个缺省Servlet。
url-pattern必须是/。
静态资源文件就不能正常显示了,你需要做的事情,是静态资源文件还可以正常的显示出来。
package com.cskaoyan.response;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("/")public class MyDefaultServlet extends HttpServlet {protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {}protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {System.out.println("/");//关于路径相关的APIString requestURI = request.getRequestURI();String requestURL = request.getRequestURL().toString();//该API返回当前应用的应用名String contextPath = request.getContextPath();//返回的路径: servletPath相对部署根目录的一个相对路径// servletPath = requestURI - contextPathString servletPath = request.getServletPath();System.out.println(requestURI);System.out.println(requestURL);System.out.println(contextPath);System.out.println(servletPath);}}
其他两种页面跳转技术
refresh响应头
package com.cskaoyan.response;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.text.SimpleDateFormat;import java.util.Date;@WebServlet("/refresh")public class RefreshServlet extends HttpServlet {protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {}protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//refresh是一个响应头,//页面会一直刷新,动态显示时间 Mon Nov 30 10:14:17 CST 2020// 希望将时间改成这种格式 2020-11-30 10:13:00SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");String formateDate = format.format(new Date());response.getWriter().println(formateDate);//表示每隔指定秒数刷新当前页面//response.setHeader("refresh", "1");//表示经过指定描述之后跳转至url,然后结束// response.setHeader("refresh","3;url=http://www.baidu.com");response.setHeader("refresh","3;url=" + request.getContextPath() + "/load.html");}}
重定向
302、307 www.bing.com
需要状态码以及一个Location响应头
package com.cskaoyan.response;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("/redirect")public class RedirectServlet extends HttpServlet {protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {}protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//先根据重定向的定义以及之前学习的API自己先实现一下重定向//response.setStatus(302);//response.setHeader("Location", "http://www.baidu.com");//JavaEE规范给我们提供了一个API来实现重定向response.sendRedirect(request.getContextPath() + "/load.html");}}
package com.cskaoyan.response;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("/login")public class LoginServlet extends HttpServlet {protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {response.setContentType("text/html;charset=utf-8");String username = request.getParameter("username");String password = request.getParameter("password");if("admin".equals(username) && "admin".equals(password)){//表示登录成功//跳转的方式可以有如下三种:1.转发 2.定时刷新 3 重定向//request.getRequestDispatcher("/success.html").forward(request, response);// response.getWriter().println("登录成功,即将跳转至登录成功页面,如果没有跳转," +// "可以点击<a href='" + request.getContextPath() + "/success.html" +"'>当前链接</a>手动跳转");// response.setHeader("refresh", "10;url=" + request.getContextPath() + "/success.html");response.sendRedirect(request.getContextPath() + "/success.html");}}protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {}}
几种页面跳转技术的区别
转发、重定向、定时刷新
转发是一次请求,可以共享request域;其他两个是两次请求,不可以共享request域
转发只能转发到当前应用下;其他两种技术不受限制
转发是request介导的;其他两种是response介导的
转发是服务器介导的;其他两种是浏览器介导的
下载
先说浏览器的行为。
浏览器对于可以打开的文件执行打开操作,对于无法打开的文件默认执行下载操作。但是如果对于这部分浏览器可以打开的,如果希望浏览器执行下载,可以使用响应头,告诉浏览器执行下载操作,而不是打开。
package com.cskaoyan.response;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.File;import java.io.FileInputStream;import java.io.IOException;@WebServlet("/download")public class DownloadServlet extends HttpServlet {protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {}protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//把1.jpg下载到本地response.setHeader("Content-Disposition", "attachment;filename=1.jpg");String realPath = getServletContext().getRealPath("1.jpg");//String realPath = getServletContext().getRealPath("WEB-INF/1.html");FileInputStream inputStream = new FileInputStream(new File(realPath));ServletOutputStream outputStream = response.getOutputStream();int length = 0;byte[] bytes = new byte[1024];while ((length = inputStream.read(bytes)) != -1){outputStream.write(bytes, 0, length);}//应该关闭流inputStream.close();//输出流可以关闭也可以不关闭,如果不关闭的话,tomcat会帮我们关闭outputStream.close();}}
