inputstream转fileinputstream对象_Java Web--Servlet--HttpServletResponse对象

HttpServletResponse对象

  • 一、HttpServletResponse对象介绍
    • 1.1、负责向客户端(浏览器)发送数据的相关方法
    • 1.2、负责向客户端(浏览器)发送响应头的相关方法
    • 1.3、负责向客户端(浏览器)发送响应状态码的相关方法
    • 1.4、响应状态码的常量
  • 二、HttpServletResponse对象常见应用
    • 2.1、Response输出方法
    • 2.2、Response乱码问题
    • 2.3、中文文件下载
  • 三、HttpServletResponse常见应用——设置响应头控制浏览器的行为
    • 3.1、设置http响应头控制浏览器禁止缓存当前文档内容
    • 3.2、设置http响应头控制浏览器定时刷新网页(refresh)
    • 3.3、通过response实现请求重定向
    • 3.4、重定向与转发的区别
  • 四、web工程中URL地址的推荐写法
    • 4.1、"/"代表当前web工程的常见应用场景
    • 4.2、"/"代表webapps目录的常见应用场景

HttpServletResponse对象

一、HttpServletResponse对象介绍

9fc837a10ccefdc845c180c074f475cf.png

HttpServletResponse对象代表服务器的响应。这个对象中封装了向客户端发送数据、发送响应头,发送响应状态码的方法。查看HttpServletResponse的API,可以看到这些相关的方法。

1.1、负责向客户端(浏览器)发送数据的相关方法

ac62f1e76fb75b2c6db424f29d898ab1.png

1.2、负责向客户端(浏览器)发送响应头的相关方法

b562e7705e1063f4b40e8fc13b0020e6.png

19080a9e99d0977127fe5248ebd21de2.png

1.3、负责向客户端(浏览器)发送响应状态码的相关方法

fc4c14eb503c775589fa9b5b6cc09355.png

1.4、响应状态码的常量

HttpServletResponse定义了很多状态码的常量(具体可以查看Servlet的API),当需要向客户端发送响应状态码时,可以使用这些常量,避免了直接写数字,常见的状态码对应的常量:状态码404对应的常量

5d354b4245a797f97bdfe14d7ed9305b.png

状态码200对应的常量

6f356c85faead72fd38c9b410627b786.png

状态码500对应的常量

cf3cc8bf036385e9fff76db05ac72d6d.png

二、HttpServletResponse对象常见应用

2.1、Response输出方法

  • PrintWriter getWriter()
  • 获得字符流,通过字符流的write(String s)方法可以将字符串设置到response缓冲区中,随后Tomcat会将response缓冲区中的内容组装成Http响应返回给浏览器端。
  • ServletOutputStream getOutputStream()
  • 获得字节流,通过该字节流的write(byte[] bytes)可以向response缓冲区中写入字节,再由Tomcat服务器将字节内容组成Http响应返回给浏览器。

注意:虽然response对象的getOutSream()和getWriter()方法都可以发送响应消息体,但是他们之间相互排斥,不可以同时使用,否则会发生异常。

2.2、Response乱码问题

乱码发生的原因:

计算机中的数据都是以二进制进行存储的,因此传输文本时,就会发生字节和字符之间的转换。字符与字节之间的转换需要查码表完成,将字符转换为字节的过程叫做编码,将字节转换为字符的过程叫做解码。如果编码和解码使用的码表不一致,就会发生乱码。这就是乱码发生的根本原因

①、response缓冲区的默认编码是iso8859-1,此码表中没有中文。所以需要更改response的编码方式:

7bb3cd8276573a4605f0cfdb62740580.png

②、通过更改response的编码方式为UTF-8,任然无法解决乱码问题,因为发送端服务端虽然改变了编码方式为UTF-8,但是接收端浏览器端仍然使用GB2312编码方式解码,还是无法还原正常的中文,因此还需要告知浏览器端使用UTF-8编码去解码。

eceb0099dab2da2e643458440f471761.png

上面通过调用两个方式分别改变服务端对于Response的编码方式以及浏览器的解码方式为同样的UTF-8编码来解决编码方式不一样发生乱码的问题。response.setContentType("text/html;charset=UTF-8")这个方法包含了上面的两个方法的调用,因此在实际的开发中,只需要调用一个response.setContentType("text/html;charset=UTF-8")方法即可。

