How to make “Save As” window pop up when downloadi

2019-07-31 12:29发布

问题:

I'm currently implementing the ability to download uploaded files.

The function works well, The "Save As" window does not appear.

I will attach the code that performs the download function.

DownLoadView.java

public class DownLoadView extends AbstractView
{
    private File file;

    public  DownLoadView(File file)
    {
        setContentType("application/octet-stream");
        this.file = file;
    }

    @Override
    protected void renderMergedOutputModel(Map<String, Object> arg0, HttpServletRequest req, HttpServletResponse resp)
            throws Exception
    {
        resp.setContentType(getContentType());
        resp.setContentLength((int) file.length());
        System.out.println("getContentType >> " + resp.getContentType());
        String userAgent = req.getHeader("User-Agent");

        boolean ie = userAgent.indexOf("MSIE") > -1;

        String fileName = file.getName();

        if(ie)
        {
            fileName = URLEncoder.encode(file.getName(), "utf-8").replaceAll("\\+", "%20");
        }
        else
        {
            fileName = new String(file.getName().getBytes("utf-8")).replaceAll("\\+", "%20");
        }

        resp.setHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\"");

        OutputStream out = resp.getOutputStream();
        FileInputStream fis = null;

        System.out.println("resp : " + resp);

        try
        {
            fis = new FileInputStream(file);
            FileCopyUtils.copy(fis, out);
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
        finally 
        {
            if(fis != null)
            {
                try 
                {
                    fis.close();
                }
                catch(Exception e)
                {
                    e.printStackTrace();
                }
            }       
        }
        out.flush();
    }
}

I studied MIME-TYPE and Content-Type to implement the file download function.

As a result, as far as I can tell, To perform the "Save As" function,

  resp.setHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\"");

I found that you need to set the "Content-Disposition".

I set it as it is, but the "Save As" window does not appear. (When I open your browser with Chrome)

As a result of taking a log of ContentType,

getContentType >> application/octet-stream;charset=UTF-8

I confirmed that it is set like the above log.

I set something wrong and the "Save As" window does not pop up?

I would appreciate it if you could tell me what went wrong.

Oh, and one more question.

To test these things, I tried to download files from Microsoft Edge browser and firefox browser.

For Edge, the "Save As" window opens!

And for fire fox, the "Save As" window does not appear. However, a check window is opened for whether to open or save the file.

Is this because of the properties that each browser has?

  1. Why does not the "Save As" window appear on my logic?
  2. Why do I get a file download window for each browser type when I download a file?

回答1:

As far as I know, the Open/Save As dialogue is what happens by default. And I think, there is no point in trying to force anything. It's a browser settings that you cant change on the client side.

With 'Save As' dialogue, only 2 things can be done.

  • Change the download file name, type, extension..
  • Choose the download folder

In the current code, we can always specify the file name and extension(test.txt,test.jpeg,test.xls,...)

response.setHeader("Content-Disposition","attachment; filename=test.txt");

The following program worked for me in every browser with its own settings

@RequestMapping("/downloadFile")
public ModelAndView writeFileContentInResponse(HttpServletResponse response) throws IOException {
 FileInputStream inputStream = new FileInputStream("Fullfilepathto/test.txt"); 
 response.setHeader("Content-Disposition","attachment; filename=test.txt");
        try {
            int c;
            while ((c = inputStream.read()) != -1) {
            response.getWriter().write(c);
            }
        } finally {
            if (inputStream != null) 
                inputStream.close();
                response.getWriter().close();
        }
        return "index";
        }