HTTP设置响应状态response.setStatus(),解决异常不能抛出

当在HTTP响应中遇到异常时,response.setStatus()可以用来设置响应状态,确保异常信息能传递给前端。例如,通过流返回压缩文件,如果过程中抛出异常,前端可能无法捕获。此时,自定义响应状态和消息能够帮助正确反馈错误信息。另外,对于返回流类型的文件下载,若使用AjaxResult等统一返回封装类,可能会导致预设Content-Type不匹配的异常。解决方法是避免返回值,改为void类型。

HTTP设置响应状态response.setStatus(),解决异常不能抛出

如下列代码,一个压缩文件并将zip以流返回给前端,在过程中由于各种原因抛出了异常,但是前端并不能接收到这个异常,程序会继续走下去,比如下列代码中,图片出现问题之后,抛出异常,但是依然会将图片压缩并以流形式返回,返回一个损坏的zip。

 @RequestMapping(value = "down")
    public void down(HttpServletResponse response,Integer id) {
        List<String> link = supplyProductVariantService.downBaiDu(id);
        if (link == null) {
           throw new OperationException("图片发生异常");
        } else {
            String[] links = link.toArray(new String[]{});
            try {
                String downloadFilename = System.currentTimeMillis() + ".zip";//文件的名称
                downloadFilename = URLEncoder.encode(downloadFilename, "UTF-8");//转换中文否则可能会产生乱码
                response.setContentType("application/octet-stream");// 指明response的返回对象是文件流
                response.setHeader("Content-Disposition", "attachment;filename=" + downloadFilename);//默认显示的文件名
                ZipOutputStream zos = new ZipOutputStream(response.getOutputStream());
                for (int i = 0; i < links.length; i++) {
                    //URL url = new URL(links[i]);
                    zos.putNextEntry(new ZipEntry(i + ".jpg"));
                    //重定向 页面302 取图片地址
                    String header = HttpRequest.get(links[i]).execute().header("Location");
                    URL url = new URL(header);
                    InputStream fis = url.openConnection().getInputStream();
                    byte[] buffer = new byte[1024];
                    int r = 0;
                    while ((r = fis.read(buffer)) != -1) {
                        zos.write(buffer, 0, r);
                    }
                    fis.close();
                }
                zos.flush();
                zos.close();
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

我们可以自设响应状态以及响应信息,将信息以流形式返回给前端

     List<String> link = supplyProductVariantService.downBaiDu(id);
        if (link == null) {
            try {
                String data = "下载失败";
                response.setStatus(400);
                response.setHeader("content-type", "text/html;charset=UTF-8");//通过设置响应头控制浏览器以UTF-8的编码显示数据
                response.getOutputStream().write(data.getBytes("UTF-8"));
            } catch (Exception e) {
                e.printStackTrace();
            }
        } 

在这里插入图片描述
在这里插入图片描述

此外:

下载文件时,由于给前端返回的是流

response.setContentType("application/octet-stream");// 指明response的返回对象是文件流

No converter for [class xxx.Result] with preset Content-Type ‘application/octet-stream

而我们可能项目中会使用AjaxResult等一些统一返回封装类,这样会导致出现 预设内容类型为“多部分/表单数据”的[class xxx.Result]没有转换器 异常
在这里插入图片描述

解决办法:

  1. 不要返回值(void)

  2. response.setContentType("application/json;charset=utf-8");
    
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值