9ba0597efca658df5612877020fbaed2.png

2.3、中文文件下载

示例:文件下载 注意:下载中文文件时,需要注意的地方就是中文文件名要使用URLEncoder.encode方法进行编码:URLEncoder.encode(fileName, "字符编码"),否则会出现文件名乱码。ResponseDemo02.java

  • package com.lovo.study;
  • import java.io.FileInputStream;
  • import java.io.IOException;
  • import java.io.InputStream;
  • import java.io.OutputStream;
  • import java.net.URLEncoder;
  • import javax.servlet.ServletException;
  • import javax.servlet.http.HttpServlet;
  • import javax.servlet.http.HttpServletRequest;
  • import javax.servlet.http.HttpServletResponse;
  • public class ResponseDemo02 extends HttpServlet {
  • private static final long serialVersionUID = 1L;
  • public ResponseDemo02() {
  • super();
  • }
  • protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  • //获取要下载文件的绝对路劲
  • String realPath = this.getServletContext().getRealPath("/downloads/美女.jpg");
  • //获取要下载的文件名
  • String fileName = realPath.substring(realPath.lastIndexOf("") + 1);
  • //设置content-disposition响应头控制浏览器以下载的形式打开文件,
  • //中文文件名要使用URLEncoder.encode方法进行编码,否则会出现文件名乱码
  • response.setHeader("Content-disposition",
  • "attachment;filename="+URLEncoder.encode(fileName,"UTF-8"));
  • InputStream in = new FileInputStream(realPath);
  • int len = 0;
  • byte [] buffer = new byte[1024];
  • OutputStream out = response.getOutputStream();
  • while((len = in.read(buffer)) > 0){
  • out.write(buffer,0,len);
  • }
  • in.close();
  • }
  • protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  • doGet(request, response);
  • }
  • }

三、HttpServletResponse常见应用——设置响应头控制浏览器的行为

3.1、设置http响应头控制浏览器禁止缓存当前文档内容

  • response.setDateHeader("expries", -1);
  • response.setHeader("Cache-Control", "no-cache");
  • response.setHeader("Pragma", "no-cache");

3.2、设置http响应头控制浏览器定时刷新网页(refresh)

  • response.setHeader("refresh", "5");//设置refresh响应头控制浏览器每隔5秒钟刷新一次

3.3、通过response实现请求重定向

请求重定向:一个web资源收到客户端请求后,通知客户端去访问另外一个web资源,这称之为请求重定向。实现方式:response.sendRedirect(String location),即调用response对象的sendRedirect方法实现请求重定向sendRedirect内部的实现原理:使用response设置302状态码和设置location响应头实现重定向

  • package com.lovo.study;
  • import java.io.IOException;
  • import javax.servlet.ServletException;
  • import javax.servlet.http.HttpServlet;
  • import javax.servlet.http.HttpServletRequest;
  • import javax.servlet.http.HttpServletResponse;
  • public class ResponseDemo03 extends HttpServlet {
  • private static final long serialVersionUID = 1L;
  • public ResponseDemo03() {
  • super();
  • }
  • protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  • /**
  • * 1.调用sendRedirect方法实现请求重定向,
  • * sendRedirect方法内部调用了
  • * response.setHeader("Location", "/request_form.jsp");
  • * response.setStatus(HttpServletResponse.SC_FOUND);//设置302状态码,等同于response.setStatus(302);
  • */
  • response.sendRedirect("/request_form.jsp");
  • }
  • protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  • doGet(request, response);
  • }
  • }

3.4、重定向与转发的区别

