1.背景
在开发中,都规定好了后端返回数据的格式,当我们需要使用void作为controller的返回类型时,之前的返回格式就没办法使用了,但为了更灵活的返回数据,可以使用response.getWriter()去返回指定的数据,然后在使用response.getWriter()后,发现根本就不执行,直接抛出异常
2.问题
如下程序,很简单的逻辑,但是真正执行时,response.getWriter()这一句根本就没有执行,而且catch语句都不会进行,直接finally
3.原因
该语句前使用了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