记一次response的坑:response.getWriter()失效问题

导读:本篇文章讲解 记一次response的坑:response.getWriter()失效问题,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

1.背景

在开发中,都规定好了后端返回数据的格式,当我们需要使用void作为controller的返回类型时,之前的返回格式就没办法使用了,但为了更灵活的返回数据,可以使用response.getWriter()去返回指定的数据,然后在使用response.getWriter()后,发现根本就不执行,直接抛出异常

2.问题

如下程序,很简单的逻辑,但是真正执行时,response.getWriter()这一句根本就没有执行,而且catch语句都不会进行,直接finally

记一次response的坑:response.getWriter()失效问题

3.原因

记一次response的坑:response.getWriter()失效问题 

该语句前使用了getOutputStream,就不能再用writer方式输出。只能使用一种

4.解决方案

4.1如果做的不是下载需求的话,删除getOutputStream即可

4.2一般在实际工作中,遇到这个问题,都是下载需求,因此getOutputStream不可省

可以继续利用response.getOutputStream()生成的OutputStreamWriter对象,把数据以JSON格式返回给前端,不能再使用writer对象进行回写!代码如下:

try(
    OutputStreamWriter writer =newOutputStreamWriter(outs,StandardCharsets.UTF_8);
   ) {
        //组装JSON
        Map<String, Object> map=new HashedMap<>();
        map.put("retCode", "9999");
        map.put("retMsg", "Excel下载失败:"+e.getMessage());
        String json = new ObjectMapper().writeValueAsString(map);
        writer.write(json);
        writer.flush();
     }catch (Exception e1) {
         throw new PortalException("response.getOutputStream()语句异常",e1);
     }

注意:outs对象是前面代码生成的,大致如下:

ServletOutputStream outs = response.getOutputStream();

5.易错点

在一次请求中,response是一次性的!当连接关闭,response就已经失效了!在我的代码中,由于response.getOutputStream()是用于处理下载的,而OutputStreamWriter是处理失败回写的,两个语句位于不同的代码块中,当我在调用response.getOutputStream()去处理下载后,调用以下代码进行关闭流:

outs.close();

由于关闭流与OutputStreamWriter失败回写不在同一层次,运行到outs.close()时,response也随之失效了,可以理解为“这一次请求已经结束了!”,因此,后续在调用回写代码时,导致回写失败:

OutputStreamWriter writer =newOutputStreamWriter(outs,StandardCharsets.UTF_8);

//outs来源于response.getOutputStream(),而response已经失效了

 解决办法:

生成outs对象并且关闭outs,与上述生成writer对象保持同一层次即可!

代码如下:

ServletOutputStream outs = response.getOutputStream();
try {
    response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
    response.setCharacterEncoding("utf-8");
    service.downExcel(outs);//业务代码
} catch (Exception e) {
    response.reset();
    response.setHeader("content-type", "text/html;charset=utf-8");
    try(
            OutputStreamWriter writer =newOutputStreamWriter(outs,StandardCharsets.UTF_8);
    ) {
        //组装JSON
        Map<String, Object> map=new HashedMap<>();
        map.put("retCode", "9999");
        map.put("retMsg", "Excel下载失败:"+e.getMessage());
        String json = new ObjectMapper().writeValueAsString(map);
        writer.write(json);
        writer.flush();
    } catch (Exception e1) {
        throw new PortalException("response.getOutputStream()语句异常",e1);
    }
}finally{
    //这里关闭流,与writer 对象保持同一级别,防止流关闭不去执行下载失败回调的代码
        outs.close();
}

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由半码博客整理,本文链接:https://www.bmabk.com/index.php/post/99609.html

(0)
小半的头像小半

相关推荐

半码博客——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!