HttpServletResponse

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

service方法中的response的类型是ServletResponse,而doGet/doPost方法的response的类型是HttpServletResponse,HttpServletResponse是ServletResponse的子接口,功能和方法更加强大。

1.response的运行流程

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

1.通过response设置响应行

设置响应行的状态码

setStatus(int sc)

public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //相应行
        response.setStatus(404);
    }

2.通过response设置响应头

addHeader(String name, String value)

addIntHeader(String name, int value)

addDateHeader(String name, long date)

setHeader(String name, String value)//给头设置值

setDateHeader(String name, long date)

setIntHeader(String name, int value)

其中,add表示添加,而set表示设置

重定向需要:1.状态码:302

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

 MyServlet01直接跳转到MyServlet02

复制代码
public class MyServlet01 extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //response.setStatus(302);//设置状态码302
        //设置Location头
        //response.setHeader("Location","/Web03/MyServlet02" );
        //重定向
        response.sendRedirect("/Web03/MyServlet02");
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }
}
复制代码
复制代码
public class MyServlet02 extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.getWriter().write("hello dandan...");
    }

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

3.通过response设置响应体

设置定时刷新

复制代码
public class RefreshServlet extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //定时shuaxin 
        response.setHeader("Refresh","5;url=http://www.baidu.com");
    }

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

(1)响应体设置文本

PrintWriter getWriter()

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

 

关于设置中文的乱码问题

原因:response缓冲区的默认编码是iso8859-1,此码表中没有中文,可以通过     response的setCharacterEncoding(String charset) 设置response的编码

但我们发现客户端还是不能正常显示文字

原因:我们将response缓冲区的编码设置成UTF-8,但浏览器的默认编码是本地系     统的编码,因为我们都是中文系统,所以客户端浏览器的默认编码是GBK,我们可以   手动修改浏览器的编码是UTF-8。

我们还可以在代码中指定浏览器解析页面的编码方式,

通过response的setContentType(String type)方法指定页面解析时的编码是UTF-8

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

复制代码
public class BodyServlet extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //设置缓冲区的码表
        //response.setCharacterEncoding("utf-8");
        //设置浏览器解析码表
        response.setContentType("text/html;charset=utf-8");
        
        response.getWriter().write("你好");
    }

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

上面的代码不仅可以指定浏览器解析页面时的编码,同时也内含            setCharacterEncoding的功能,所以在实际开发中只要编写      response.setContentType("text/html;charset=UTF-8");就可以解决页面输出中文乱码问题。

(2)响应头设置字节

ServletOutputStream  getOutputStream()

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

1.案例-完成文件下载

文件下载的实质就是文件拷贝,将文件从服务器端拷贝到浏览器端。所以文件下载需     要IO技术将服务器端的文件使用InputStream读取到,在使用    ServletOutputStream写到response缓冲区中

上述代码可以将图片从服务器端传输到浏览器,但浏览器直接解析图片显示在页面上,  而不是提供下载,我们需要设置两个响应头,告知浏览器文件的类型和文件的打开方 式。

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

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

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

 

但是,如果下载中文文件,页面在下载时会出现中文乱码或不能显示文件名的情况,     原因是不同的浏览器默认对下载文件的编码方式不同,ie是UTF-8编码方式,而火狐     浏览器是Base64编码方式。所里这里需要解决浏览器兼容性问题,解决浏览器兼容   性问题的首要任务是要辨别访问者是ie还是火狐(其他),通过Http请求体中的一 个属性可以辨别

解决乱码方法如下(不要记忆--了解):

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");                   

}

其中agent就是请求头User-Agent的值

复制代码
public class DownloadServlet extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //获取文件名
        String filename=request.getParameter("filename");
        
        //解决中文乱码
        filename=new String(filename.getBytes("ISO-8859-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");                
                }
                
                
                
        //图片,txt下载
        //1.告知浏览器文件MIME类型
        response.setContentType(getServletContext().getMimeType(filename));
        
        //2.告知浏览器改文件的打开方式是以附件方式打开
        response.setHeader("Content-Disposition", "attachment;filename="+filenameEncoder);
        //获取文件绝对
        String path=getServletContext().getRealPath("download/"+filename);
        //明确数据源
        FileInputStream fis=new FileInputStream(path);
        //目的地
        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();
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }
}
复制代码
复制代码
<body>
<a href="/Web03/DownloadServlet?filename=小薯条.jpg">小薯条.jpg</a>
<a href="/Web03/DownloadServlet?filename=a.wmv">a.wmv</a>
<a href="/Web03/DownloadServlet?filename=a.zip">a.zip</a>
<a href="/Web03/DownloadServlet?filename=a.txt">a.txt</a>
</body>
复制代码

response细节点:

  1. response获得的流不需要手动关闭,web容器(tomcat容器)会帮助我们关闭,
  2. getWriter和getOutputStream不能同时调用
  3. 重定向语句一般作为终结代码
posted @ 2020-08-15 09:32  01zh  阅读(124)  评论(0编辑  收藏  举报