1)转发是服务器行为,重定向是客户端行为。 为什么这样说呢,这就要看两个动作的工作流程:转发过程:客户浏览器发送http请求——web服务器接受此请求——调用内部的一个方法在容器内部完成请求处理和转发动作——将目标资源发送给客户;在这里,转发的路径必须是同一个web容器下的url,其不能转向到其他的web路径上去,中间传递的是自己的容器内的request。在客户浏览器路径栏显示的仍然是其第一次访问的路径,也就是说客户是感觉不到服务器做了转发的。转发行为是浏览器只做了一次访问请求。重定向过程:客户浏览器发送http请求——web服务器接受后发送302状态码响应及对应新的location给客户浏览器——客户浏览器发现是302响应,则自动再发送一个新的http请求,请求url是新的location地址——服务器根据此请求寻找资源并发送给客户。在这里location可以重定向到任意URL,既然是浏览器重新发出了请求,则就没有什么request传递的概念了。在客户浏览器路径栏显示的是其重定向的路径,客户可以观察到地址的变化的。重定向行为是浏览器做了至少两次的访问请求的。2).对信息的传输不一样重定向,其实是两次request第一次,客户端request A,服务器响应,并response回来,告诉浏览器,你应该去B。这个时候IE可以看到地址变了,而且历史的回退按钮也亮了。重定向可以访问自己web应用以外的资源。在重定向的过程中,传输的信息会被丢失。请求转发是服务器内部把对一个request/response的处理权,移交给另外一个对于客户端而言,它只知道自己最早请求的那个A,而不知道中间的B,甚至C、D。传输的信息不会丢失。3).对于路径的认知不一样请求转发是服务器端的动作,所以当转发路径如:

  • request.getRequestDispatcher("/RequestDemo07").forward(request, response);

路径前的绝对路径"/",会被认为是当前工程的根目录,也就是说,如果当前路径是:http://localhost:8080/ServletDemo/RequestDemo06那么根据上面的跳转就会跳转到http://localhost:8080/ServletDemo/RequestDemo07而重定向,如下面的路径: response.sendRedirect("/RequestDemo07");如果当前路径是: http://localhost:8080/ServletDemo/RequestDemo06就会跳转到: http://localhost:8080/RequestDemo07

四、web工程中URL地址的推荐写法

在JavaWeb开发中,只要是写URL地址,那么建议最好以"/"开头,也就是使用绝对路径的方式,那么这个"/"到底代表什么呢?可以用如下的方式来记忆"/":如果"/"是给服务器用的,则代表当前的web工程,如果"/"是给浏览器用的,则代表webapps目录。

4.1、"/"代表当前web工程的常见应用场景

①.ServletContext.getRealPath(String path)获取资源的绝对路径

  • /**
  • * 1.ServletContext.getRealPath("/download/1.JPG")是用来获取服务器上的某个资源,
  • * 那么这个"/"就是给服务器用的,"/"此时代表的就是web工程
  • * ServletContext.getRealPath("/download/1.JPG")表示的就是读取web工程下的download文件夹中的1.JPG这个资源
  • * 只要明白了"/"代表的具体含义,就可以很快写出要访问的web资源的绝对路径
  • */
  • this.getServletContext().getRealPath("/download/1.JPG");

②.在服务器端forward到其他页面

  • /**
  • * 2.forward
  • * 客户端请求某个web资源,服务器跳转到另外一个web资源,这个forward也是给服务器用的,
  • * 那么这个"/"就是给服务器用的,所以此时"/"代表的就是web工程
  • */
  • this.getServletContext().getRequestDispatcher("/index.jsp").forward(request, response);

③.使用include指令或者<jsp:include>标签引入页面

  • <%@include file="/jspfragments/head.jspf" %>
  • <jsp:include page="/jspfragments/demo.jsp" />

此时"/"代表的都是web工程。

4.2、"/"代表webapps目录的常见应用场景

①.使用sendRedirect实现请求重定向

  • response.sendRedirect("/index.jsp");

服务器发送一个URL地址给浏览器,浏览器拿到URL地址之后,再去请求服务器,所以这个"/"是给浏览器使用的,此时"/"代表的就是webapps目录,也就是上面的路径实际是:

  • http://localhost:8080/index.jsp

这样的路径肯定不不正确的,所以要正常访问需要改为:

  • response.sendRedirect("/SerlvetDemo(工程名)/index.jsp");

这种写法是将项目名称写死在程序中的做法,不灵活,万一哪天项目名称变了,此时就得改程序,所以推荐使用下面的灵活写法:

  • response.sendRedirect(request.getContextPath()+"/index.jsp");

