在春天从模型和视图下载文件

时间:2012-08-01 15:47:46

标签: java spring spring-mvc download

我正在尝试创建一个用户可以下载某个.log文件的页面。这是代码:

if(action.equalsIgnoreCase("download")){
       String file = (String)request.getParameter("file");
       response.setHeader("Content-Disposition",
       "attachment;filename="+file+"");
       response.setContentType("text/plain");

       File down_file = new File("log/"+file);

       FileInputStream fileIn = new FileInputStream(down_file);
       ServletOutputStream out = response.getOutputStream();

       byte[] outputByte = new byte[4096];
       //copy binary contect to output stream
       while(fileIn.read(outputByte, 0, 4096) != -1)
       {
        out.write(outputByte, 0, 4096);
       }
       fileIn.close();
       out.flush();
       out.close();

       return null;
}
我在哪里做错了? 当我点击下载按钮时,它正确地要求我保存文件,但它总是一个0字节的文件...

2 个答案:

答案 0 :(得分:5)

这应该做的工作:

public void getFile(final HttpServletResponse response) {
  String file = (String) request.getParameter("file");
  response.setHeader("Content-Disposition",
                     "attachment;filename=" + file);
  response.setContentType("text/plain");

  File down_file = new File("log/" + file);
  FileInputStream fileIn = new FileInputStream(down_file);
  ByteStreams.copy(fileIn, response.getOutputStream());
  response.flushBuffer();

  return null;
}

其中ByteStreams.copy来自精彩的Google's Guava library

修改

另外,如果你使用的是Spring MVC 3.1,你可以用更干净的方式(我就是这样做,结果是单行;)):

@Controller
public final class TestController extends BaseController {

    @RequestMapping(value = "/some/url/for/downloading/files/{file}",
                    produces = "text/plain")
    @ResponseBody
    public byte[] getFile(@PathVariable final String file) throws IOException {
        return Files.toByteArray(new File("log/" + file));
    }

}

并在servlet.xml添加转换器到mvc:message-converters

<mvc:annotation-driven>
    <mvc:message-converters>
        <bean class="org.springframework.http.converter.ByteArrayHttpMessageConverter" />
    </mvc:message-converters>
</mvc:annotation-driven>

这样您就可以使用byte[]注释的任何@Controller方法返回@ResponseBody。阅读更多herehere

Files.toByteArray也来自番石榴。

答案 1 :(得分:2)

尝试:

IOUtils.copy(fileIn, response.getOutputStream());
response.flushBuffer();

您可以在此处找到Apache Commons IO:http://commons.apache.org/io/

Here您找到IOUtils.copy()参考。