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

本文介绍了配置 Spring MVC 控制器以将文件发送到客户端的处理方法,对大家解决问题具有一定的参考价值

问题描述

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

I think my scenario is pretty common. I have a database and I want my Spring MVC app to accept a request in the controller, invoke the DB service to get data and send that data to the client as a CSV file. I'm using the JavaCSV library found here to assist in the process: http://sourceforge.net/projects/javacsv/

我发现了几个人们做类似事情并拼凑出看起来正确的东西的例子.但是,当我点击该方法时,实际上什么也没发生.

I've found several examples of people doing similar things and cobbled together something that looks correct-ish. When I hit the method, though, nothing is really happening.

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

I thought writing the data to the HttpServletResponse's outputStream would be sufficient, but apparently, I'm missing something.

这是我的控制器代码:

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

};

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

What step am I missing here? Basically, the net effect is... nothing. I would have thought setting the header and content type would cause my browser to pick up on the response and trigger a file download action.

推荐答案

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

It seems to be because your Content-type is set incorrectly, it should be response.setContentType("text/csv;charset=utf-8") instead of response.setContentType("data:text/csv;charset=utf-8").

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

Additionally, if you are using Spring 3, you should probably use a @ResponseBody HttpMessageConverter for code reuse. For example:

  • 在控制器中:

  • In the 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:

  • plus a simple 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();
       }
    }
    

  • 和一个将所有内容绑定在一起的简单对象:

  • and a simple object to bind everything together:

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

  • 这篇关于配置 Spring MVC 控制器以将文件发送到客户端的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,WP2

    admin_action_{$_REQUEST[‘action’]}

    do_action( "admin_action_{$_REQUEST[‘action’]}" )动作钩子::在发送“Action”请求变量时激发。Action Hook: Fires when an ‘action’ request variable is sent.目录锚点:#说明#源码说明(Description)钩子名称的动态部分$_REQUEST['action']引用从GET或POST请求派生的操作。源码(Source)更新版本源码位置使用被使用2.6.0 wp-admin/admin.php:...

    日期:2020-09-02 17:44:16 浏览:1159

    admin_footer-{$GLOBALS[‘hook_suffix’]}

    do_action( "admin_footer-{$GLOBALS[‘hook_suffix’]}", string $hook_suffix )操作挂钩:在默认页脚脚本之后打印脚本或数据。Action Hook: Print scripts or data after the default footer scripts.目录锚点:#说明#参数#源码说明(Description)钩子名的动态部分,$GLOBALS['hook_suffix']引用当前页的全局钩子后缀。参数(Parameters)参数类...

    日期:2020-09-02 17:44:20 浏览:1060

    customize_save_{$this->id_data[‘base’]}

    do_action( "customize_save_{$this-&gt;id_data[‘base’]}", WP_Customize_Setting $this )动作钩子::在调用WP_Customize_Setting::save()方法时激发。Action Hook: Fires when the WP_Customize_Setting::save() method is called.目录锚点:#说明#参数#源码说明(Description)钩子名称的动态部分,$this->id_data...

    日期:2020-08-15 15:47:24 浏览:800

    customize_value_{$this->id_data[‘base’]}

    apply_filters( "customize_value_{$this-&gt;id_data[‘base’]}", mixed $default )过滤器::过滤未作为主题模式或选项处理的自定义设置值。Filter Hook: Filter a Customize setting value not handled as a theme_mod or option.目录锚点:#说明#参数#源码说明(Description)钩子名称的动态部分,$this->id_date['base'],指的是设置...

    日期:2020-08-15 15:47:24 浏览:888

    get_comment_author_url

    过滤钩子:过滤评论作者的URL。Filter Hook: Filters the comment author’s URL.目录锚点:#源码源码(Source)更新版本源码位置使用被使用 wp-includes/comment-template.php:32610...

    日期:2020-08-10 23:06:14 浏览:925

    network_admin_edit_{$_GET[‘action’]}

    do_action( "network_admin_edit_{$_GET[‘action’]}" )操作挂钩:启动请求的处理程序操作。Action Hook: Fires the requested handler action.目录锚点:#说明#源码说明(Description)钩子名称的动态部分$u GET['action']引用请求的操作的名称。源码(Source)更新版本源码位置使用被使用3.1.0 wp-admin/network/edit.php:3600...

    日期:2020-08-02 09:56:09 浏览:873

    network_sites_updated_message_{$_GET[‘updated’]}

    apply_filters( "network_sites_updated_message_{$_GET[‘updated’]}", string $msg )筛选器挂钩:在网络管理中筛选特定的非默认站点更新消息。Filter Hook: Filters a specific, non-default site-updated message in the Network admin.目录锚点:#说明#参数#源码说明(Description)钩子名称的动态部分$_GET['updated']引用了非默认的...

    日期:2020-08-02 09:56:03 浏览:855

    pre_wp_is_site_initialized

    过滤器::过滤在访问数据库之前是否初始化站点的检查。Filter Hook: Filters the check for whether a site is initialized before the database is accessed.目录锚点:#源码源码(Source)更新版本源码位置使用被使用 wp-includes/ms-site.php:93910...

    日期:2020-07-29 10:15:38 浏览:825

    WordPress 的SEO 教学:如何在网站中加入关键字(Meta Keywords)与Meta 描述(Meta Description)?

    你想在WordPress 中添加关键字和meta 描述吗?关键字和meta 描述使你能够提高网站的SEO。在本文中,我们将向你展示如何在WordPress 中正确添加关键字和meta 描述。为什么要在WordPress 中添加关键字和Meta 描述?关键字和说明让搜寻引擎更了解您的帖子和页面的内容。关键词是人们寻找您发布的内容时,可能会搜索的重要词语或片语。而Meta Description则是对你的页面和文章的简要描述。如果你想要了解更多关于中继标签的资讯,可以参考Google的说明。Meta 关键字和描...

    日期:2020-10-03 21:18:25 浏览:1695

    谷歌的SEO是什么

    SEO (Search Engine Optimization)中文是搜寻引擎最佳化,意思近于「关键字自然排序」、「网站排名优化」。简言之,SEO是以搜索引擎(如Google、Bing)为曝光媒体的行销手法。例如搜寻「wordpress教学」,会看到本站的「WordPress教学:12个课程…」排行Google第一:关键字:wordpress教学、wordpress课程…若搜寻「网站架设」,则会看到另一个网页排名第1:关键字:网站架设、架站…以上两个网页,每月从搜寻引擎导入自然流量,达2万4千:每月「有机搜...

    日期:2020-10-30 17:23:57 浏览:1298