java - 配置 Spring MVC Controller 以将文件发送到客户端

标签 java spring servlets file-io csv

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

我发现了几个人做类似事情的例子,然后拼凑出一些看起来很正确的东西。但是,当我点击该方法时,什么都没有发生。

我认为将数据写入 HttpServletResponse 的 outputStream 就足够了,但显然我遗漏了一些东西。

这是我的 Controller 代码:

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

};

我在这里缺少什么步骤?基本上,净效果是……什么都没有。我原以为设置标题和内容类型会导致我的浏览器接收响应并触发文件下载操作。

最佳答案

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

此外,如果您使用的是 Spring 3,您可能应该使用 @ResponseBody HttpMessageConverter用于代码重用。例如:

  • 在 Controller 中:

    @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();
       }
    }
    
  • 和一个简单的对象将所有东西绑定(bind)在一起:

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

关于java - 配置 Spring MVC Controller 以将文件发送到客户端,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9913732/

相关文章:

jquery - 处理spring请求中的数据表请求参数

java - Servlet Post 参数 : what case can a parameter have several values?

java - 使用 keycloak 在 servlet 应用程序中获取用户角色

java - 如何编写可维护的 merge() 方法?

java - 如何在android中创建年龄计算方法的方法

java - ResultSet 对象是什么样的?

java - OAuthException : Error validating verification code

java - 如何在以下代码中为回收器适配器设置点击监听器?

spring - 如何知道 PagingState 已经到达最后一页?

java - 从 http 链接映射 http 参数