使用 java 在基于 REST 的 web 服务中响应文件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12207103/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 08:02:31  来源:igfitidea点击:

File response in REST based webservice using java

javaspringrest

提问by user1332962

I am writing a REST webserivce using spring. I have to return back a file in the response.

我正在使用 spring 编写 REST webserivce。我必须在响应中返回一个文件。

Its a GET call and when the user enters the URL, the user should be shown with the download section in the browser.

它是一个 GET 调用,当用户输入 URL 时,应该会在浏览器中向用户显示下载部分。

I am not sure what should be the return type in the controller. Do i have to specify any content type i code?

我不确定控制器中的返回类型应该是什么。我是否必须指定我编码的任何内容类型?

采纳答案by user1332962

I used the below piece of code

我使用了下面的一段代码

    FileInputStream inputStream = new FileInputStream("FileInputStreamDemo.java");  //read the file

    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();
    }

This was found in one more thread

这是在另一个线程中找到的

how to write a file object on server response and without saving file on server?

如何在服务器响应上写入文件对象而不在服务器上保存文件?

回答by Anand

I had the similar requirement in my project. I used the below piece of code

我在我的项目中有类似的要求。我使用了下面的一段代码

@Controller
@RequestMapping("/reports")
public class ReportsController {

    protected static String PRODUCTIVITY_REPORT_FILE = "productivityReportFile";

    @Resource(name="propertyMap")
    protected Map<String, String> propertyMap;

    @RequestMapping(value="/cratl/productivity_report", method=RequestMethod.GET, produces="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
    public @ResponseBody byte[] getProductivityReport()
            throws Exception {
        byte[] reportBytes = null;
        try {
            File reportFile = new File(propertyMap.get(PRODUCTIVITY_REPORT_FILE));
            if (reportFile != null && reportFile.exists()) {
                InputStream reportInputStream = new FileInputStream(reportFile);
                long length = reportFile.length();
                reportBytes = new byte[(int)length];
                int offset = 0;
                int numRead = 0;
                while (offset < reportBytes.length
                       && (numRead = reportInputStream.read(reportBytes, offset, reportBytes.length-offset)) >= 0) {
                    offset += numRead;
                }
                if (offset < reportBytes.length) {
                    throw new Exception("Could not completely read file "+ reportFile.getName());
                }
                reportInputStream.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return reportBytes;
    }

I hope it helps you

我希望它能帮助你

回答by fonZ

Your controller method, which can have any name you want, returns a String with a url name that is defined in the views.xml that is defined for the view you want to load, the downloads section in this case. So your controller looks like this:

您的控制器方法(可以使用您想要的任何名称)返回一个字符串,该字符串带有在为您要加载的视图(在本例中为下载部分)定义的 views.xml 中定义的 url 名称。所以你的控制器看起来像这样:

@Controller
public class MyController {

    @RequestMapping(value = "/downloads", method = RequestMethod.GET)
    public String getDownloadSection() {
        System.out.println("getting downloads");
        return "downloads/index";
    }
}

Your views.xml should contain the tag:

你的 views.xml 应该包含标签:

<definition extends="default" name="downloads/index">
<put-attribute name="body" value="/WEB-INF/views/downloads/index.jspx"/>
</definition>

The extends="default"is a tile definition that should be in your layouts.xml

延伸=“默认”是一个平铺定义,应该是在你的layouts.xml

I think thats about it. If you do a GET request to //yoursite/downloads it should print the message.

我想就是这样。如果您对 //yoursite/downloads 发出 GET 请求,它应该打印该消息。

That should answer your question i hope :)

这应该能回答你的问题,我希望:)