Certainly! Here’s your question formatted for submission on Stack Overflow:
Description:
In my Java 8 Spring Boot application, I’m encountering an encoding issue with French characters. Specifically, the character ‘é’ is displayed as ‘Ac’ in downloaded file names and response headers. This issue persists even when inspecting the network trace in the browser. Below is the original code snippet:
Service Class:
public ResponseEntity<?> downloadReport(Long serviceId, Long reportId) throws Exception, IOException {
// Retrieve file details from cache
DownloadFileCache downloadFileCache = FileCacheUtil.getFileDetailsFromCache(reportId);
String reportStatus = "DOWNLOADED";
if (!ObjectUtils.isEmpty(downloadFileCache)) {
try {
// Get the file information based on documentId
String fileName = downloadFileCache.getFileName();
String path = downloadFileCache.getPath();
String actualFileName = null;
if (StringUtils.isBlank(path) || StringUtils.isBlank(fileName)) {
Status status = buildStatus(GetReportSchedulesRequestValidator.BAD_REQUEST_STATUS_CODE,
Severity.Error, "File not found.");
reportStatus = null;
throw new Exception(status);
}
if (StringUtils.isNotBlank(fileName)) {
actualFileName = fileName.substring(0, fileName.lastIndexOf("•"));
}
HttpHeaders httpHeaders = new HttpHeaders();
String mimeType = URLConnection.guessContentTypeFromName(actualFileName);
if (mimeType == null) {
mimeType = "application/octet-stream";
}
httpHeaders.set(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename="" + actualFileName + """);
httpHeaders.setContentType(MediaType.parseMediaType(mimeType));
if (StringUtils.isNotBlank(fileName) && fileName.contains("&")) {
fileName = fileName.replace("&", "%26");
}
Log.info("httpheaders- " + httpHeaders);
Log.debug("httpheaders= " + httpHeaders);
return ResponseEntity.ok()
.headers(httpHeaders)
.body(Client.download(path, fileName).getBody());
} catch (Exception e) {
Status status = buildStatus(GetReportSchedulesRequestValidator.BAD_REQUEST_STATUS_CODE,
Severity.Error, "File not found.");
reportStatus = null;
throw new Exception(status);
} finally {
if (StringUtils.isNotBlank(reportStatus)) {
updateDownloadStatus(reportId, serviceId, reportStatus);
}
}
}
return null; // Handle case when downloadFileCache is empty
}
Client Code:
public ResponseEntity<ByteArrayResource> download(String containerName, String blobName) throws Exception, IOException {
Log.trace("inside download documents");
RestRequestBuilder requestBuilder = RestRequestBuilder.getRequest()
.withPathSegment(containerName)
.withPathSegment(PREFIX)
.withQueryParam(BLOB, blobName);
return ResponseEntity.ok().body(callForEntity(requestBuilder, ByteArrayResource.class).getBody());
}
Original code works fine in Linux but it is not working in Microsoft cloud giving encoding issues.
Issue Resolution Attempt:
To address the encoding issue, I attempted to forcefully encode the file name using UTF-8 in the service class:
String encodedFilename = URLEncoder.encode(actualFileName, StandardCharsets.UTF_8.toString());
httpHeaders.set(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename="" + encodedFilename + """);
However, during debugging, I observed that with the original code, the request headers had the correct file name. But with the above approach, instead of spaces, ‘%c3%a9’ was added, and in the response dump, ‘CONTENT_DISPOSITION’ filename contained ‘Ac’ characters instead of the French character ‘é’.
I’m expecting this french character to be correctly displayed in downloaded file name