HttpServletResponse

1 HttpServletResponse概述

在创建Servlet时会覆盖service()方法,或doGet()/doPost()。这些方法都有两个参数,一个为代表请求的request和代表响应response

service方法中的response的类型是ServletResponse

doGet/doPost方法的response的类型是HttpServletResponse

HttpServletResponseServletResponse的子接口,功能和方法更加强大。

1.1 response的运行流程

  

1.2通过抓包工具抓取Http响应

(之前写过)

 

因为response代表响应,所以可以通过该对象分别设置Http响应的响应行,响应头和响应体:

2通过response设置响应行

1)设置响应行的状态码setStatus(int sc)

例:建一个web项目,建一个servlet

public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //设置状态码
        response.setStatus(302);        
    }

3通过response设置响应头

3.1

1)设置响应头 setHeader(String name, String value)

2)添加响应头addHeader(String name, String value)

例:

public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {            
        //添加响应头
        response.addHeader("name", "zhangsan");
    }

其他方法:

addIntHeader(String name, int value)

addDateHeader(String name, long date)

setDateHeader(String name, long date)

setIntHeader(String name, int value)

3.2设置定时刷新的头

response.setHeader("refresh", "5;url=http://www.baidu.com");

用js方式:

建一个index.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<script>
window.onload=function(){
    var time=5;
    var second=document.getElementById("second");
    var timer=setInterval(function(){
        second.innerHTML=time;
        time--;
        if(time==0){
            clearInterval(timer);
            location.href="http://www.baidu.com";
        }
    }, 1000);
}    
</script>
</head>
<body>
    恭喜你注册成功,<span id="second" style="color:red">5</span>秒后跳转,如不跳转点击
    <a href="http://www.baidu.com">这里</a>    
</body>
</html>

4重定向

4.1重定向需要

  状态码:302

  响应头:location 代表重定向地址

4.2特点

1)访问服务器两次

2)地址栏会发生变化

例:建两个servletServlet01, Servlet02 

package com.zyx.demo01;

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 Servlet01 extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.getWriter().write("Servlet01");
        //重定向到Servlet02
        //1.设置响应行状态码
        response.setStatus(302);
        //2.设置响应头的Location
        response.setHeader("Location", "/20190109WEB/Servlet02");        
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }
}

访问http://localhost:8080/20190109WEB/Servlet01

实际不用这些,比较麻烦,用sendRedirect()方法

public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.getWriter().write("Servlet01");
        //重定向到Servlet02        
        response.sendRedirect("/20190109WEB/Servlet02");
    }

5通过response设置响应体

5.1响应体设置文本

PrintWriter getWriter()

获得字符流,通过字符流的write(String s)方法可以将字符串设置到response缓冲区中,随后Tomcat会将response缓冲区中的内容组装成Http响应返回给浏览 器端。

5.2关于设置中文的乱码问题

response.getWriter().write("中国");

  

修改:

public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //设置response缓冲区码表
        response.setCharacterEncoding("utf-8");
        //告知客户端用什么码表解码
        response.setHeader("Content-Type", "text/html;charset=utf-8");
        response.getWriter().write("中国");        
    }

比较麻烦,不用这种方式。用方法解决:

//解决响应时中文乱码问题
response.setContentType("text/html;charset=utf-8");    

5.3响应头设置字节

方法:ServletOutputStream getOutputStream()

获得字节流,通过该字节流的write(byte[] bytes)可以向response缓冲区中写入字节,再由Tomcat服务器将字节内容组成Http响应返回给浏览器。

字节能解析就解析。不能解析就下载。

例:

public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //获取Servlet字节输出流
        ServletOutputStream out=response.getOutputStream();
        //获取服务器上的图片(绝对路径)
        String realpath=getServletContext().getRealPath("download/pic.jpg");
        //获取数据源
        FileInputStream in=new FileInputStream(realpath);
        //开始复制
        int len=0;
        byte[] bytes=new byte[1024];
        while((len=in.read(bytes))!=-1){
            out.write(bytes,0,len);
        }
        //释放资源
        in.close();        
    }

改成b.zip就是下载(因为无法解析)

 

5.4文件下载

文件下载的实质就是文件拷贝,将文件从服务器端拷贝到浏览器端。

所以文件下载需要IO技术将服务器端的文件使用InputStream读取到,

再使用ServletOutputStream写到response缓冲区中。

例:

建一个download.jsp

提供下载,需要设置两个响应头,告知浏览器文件的类型和文件的打开方式:

