【问题标题】:How to redirect file to another spring controller?如何将文件重定向到另一个弹簧控制器?
【发布时间】:2015-11-12 10:10:30
【问题描述】:

我有以下控制器方法:

  @RequestMapping(value = { "/member/uploadExternalImage",
            "/member/uploadExternalImage" }, method = RequestMethod.GET)
    public String handleFileUpload(@RequestParam String url, RedirectAttributes redirectAttributes
    ) throws IOException {
        byte[] binaryFile = IOUtils.toByteArray(
                new URL(url)
                        .openStream());

        File file = File.createTempFile("tmp", ".txt", new File(System.getProperty("user.dir")));
        FileUtils.writeByteArrayToFile(file, binaryFile);
        redirectAttributes.addFlashAttribute(file);
        return "redirect:/member/uploadImage";
    }

在这里我得到外部链接,通过这个链接下载文件并将其重定向到另一个控制器:

看起来像这样:

@RequestMapping(value = { "/member/createCompany/uploadImage",
            "/member/uploadImage" })
    @ResponseBody
    public ResponseEntity<String> handleFileUpload(@Validated MultipartFileWrapper file,
            BindingResult result, Principal principal) throws IOException {

MultipartFileWrapper:

@Component
public class MultipartFileWrapper {
    @Extensions(imageFormats = {".jpg",".png",".gif",".bmp"}, videoFormats = {".mp4",".mov"})
    MultipartFile multipartFile;
    ...
}

但是重定向没有正确发生。它在验证时中断。接受的 multipartFile 为 null。

如何解决?

附言

我试过了

File file = File.createTempFile("tmp", ".jpg", new File(System.getProperty("user.dir")));
        FileUtils.writeByteArrayToFile(file, binaryFile);
        FileItem fileItem = new DiskFileItem("trololo", ".jpg", false, "fileName", 1024_000_0, file);
        fileItem.getOutputStream();
        fileItem.getInputStream();
        MultipartFile multipartFile = new CommonsMultipartFile(fileItem);
        MultipartFileWrapper wrapper = new MultipartFileWrapper();
        wrapper.setMultipartFile(multipartFile);
        redirectAttributes.addFlashAttribute(wrapper);
        return "redirect:/member/uploadImage";

它重定向正确但大小等于0

【问题讨论】:

    标签: java file spring-mvc redirect multipart


    【解决方案1】:

    我相信 multipartFile 为空,因为它在请求中不存在。您将文件属性添加到重定向属性,但不会绑定到 MultipartFileWrapper。

    尝试在重定向之前将您的文件包装在 CommonsMultipartFile 或 MockMultipartFile 中。这显然是一个糟糕的建议,因为这不是多格式请求,也不会发生绑定。

    最好的办法是直接处理文件内容或创建一个单独的方法来处理来自外部下载或用户上传的文件内容。然后,您可以将文件添加为 flash 属性,并从您的两个 handleFileUpload 方法重定向到此方法。

    在常用方法中,您必须从模型中获取文件实例。 (就像 Serge Ballesta 所描述的那样)

    【讨论】:

    • 我已经更新了我的答案,并注意尝试包装文件是一个糟糕的建议。
    【解决方案2】:

    您添加一个File 对象作为flash 属性。因此,您将在模型中为重定向请求获取它。但我无法想象您如何在用于上传文件的MultipartFile 中获得它。恕我直言,您的第二个控制器应该是:

    @RequestMapping(value = { "/member/createCompany/uploadImage",
                "/member/uploadImage" })
        @ResponseBody
        public ResponseEntity<String> handleFileUpload(Model model, Principal principal) throws IOException {
            File file = (File) model.getAttribute("file");
            ...
    

    【讨论】:

    • 我明白了,重定向前文件大小等于 0
    • @gstackoverflow:我已阅读,但无法理解您要实现的目标。为什么您尝试将 MultipartFile 用于未上传的文件?为什么不能直接使用 binaryFile 中的 File 对象或(甚至更好)其内容?
    【解决方案3】:

    如下面代码sn-p所示,只需从输入流中读取文件,写入输出流即可,

    final File TEST_FILE = new File("C:/Users/arrows.gif");
        final DiskFileItem diskFileItem = new DiskFileItem("file", "image/jpeg", true, TEST_FILE.getName(), 100000000, TEST_FILE.getParentFile());
        InputStream input =  new FileInputStream(TEST_FILE);
        OutputStream os = diskFileItem.getOutputStream();
        int ret = input.read();
        while ( ret != -1 )
        {
          os.write(ret);
          ret = input.read();
        }
        os.flush();
    
        MultipartFile multipartFile = new CommonsMultipartFile(diskFileItem);
        redirectAttributes.addFlashAttribute("multipartFile", multipartFile);
    
        return "redirect:request2";
    

    在“request2”映射方法中,从模型映射中获取即可,

    我希望它能解决问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-11
      相关资源
      最近更新 更多