request.getContextPath()获取到的内容就是"/ServletDemo",这样就比较灵活了,使用request.getContextPath()代替"/项目名称",推荐使用这种方式,灵活方便!②.使用超链接跳转

  • <a href="/ServletDemo/index.jsp">跳转到首页</a>

这是客户端浏览器使用的超链接跳转,这个"/"是给浏览器使用的,此时"/"代表的就是webapps目录。使用超链接访问web资源,绝对路径的写法推荐使用下面的写法改进:

  • <a href="${pageContext.request.contextPath}/index.jsp">跳转到首页</a>

③.Form表单提交④.js脚本和css样式文件的引用 处理方案等同于超链接案例:生成随机图片

  • package com.lovo.study;
  • import java.awt.Color;
  • import java.awt.Font;
  • import java.awt.Graphics2D;
  • import java.awt.image.BufferedImage;
  • import java.io.IOException;
  • import javax.imageio.ImageIO;
  • import javax.servlet.ServletException;
  • import javax.servlet.http.HttpServlet;
  • import javax.servlet.http.HttpServletRequest;
  • import javax.servlet.http.HttpServletResponse;
  • public class ResponseDemo04 extends HttpServlet {
  • private static final long serialVersionUID = 1L;
  • public ResponseDemo04() {
  • super();
  • }
  • protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  • response.setHeader("refresh", "5");
  • BufferedImage image = new BufferedImage(80, 20, BufferedImage.TYPE_INT_RGB);
  • Graphics2D g = (Graphics2D)image.getGraphics();
  • //先设置画笔颜色然后画背景颜色
  • g.setColor(Color.WHITE);
  • g.fillRect(0, 0, 80, 20);
  • //设置画笔颜色画数字
  • g.setColor(Color.BLUE);
  • //设置字体
  • g.setFont(new Font(null, Font.BOLD, 20));
  • //生产随机数
  • int [] nums = {0,1,2,3,4,5,6,7,8,9};
  • String str = "";
  • for(int i=0; i<6; i++){
  • int n = (int)Math.floor(Math.random() * 10);
  • str += n;
  • }
  • //画字符串
  • g.drawString(str, 0, 20);
  • //设置响应头以图片方式打开
  • response.setContentType("image/jpeg");
  • //设置响应头清除缓存
  • response.setDateHeader("expries", -1);
  • response.setHeader("Cache-Control", "no-cache");
  • response.setHeader("Pragma", "no-cache");
  • //6.将图片写给浏览器
  • ImageIO.write(image, "jpg", response.getOutputStream());
  • }
  • protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  • doGet(request, response);
  • }
  • }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
您可以使用ServletResponse对象来直接返回一个文件并在浏览器上显示。以下是一个简单的示例代码: ```java protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 获取文件路径 String filePath = "/path/to/your/file.pdf"; // 替换为您的文件路径 // 设置响应的内容类型 response.setContentType("application/pdf"); // 设置响应的头信息,指定文件名 response.setHeader("Content-Disposition", "inline; filename=file.pdf"); // 读取文件并写入响应输出流 try (InputStream inputStream = new FileInputStream(filePath); OutputStream outputStream = response.getOutputStream()) { byte[] buffer = new byte[4096]; int bytesRead; while ((bytesRead = inputStream.read(buffer)) != -1) { outputStream.write(buffer, 0, bytesRead); } } catch (IOException e) { e.printStackTrace(); } } ``` 在上述示例,`doGet`方法用于处理HTTP GET请求。首先,您需要设置正确的文件路径,将其替换为您的实际文件路径。然后,通过调用`setContentType`方法设置响应的内容类型,这里使用`application/pdf`表示PDF文件。接下来,通过调用`setHeader`方法设置响应的头信息,其`Content-Disposition`指定文件名为`file.pdf`,并将`inline`作为参数表示在浏览器上直接显示。最后,通过读取文件并将其写入响应的输出流,实现将文件内容返回给浏览器。 请注意,上述代码使用了try-with-resources语句,以确保在完成操作后正确关闭输入和输出流。此外,还应该处理可能发生的异常情况,例如文件不存在或读取失败等。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值