AngularJS - Spring - 当查询结果为空时返回状态代码和文本



我有一个请求Spring Boot应用程序的AngularJS项目。

然后,Spring Boot 应用程序将以字节为单位返回数据,稍后可以将其下载为 Excel 文件,如下所示:

Spring 启动控制器应用程序:

public ResponseEntity generateExcelReport(@RequestBody ArrayList<SearchCriteria> searchCriteriaList) {
Query dynamicQuery = new Query();
HttpHeaders responseHeaders = new HttpHeaders();
responseHeaders.add("Content-Disposition", "attachment");
try {
List<Investment> resultList = investmentService.findByDynamicQuery(dynamicQuery);
Workbook workbook = myService.generateExcelReport(resultList);
ByteArrayOutputStream out = new ByteArrayOutputStream();
workbook.write(out);
byte[] bArray = out.toByteArray();
ByteArrayResource resource = new ByteArrayResource(bArray);
workbook.close();
out.close();
out.flush();
return ResponseEntity
.ok()
.headers(responseHeaders)
.contentLength(resource.getByteArray().length)
.contentType(MediaType.parseMediaType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"))
.body(resource);
} catch (IOException e) {
return ResponseEntity.badRequest().body(e);
}
}

但是我想通过返回状态为 204 的ResponseEntity来改进这段代码,如果resultList为空,如下所示:

更新:

public ResponseEntity generateExcelReport(@RequestBody ArrayList < SearchCriteria > searchCriteriaList) {
Query dynamicQuery = new Query();
HttpHeaders responseHeaders = new HttpHeaders();
responseHeaders.add("Content-Disposition", "attachment");
try {
List < Investment > resultList = investmentService.findByDynamicQuery(dynamicQuery);
// If there are no results found, throw a 204 No Content back to front-end
// So that there is no Excel generation involved.
if (resultList.isEmpty()) {
return ResponseEntity.status(HttpStatus.NO_CONTENT).body("There are no results found.");
}
...
return ResponseEntity
.ok()
.headers(responseHeaders)
.contentLength(resource.getByteArray().length)
.contentType(MediaType.parseMediaType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"))
.body(resource);
} catch (IOException e) {
return ResponseEntity.badRequest().body(e);
}
}

这是前端的 AngularJS 片段

ReportService.generateExcelReport($scope.searchCriteriaList)
.then(function (responseObj) {
if (responseObj.status === 204) {
return SweetAlert.swal("No results", responseObj.data, "warning");
} 
// responseObj.data = Excel bytes returned by Spring in this case
var blob = new Blob([responseObj.data], {
type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
});
FileSaver.saveAs(blob, "myreport.xlsx");
swal.close();
})

但我的问题是,我的 $http.post 请求包含一个responseType: "arraybuffer"作为请求的一部分。

正因为如此, 即使我在后端返回一个字符串,如下所示:

return ResponseEntity.status(HttpStatus.NO_CONTENT).body("There are no results found.");

我仍然在响应数据中得到一个数组缓冲区。而且我无法访问字符串。

$http.post 请求代码段:

generateExcelReport: function (searchCriteriaList) {
var requestConfig = {
responseType: "arraybuffer",
headers: {
"Content-Disposition": "attachment"
}
};
var url =  "my-api/generate-paiwi-reports-excel"
return $http.post(url, searchCriteriaList, requestConfig);
}

我不确定我是否进入了正确的方向。请帮忙。=) 提前非常感谢你。=)

我设法为这个解决方案提供了一个解决方案,但我不确定它是否是最适合这项工作的解决方案。

由于我仍然没有办法(我能想到)删除$http.post请求中的responseType: "arraybuffer",因此我将始终有一个arraybuffer作为对控制器的响应。

即使我只是从 Spring 后端返回一个字符串,我也会有一个 ArrayBuffer。

但值得庆幸的是,有一个名为TextDecoder的Web API,可以将我的ArrayBuffer响应解码为字符串。

我发现这一点要归功于 SO 中现有问题的答案。在字符串和数组缓冲区之间转换

这是我现在的整个代码:

弹簧后端;

List<Investment> resultList = investmentService.findByDynamicQuery(dynamicQuery);
// By throwing this HttpStatus, it will be in the .catch function of the Promise.
if (resultList.isEmpty()) {
return ResponseEntity
.status(HttpStatus.NOT_ACCEPTABLE)
.body("There are no results found.");
}

AngularJS 控制器:

// AngularJS $http.post request returns an httpPromise containing different properties        
ReportService.generateExcelReport($scope.searchCriteriaList)
.then(function(responseObj) {
var dateToday = ReportService.getFullDateToday();
var fileName = "MyReport_" + dateToday + ".xlsx";
// responseObj.data = Excel bytes returned by Spring in this case
var blob = new Blob([responseObj.data], {
type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
});
FileSaver.saveAs(blob, fileName);
swal.close();
})
.catch(function(error) {
// I forced Spring to throw a 406 - Not Acceptable error when mongoDB query result is 0.
if (error.status === 406) {
var decoder = new TextDecoder("utf-8");
var errorMessage = decoder.decode(error.data);
return SweetAlert.swal("No Results", errorMessage, "warning");
}
console.error(error);
SweetAlert.swal("Ooops!", "Something went wrong...", "error");
})

最新更新