弹出下载文件控制器中的重定向错误处理

时间:2014-12-05 20:23:34

标签: java spring jsp spring-mvc

This问题很好地解释了如何在春天编写下载文件控制器。 This问题很好地解释了无法使用response.sendRedirect()发送Post请求

我希望将用户重定向到同一页面,并显示导致文件下载错误的错误。这是工作流程

  1. 用户点击www.abc.com/index [控制器已映射/index.jsp并返回ModelAndView]
  2. 在此页面,我们有一个文件下载,其URL为www.abc.com/download?resource_id=123。 [控制器已映射/下载并返回void]
  3. 当文件下载出错时,应将用户重定向到www.abc.com/index,并显示错误信息。
  4. 当文件下载没有错误时,用户将停留在同一页面并显示文件下载对话框。
  5. 以下是转发代码段:

    @RequestMapping(/download)
    public void execute(@RequestParam(value = "resource_id" required = true) final String resource, final HttpServletRequest request, final HttpServletResponse response) {
        try {
            //some processing
        } catch {
            RequestDispatcher dispatcher = request.getRequestDispatcher("/index" + "?is_downloaded=false");
            dispatcher.forward(request, response)
        }
    }
    
    @RequestMapping(/index)
    public void execute(@RequestParam(value = "is_downloaded" required = false) final String isDownloaded, final HttpServletRequest request) {
        //do stuff here
    }
    

    第3步是问题所在。

    • 使用转发功能会在发生错误时将网址更改为报告的下载网址。
    • 使用redirect作为具有隐藏参数的response.sendRedirect()是不可能的,根本不会修改URL。
    • 将redirect用作带有隐藏参数的response.sendRedirect(),并在网址末尾引入“?is_downloaded = false”

    任何人都可以告诉解决方法。

1 个答案:

答案 0 :(得分:1)

我遇到了类似问题,并使用以下代码解决了这个问题。

我的控制器中有以下异常处理程序。如果出现错误,则负责重定向和错误消息传递。

@ExceptionHandler(FileNotFoundException.class)
public ModelAndView exceptionHandler(Exception ex) {
    ModelAndView modelAndView = new ModelAndView();
    modelAndView.setViewName("rescues/general");
    modelAndView.addObject("message", ex.getMessage());
    return modelAndView;
}

这是RequestMapping

@RequestMapping(value = "s3Download.request", method = RequestMethod.GET)
@ResponseBody
public ResponseEntity<InputStreamResource> download(@RequestParam(value = "s3key") String s3Key)
        throws IOException {
    HttpHeaders responseHeaders = new HttpHeaders();
    InputStreamResource inputStreamResource = s3DownloadService.getS3File(s3Key, responseHeaders);
    return new ResponseEntity<>(inputStreamResource, responseHeaders, HttpStatus.OK);
}

如果文件在服务器上是本地文件,则可以使用FileSystemResource代替InputStreamResource。

服务层负责在HttpHeaders对象上设置响应头值

responseHeaders.setContentType(MediaType.parseMediaType(objectMetaData.getContentType()));
responseHeaders.setContentLength(objectMetaData.getContentLength());
responseHeaders.setContentDispositionFormData("attachment", fileName);