在Java,Spring MVC中下载链接

时间:2016-07-28 12:09:22

标签: spring-mvc servlets download

我试图在我的网页中实现一个链接,以CSV格式下载文件。文件的内容被附加到stringbuffer并刷新以响应它自己。下面的代码是我试图实现的:

    public void getDownloadFile(HttpServletResponse response) throws IOException{
         response.setContentType("application/octet-stream");
            response.setHeader("Content-Disposition","attachment;filename=data.csv");
            ServletOutputStream out = response.getOutputStream();
            try{
            StringBuffer sb = generateCsvFileBuffer();          
            InputStream in =  new ByteArrayInputStream(sb.toString().getBytes("UTF-8"));
            byte[] outputByte = new byte[4096];

            while(in.read(outputByte, 0, 4096) != -1)
            {
                out.write(outputByte, 0, 4096);
            }
            in.close();
            out.flush();
            out.close();            
          }
        catch (Exception e) {
            System.out.println("Error in CsvFileWriter !!!");
            e.printStackTrace();
        } finally {
            try {
                out.flush();
                out.close();
            } catch (IOException e) {
                System.out.println("Error while flushing/closing fileWriter !!!");
                e.printStackTrace();
            }
        }
          return;
    }

调用的generateCsvFileBuffer()方法是写入文件详细信息的位置。方法如下:

public StringBuffer generateCsvFileBuffer(){
        StringBuffer writer = new StringBuffer();

        writer.append("name");
        writer.append(", ");
        writer.append("age");
        writer.append(", ");
        writer.append("address");
        writer.append(", ");
        writer.append("phone no");
        writer.append("\n");

        return writer;
    }

程序运行到最后一行代码,没有任何错误但没有输出。单击链接时,视图中没有任何反应。任何帮助都非常感谢。

1 个答案:

答案 0 :(得分:0)

我冒昧地使用Java 7的try-with-resources重写代码,以便更好地处理错误和可读性。

package demo.spring.mvc;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class FileDownloadController {

    @RequestMapping("/download")
    public void download(Model model, HttpServletResponse resp) {
        resp.setContentType("text/csv");
        resp.setHeader("Content-Disposition", "attachment;filename=data.csv");
        String csv = generateCsv();
        try (ServletOutputStream out = resp.getOutputStream();) {
            byte[] arr = new byte[4096];
            try (InputStream in = new ByteArrayInputStream(csv.getBytes("UTF-8"));) {
                for (int c; (c = in.read(arr)) != -1;) {
                    out.write(arr, 0, c);
                }
            }
        } catch (IOException e) {
            System.err.println("Error in CsvFileWriter!!!");
            e.printStackTrace();
        }
    }

    public String generateCsv() {
        StringBuilder sb = new StringBuilder();
        sb.append("name")
                .append(", ").append("age")
                .append(", ").append("address")
                .append(", ").append("phone no")
                .append("\n");
        return sb.toString();
    }

}

作为额外的奖励,这里有一些关于原始代码的想法。

  • 我将StringBuffer更改为StringBuilder。从Java 5开始,您可以通过将StringBuffer切换为未同步的对应StringBuilder来获得更好的性能。
  • 你的while循环有一个错误,因为你没有测试读取的字符数(我引入的c int)。
  • 您可以将调用链接到append(...),以避免重复应用该方法的变量名称。
  • 我从致电System.out切换到System.err来电,因为这里主要是错误处理。它远非完美。使用日志系统会让您感觉更好。