小编典典

配置Spring MVC控制器将文件发送到客户端

java

我认为我的情况很普遍。我有一个数据库,我希望我的Spring MVC应用程序在控制器中接受请求,调用DB服务以获取数据并将该数据作为CSV文件发送到客户端。我正在使用JavaCSV此处找到的库来协助完成此过程:http
:
//sourceforge.net/projects/javacsv/

我发现了一些人在做类似事情并将一些看起来正确的东西拼凑在一起的例子。但是,当我使用该方法时,实际上没有任何反应。

我以为将数据写入HttpServletResponse的outputStream就足够了,但是显然我缺少了一些东西。

这是我的控制器代码:

@RequestMapping(value="/getFullData.html", method = RequestMethod.GET)
public void getFullData(HttpSession session, HttpServletRequest request, HttpServletResponse response) throws IOException{
    List<CompositeRequirement> allRecords = compReqServ.getFullDataSet((String)session.getAttribute("currentProject"));

    response.setContentType("data:text/csv;charset=utf-8"); 
    response.setHeader("Content-Disposition","attachment; filename=\yourData.csv\"");
    OutputStream resOs= response.getOutputStream();  
    OutputStream buffOs= new BufferedOutputStream(resOs);   
    OutputStreamWriter outputwriter = new OutputStreamWriter(buffOs);

    CsvWriter writer = new CsvWriter(outputwriter, '\u0009');  
    for(int i=1;i <allRecords.size();i++){              
        CompositeRequirement aReq=allRecords.get(i);  
        writer.write(aReq.toString());  
    }     
    outputwriter.flush();   
    outputwriter.close();

};

我在这里错过了哪一步?基本上,最终结果是……什么都没有。我本来以为设置标题和内容类型会导致我的浏览器选择响应并触发文件下载操作。


阅读 209

收藏
2020-09-24

共1个答案

小编典典

似乎是因为您的Content-
type设置不正确,因此应response.setContentType("text/csv;charset=utf-8")改为response.setContentType("data:text/csv;charset=utf-8")

另外,如果您使用的是Spring 3,则可能应该使用@ResponseBody

HttpMessageConverter进行代码重用。例如:

  • 在控制器中:
        @RequestMapping(value = "/getFullData2.html", method = RequestMethod.GET, consumes = "text/csv")
    @ResponseBody // indicate to use a compatible HttpMessageConverter
    public CsvResponse getFullData(HttpSession session) throws IOException {
          List<CompositeRequirement> allRecords = compReqServ.getFullDataSet((String) session.getAttribute("currentProject"));
          return new CsvResponse(allRecords, "yourData.csv");
    }
  • 加上一个简单的HttpMessageConverter:
        public class CsvMessageConverter extends AbstractHttpMessageConverter<CsvResponse> {
       public static final MediaType MEDIA_TYPE = new MediaType("text", "csv", Charset.forName("utf-8"));
       public CsvMessageConverter() {
           super(MEDIA_TYPE);
       }

       protected boolean supports(Class<?> clazz) {
           return CsvResponse.class.equals(clazz);
       }

       protected void writeInternal(CsvResponse response, HttpOutputMessage output) throws IOException, HttpMessageNotWritableException {
           output.getHeaders().setContentType(MEDIA_TYPE);
           output.getHeaders().set("Content-Disposition", "attachment; filename=\"" + response.getFilename() + "\"");
           OutputStream out = output.getBody();
           CsvWriter writer = new CsvWriter(new OutputStreamWriter(out), '\u0009');
           List<CompositeRequirement> allRecords = response.getRecords();
           for (int i = 1; i < allRecords.size(); i++) {
                CompositeRequirement aReq = allRecords.get(i);
                writer.write(aReq.toString());
           }
           writer.close();
       }
    }
  • 和一个简单的对象将所有内容绑定在一起:
        public class CsvResponse {    
       private final String filename;
       private final List<CompositeRequirement> records;

       public CsvResponse(List<CompositeRequirement> records, String filename) {
           this.records = records;
           this.filename = filename;
       }
       public String getFilename() {
           return filename;
       }
       public List<CompositeRequirement> getRecords() {
           return records;
       }
    }
2020-09-24