1)告知浏览器文件的类型:response.setContentType(文件的MIME类型);

  用ServletContext对象的getMimeType()方法获取MIME类型

2)告示浏览器文件的打开方式是下载:

  response.setHeader("Content-Disposition","attachment;filename=文件名称");

把文件名改成中文

 

这里也改了:

 

打断点查看一下:

用debug模式(服务器上右键---Debug)查看

 

解决方式:

filename = new String(filename.getBytes("ISO8859-1"), "utf-8");

但是,没有名字

 

这是因为如果下载中文文件,页面在下载时会出现中文乱码或不能显示文件名的情况,

原因是不同的浏览器默认对下载文件的编码方式不同,ieUTF-8编码方式,而火狐浏览器是Base64编码方式。所里这里需要解决浏览器兼容性问题。

解决浏览器兼容性问题的首要任务是要辨别访问者是ie还是火狐(其他),通过Http请求体中的一个属性可以辨别(代码不用记,直接复制)。

完整代码:

public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 获取要下载的文件名称
        String filename = request.getParameter("filename");
        // 解决request对象中get方式中文乱码
        filename = new String(filename.getBytes("ISO8859-1"), "utf-8");
        // 获取User-Agent(哪个浏览器)
        String agent = request.getHeader("User-Agent");
        // 根据不同浏览器对文件进行不同编码
        String filenameEncoder = "";
        if (agent.contains("MSIE")) {
            // IE浏览器
            filenameEncoder = URLEncoder.encode(filename, "utf-8");
            filenameEncoder = filenameEncoder.replace("+", " ");
        } else if (agent.contains("Firefox")) {
            // 火狐浏览器
            BASE64Encoder base64Encoder = new BASE64Encoder();
            filenameEncoder = "=?utf-8?B?" + base64Encoder.encode(filename.getBytes("utf-8")) + "?=";
        } else {
            // 其它浏览器
            filenameEncoder = URLEncoder.encode(filename, "utf-8");
        }

        // 告知客户端浏览器该文件的MIME类型
        String filemime = getServletContext().getMimeType(filename);
        response.setContentType(filemime);
        // 告示浏览器文件的打开方式是下载
        response.setHeader("Content-Disposition", "attachment;filename=" + filenameEncoder); // 这里原来是filename,改成filenameEncoder

        // 获取文件在服务器上的绝对路径
        String realpath = getServletContext().getRealPath("download/" + filename);
        // 获取文件输入流(数据源)
        FileInputStream fis = new FileInputStream(realpath);
        // 获得输出流(目的地)
        ServletOutputStream out = response.getOutputStream();
        // 文件复制
        int len = 0;
        byte[] bytes = new byte[1024];
        while ((len = fis.read(bytes)) != -1) {
            out.write(bytes, 0, len);
        }
        // 释放资源
        fis.close();
    }

 

5.5验证码

 

1)将写好的验证码成生图片Servlet文件 CheckImgServlet复制到项目中

2)验证码数据new_words.txt放在WEB-INF里(为了外部访问不到)

3)配置web.xml

 

4)建一个register.jsp

文件目录如下:

  

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<script>
    function checkImg(obj) {
        obj.src = "/20190109WEB/CheckImgServlet?time="+new Date().getTime();
    }
</script>
</head>
<body>
    <form action="#" method="post">
        用户名:<input type="text" name="username" /><br /> 密码:<input
            type="password" name="password" /><br /> 验证码:<input type="text"
            name="code" /> <img src="/20190109WEB/CheckImgServlet"
            onclick="checkImg(this)" /><br /> <input type="submit" value="提交" />
    </form>
</body>
</html>

 

每点击图片一次,就换一张图片。

6 response细节点

1response获得的流不需要手动关闭,web容器(tomcat容器)会关闭

2getWritergetOutputStream不能同时调用

  

3)重定向语句一般作为终结代码

因为都跳走了,下面的代码不会执行了。

重点总结:

1设置响应行:

设置状态码setStatus

2添加响应头:addHeader

3设置响应头: 1定时刷新的头response.setHeader("refresh", "5;url=完整网址");

2用js方式实现

4重定向(用方法)sendRedirect

5字符流:解决响应时中文乱码问题(用方法)

response.setContentType("text/html;charset=utf-8");

6字节流两个例子:

文件下载:就是文件复制的基础上,加上下载方式和解决中文乱码和编码解析等问题

验证码:注意拷贝过来servlet后,配置web.xml。图片点击更新因为缓存问题,加一个毫秒值做为参数

原文地址:https://www.cnblogs.com/hzhjxx/p/10256307.html