spring-boot - java.lang.IllegalStateException: getWriter() 已经为此响应调用过,甚至认为它只调用过一次
问题描述
我正在使用spring-boot
. 我想发送一个 CSV 作为响应的附件,我用它opencsv
来编写 bean 到响应。即使response.getWriter()
只调用一次,我也得到了这个异常。
在寻找解决方案时,我开始知道我们不能一起使用response.getWriter()
和response.getOutputStream()
。但这里不是这种情况。
我只打电话给 getWriter 一次。
opencsv
我还通过向它写入一个纯字符串来检查它是否是由于库,例如“名称,测试”。但仍然是同样的错误。所以这不是由于opencsv
任何一个。
private Pair<Boolean, String> writeCSVToResponse(List<QuestionDownloadResponse> qdrList, HttpServletResponse response) {
String fileName = new SimpleDateFormat("'CSV'yyyyMMddHHmmss'.csv'").format(new Date());
response.reset();
response.setContentType("application/csv");
response.setHeader(HttpHeaders.CONTENT_DISPOSITION,
"attachment; filename=\"" + fileName + "\"");
response.setCharacterEncoding("UTF-8");
//Find answer, for now we will return any if exists
try {
Writer writer = response.getWriter();
// Create Mapping Strategy to arrange the
// column name in order
final CustomCSVMappingStrategy<QuestionDownloadResponse> mappingStrategy = new CustomCSVMappingStrategy<>();
mappingStrategy.setType(QuestionDownloadResponse.class);
StatefulBeanToCsv<QuestionDownloadResponse> sbc = new StatefulBeanToCsvBuilder<QuestionDownloadResponse>(writer)
.withSeparator(CSVWriter.DEFAULT_SEPARATOR)
.withMappingStrategy(mappingStrategy)
.build();
sbc.write(qdrList);
} catch (IOException e) {
CMSQuestionServiceImpl.logger.error("Error in CSV IO operations", e);
return Pair.of(false, "Failed to Open file");
} catch (CsvDataTypeMismatchException | CsvRequiredFieldEmptyException e) {
CMSQuestionServiceImpl.logger.error("Error in CSV Write operation", e);
return Pair.of(false,"Failed to write in csv");
}
}
为什么会出现这个异常,即使 response.getWriter 只被调用一次。如何解决这个问题。
解决方案
我发现了这个问题。问题是我在控制器中发送了一个字符串(一条消息)作为响应,但在服务中,我正在发送一个附件。所以 getWriter() 被我第一次在服务中调用,第二次被 spring 调用来编写字符串类型的响应消息。解决方法:我将控制器中方法的返回类型设置为void
ex::
@GetMapping(value = "/downloadCSV")
public void downloadCSV(@RequestBody(required = false) List<Integer> items, HttpServletResponse response){
唯一的问题是,如果服务出现问题,您无法发送错误消息,并且还有其他替代方法可以克服它。
推荐阅读
- vue.js - Show images files using Vue.js
- google-tag-manager - ec.js 可以用服务器端 gtm 代理吗?
- drupal-8 - Drupal 仅在显示为页面但不在显示块中时提供选项卡菜单
- javascript - 坐标(纬度,语言)的任何地址?
- ruby - 在单例方法上使用 sorbet 接口抽象
- java - Springboot 获取 api 时间太长,同时多次点击
- javascript - 如何在 Android Esspresso Kakao 测试中点击 webview 按钮
- c# - .net 5 从 HttpRequest 中检索 HttpRequestMessage
- radio-group - 如何默认值 RadioGroup Chakra-ui
- python - io.UnsupportedOperation:不可写,无法写入 .py 文件