五、HttpServletResponse类
1、作用
HttpServletResponse类和HttpServletRequest类一样,每次请求进来,Tomcat服务器都会创建一个Response对象传递给Servlet程序去使用。HttpServletRequest表示请求过来的信息,HttpServletResponse表示所有响应的信息。我们如果需要设置返回给客户端的信息,都可以通过它来设置。
2、两个输出流的说明
- 字节流:getOutputStream()——常用于下载(传递二进制数据)
- 字符流:getWrite()——常用于回传字符串(常用)
两个流同时只能使用一个,否则会报错
3、如何往客户端回传数据
回传字符串
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //设置服务器字符集 response.setCharacterEncoding("UTF-8"); //设置浏览器字符集 response.setHeader("Content-Type","text/html;charset=UTF-8"); PrintWriter writer = response.getWriter(); writer.write("哈哈"); }
设置字符集也可以使用以下方法
response.setContent-Type("text/html;charset=UTF-8")
此法会同时设置服务器和浏览器的字符集,并设置响应头
以上方法都应该在获取输出流之前调用
通过字节流回传字符串
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("txt/html;charset=utf-8") PrintWriter writer = response.getOutputStream(); //获取字符串的字节数组 writer.write("哈哈".getBytes("utf-8")); //默认编码是本机编码,也可以自己设置编码 }
4、请求重定向
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aBJZQXEi-1636276443285)(C:\Users\Ken-Chy\Desktop\大二临时\00自学部分\后端\笔记\请求重定向.png)]
public class Response1 extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //第一种方法 /* System.out.println("我曾来过"); //设置状态码302,表示重定向(已搬迁) response.setStatus(302); //设置响应头,说明新的地址在哪 response.setHeader("Location","http://localhost:8080/myfirst/response2"); */ //第二种方法(推荐使用) response.sendRedirect("https://www.baidu.com"); } }
public class Response2 extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setHeader("Content-Type","text/html;charset=UTF-8"); response.getWriter().write("欢迎您的到来"); } }
请求重定向的特点
1.浏览器地址栏会发生变化
2.两次请求
3.不共享Request域中的数据
4.不能访问WEB-INF下的资源
5.可以访问工程外的数据
六、乱码问题详解
1、乱码原因
服务器编码和浏览器端解码使用的字符集不一致
浏览器端默认使用的编码和当前操作系统的语言环境有关,如果是中文的windows系统则默认是GBK或gb2312
如果服务器中字符流是自己new创建出来的,则也是与本机字符集一致,不会乱码
而当服务器通过response.getWriter()获取字符输出流,这个输出流是通过tomcat返回的,tomcat使用的编码是ISO-8859-1
2、解决方法
获取流对象之前,设置流的默认编码
response.setCharacterEncoding("utf-8");
告诉浏览器服务器发送的消息体数据的编码,建议浏览器使用该编码解码
response.setHeader("context-type", "txt/html;charset=utf-8")
简单形式
response.setContentType(“txt/html;charset=utf-8”);
七、验证码的实现
本质:图片
目的:防止恶意表单注册
步骤:
1.创建一个对象,在内存中生成图片(验证码图片对象)
2.美化图片
3.将图片输出到页面展示
@WebServlet("/checkcode") public class CheckCode extends HttpServlet { int width = 100; int height = 50; @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //创建验证码图片对象 BufferedImage image = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB); //美化图片 //填充背景色 Graphics g = image.getGraphics();//画笔对象 g.setColor(Color.PINK);//设置画笔颜色 g.fillRect(0,0,width,height); //画边框 g.setColor(Color.BLUE); g.drawRect(0,0,width-1,height-1); String str="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890"; Random random = new Random(); for(int i = 1; i <= 4; i++){ int index = random.nextInt(str.length()); //获取随机字符 char ch = str.charAt(index); //生成验证码 g.drawString(ch+"",width/5*i,height/2); } //画干扰线 for(int i = 0; i < 6; i++){ int x1 = random.nextInt(width); int x2 = random.nextInt(width); int y1 = random.nextInt(height); int y2 = random.nextInt(height); g.drawLine(x1,y1,x2,y2); } //将图片输出到页面展示 ImageIO.write(image,"jpg",resp.getOutputStream()); } }
八、文件下载的实现
1、需求
1.页面显示超链接
2.点击超链接后弹出下载提示框或直接下载(取决于浏览器)
3.完成图片文件下载
2、分析
1.默认情况下:超链接指向的资源如果能被浏览器解析(如图片),则直接在浏览器中展示,如果不能解析(如视频),则弹出下载提示框(有的浏览器不会弹出,自动下载)
2.我们想要实现任何资源都弹出下载提示框
3.使用响应头设置资源的打开方式:content-disposition:attachment;filename=xxx(有的浏览器处理attachment不一定会弹出提示框)
attachment表示以附件的形式,filename表示文件名称
3、步骤
1.定义页面,编辑超链接href属性,指向servlet,传递资源名称filename
2.定义servlet
1.获取文件名称
2.使用字节输入流加载文件进内存
1.找到文件的服务器路径
2.用字节流关联
3.指定response的响应头
1.设置响应头类型
2.设置响应头打开方式
4.将数据写出到response输出流
@WebServlet("/download") public class DownloadServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //获取请求参数,文件名称 String filename = req.getParameter("filename"); //获取servletContext对象以获取文件的真实路径 ServletContext servletContext = this.getServletContext(); String realPath = servletContext.getRealPath("/jpg/" + filename); //用字节流关联文件 FileInputStream in = new FileInputStream(realPath); //获取文件对应的MIME类型以设置响应头类型 String mimeType = servletContext.getMimeType(filename); resp.setHeader("content-type",mimeType); //设置响应头的打开方式 resp.setHeader("content-disposition","attachment;filename=" + filename); //将输入流的数据写出到输出流中 ServletOutputStream outputStream = resp.getOutputStream(); byte[] buff = new byte[1024 * 8]; int len = 0; //read()读取一个字节,read(byte b[])读取b.length个字节的数据到b数组中,并返回读取到的字节数,如果没有字节可读了,即read()督导文件末尾了,则返回-1 while((len = in.read(buff)) != -1){ //public void write(byte b[ ], int off, int len) :将参数b的从偏移量off开始的len个字节写到输出流 outputStream.write(buff,0,len); } in.close(); } }
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <a href="/myfirst/jpg/11.jpg">查看图片嗷</a> <br> <a href="/myfirst/download?filename=11.jpg">下载图片嗷</a> </body> </html>