我认为我的情况很常见。我有一个数据库,我希望我的 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/