How can I fix this issue, when file download in the browser, it change encoding in file, I used Spring boot - spring

I used it code for response Excel byte[] to browser. But I have problem, because Spring boot encode file, and I got bad file than download from browser.
//This method returned response on controller
public ResponseEntity<ByteArrayResource>
returnAllTransactionAsExcel(TransactionSearchFilter
transactionSearchFilter) throws IOException {
List<Transaction> transactions =
getAllTransactions(transactionSearchFilter);
byte[] ourFile=writeIntoExcel(transactions);
//headers
HttpHeaders headers = new HttpHeaders();
headers.add("Pragma", "no-cache");
headers.add("Expires", "0");
headers.add("Content-Disposition", "attachment;
filename=list_transactions.xls");
headers.setCacheControl("must-revalidate, post-check=0, pre-check=0");
headers.setContentType(MediaType.parseMediaType("application/vnd.ms-excel"));
return
ResponseEntity
.ok()
.headers(headers)
.contentLength(ourFile.length)
.contentType(MediaType.parseMediaType("application/vnd.ms-excel"))
.body(new ByteArrayResource(ourFile));
}
//This method on controller
#ApiOperation(value = "Retrieve all transactions in Excel")
#RequestMapping(value = "/allExcel", method = RequestMethod.POST,
produces "application/vnd.ms-excel")
public ResponseEntity<ByteArrayResource>
getAllTransactionsAsExcel(#RequestBody TransactionSearchFilter
transactionSearchFilter) throws IOException {
return returnAllTransactionAsExcel(transactionSearchFilter);
}

I solved my problem, all problem was in swagger-ui
https://github.com/webanno/webanno/issues/459

Related

When trying to invoke rest API throws httpmediatypenotsupportedexception content type 'application/x-www-form-urlencoded' not supported

I am trying to invoke rest API below which consumes a multi-part file. First paramter is a MultipartFile and second is s String. and this functions processes some business logic
#PostMapping( value="/uploadFile", consumes = MediaType.MULTIPART_FORM_DATE_VALUE)
public ResponseEntity<String> upload(#RequestPart("file") MultipartFile file,
#RequestParam("path") String path){
//businness logic
}
Invoking above API from code below. But it throws
httpmediatypenotsupportedexception content type
'application/x-www-form-urlencoded' not supported. I have also tried
added header "Content-type", MediaType.MULTIPART_FORM_DATA_VALUE OR
"Content-Type", "multipart/form-data" OR "Accept",
"multipart/form-data" in the headers below, but that has not helped
either
public void uploadFile() {
Path path = Paths.get("C:/ABC.txt");
byte[] content = null;
try{
content = Files.readAllBytes(path); // All file is read in content variable
} catch(final IOException e){
}
MultipartFile file = new MockMultipartFile("ABC.txt",content);
UriComponentsBuilder urlBuilder = UriComponentsBuilder.fromHttpUrl(oauthURL);
urlBuilder.queryParam("file", file);
urlBuilder.queryParam("path", "/temp);
HttpHeaders headers = new HttpHeaders();
HttpEntity<String> response = null;
HttpEntity<?> entity = new HttpEntity<>(headers);
try{
response = restTemplate.exchange(urlBuilder.build().encode().toUri(), HttpMethod.POST, entity. String.class);
}
catch (Exception e){
}
}
}
Your server accepts (consumes) "multipart/form-data" however you are sending the file and path in the URL. This will always result in a "application/x-www-form-urlencoded".
So you need to change the server to accept it as you send them or send the file and path as the body (within the entity)
EDIT (some code to show how):
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.MULTIPART_FORM_DATA);
MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
body.add("file", file);
body.add("path","/temp");
HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(body, headers);
response = restTemplate.postForEntity(serverUrl, requestEntity, String.class);

Spring boot RestTemplate upload file to SharePoint online but file is corrupted

There is a RestController and I try to upload a MultiPartFile to SharePointOnline using, the SharePoint REST API I'm also using proxy due to corporate restrictions.
#Override
public ResponseEntity uploadFile(MultipartFile file) throws ApiException, IOException {
RestTemplate restTemplate = createBasicRestTemplate();
MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
body.add("file",file.getResource());
HttpHeaders header = new HttpHeaders();
header.setContentType(MediaType.MULTIPART_FORM_DATA);
HttpEntity<MultiValueMap<String, Object>> uploadBodyEntity = new HttpEntity<>(body, header);
ResponseEntity<String> response = restTemplate.exchange(BASE_URL, HttpMethod.POST,
uploadBodyEntity, String.class);
return response;
}
public RestTemplate createBasicRestTemplate() {
RestTemplate restTemplate = new RestTemplateBuilder(new ProxyCustomizer()).build();
return restTemplate;
}
#Override
public void customize(RestTemplate restTemplate) {
HttpHost proxy = new HttpHost(PROXY_HOST, PROXY_PORT);
HttpClient httpClient = HttpClientBuilder.create()
.setRoutePlanner(new DefaultProxyRoutePlanner(proxy) {
#Override
public HttpHost determineProxy(HttpHost target, HttpRequest request, HttpContext context) throws HttpException {
return super.determineProxy(target, request, context);
}
})
.build();
restTemplate.setRequestFactory(new HttpComponentsClientHttpRequestFactory(httpClient));
}
The file upload is success, but it's cannot be opened. For example if upload a txt it will looks like this:
--raF_ORlUJptia2_av7ppLBeeMcGf5BUr
Content-Disposition: form-data; name="file"; filename="test.txt"
Content-Type: text/plain
Content-Length: 159
--38dc5323d6b92b5c14c33fade0178306
Content-Disposition: form-data; name="file"; filename="test.txt"
blablalblalalal
--38dc5323d6b92b5c14c33fade0178306--
--raF_ORlUJptia2_av7ppLBeeMcGf5BUr--
If I upload an xlsx it's simply just not open, it shows 'File Format and Extension Don't Match' error.
I try to convert the MultiPartFile to simple File with this method:
public File convertFile(MultipartFile file) {
File convFile = new File(file.getOriginalFilename());
try {
convFile.createNewFile();
FileOutputStream fos = new FileOutputStream(convFile);
fos.write(file.getBytes());
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
return convFile;
}
and change the controller to:
MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
body.add("file",convertFile(file));
But the same thing happens.
How can I upload file with RestTemplate?
This is a sample request to the SharePoint REST API and based on documentation the endpoint should receive a array buffer
POST https://{site_url}/_api/web/GetFolderByServerRelativeUrl('/Folder Name')/Files/add(url='a.txt',overwrite=true)
Authorization: "Bearer " + accessToken
Content-Length: {length of request body as integer}
X-RequestDigest: "{form_digest_value}"
"Contents of file"
This is what i can see in the https log: http log
Solution was to remove MultiValueMap and replace with:
HttpEntity<byte[]> entity = new HttpEntity<>(file.getBytes(), spoHelperService.createAuthHeader(authToken));
ResponseEntity<SpoUploadResponse> response = restTemplate.exchange(uploadFileUrl, HttpMethod.POST,
entity, SpoUploadResponse.class);

Sending a multipart request using RestTemplate

I want to make a multipart request to some external API (created using Spring Boot) but all I get is Required request part 'file' is not present.
I know the source code of the external API but I can't modify it. It looks like this:
#PostMapping("/upload")
public ResponseEntity handleFileUpload(#RequestParam("file") MultipartFile file){
return ResponseEntity.ok().build();
}
And from my application I create and send requests exactly like on the following snippet:
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.MULTIPART_FORM_DATA);
MultiValueMap<String, Object> body
= new LinkedMultiValueMap<>();
body.add("file", "dupa".getBytes());
HttpEntity<MultiValueMap<String, Object>> requestEntity
= new HttpEntity<>(body, headers);
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<String> response = restTemplate
.postForEntity("http://api:8080/upload", requestEntity, String.class);
return response.getBody();
What's the reason it doesn't work? The above code rewritten using Apache HttpClient works like charm.
You basically have two options, the solution with byte array:
map.add("file", new ByteArrayResource(byteArrayContent) {
#Override
public String getFilename() {
return "yourFilename";
}
});
I remember having a problem with just adding a byte array, so you need to have a filename too and use ByteArrayResource.
Or adding a File:
map.add("file", new FileSystemResource(file));

Chrome generate two request

In a spring boot application a link generate a pdf file.
Link in thymeleaf
<a th:href="#{/printings/bytesttype/compressions}" class="list-group-item list-group-item-action"><span th:text="#{compressions}">Compressions</span></a>
On the controller side
#GetMapping(value = "/printings/bytesttype/compressions")
public ResponseEntity<byte[]> getCompressionsReport() throws IOException, Exception {
return preparePdfReport(samplingFacade.getCompressionToPrint());
}
private ResponseEntity<byte[]> preparePdfReport(byte[] content) throws IOException {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.parseMediaType("application/pdf"));
String fileName = "report.pdf";
headers.setContentDispositionFormData(fileName, fileName);
headers.setCacheControl("no-cache, must-revalidate, post-check=0, pre-check=0");
ResponseEntity<byte[]> response = new ResponseEntity<>(content, headers, HttpStatus.OK);
return response;
}
Actually user click, a request is done.
After another request is done to open with extension
chrome-extension://oemmndcbldboiebfnladdacbdfmadadm/http://localhost:8080/printings/bytesttype/compressions
Is there a way to avoid that?
tried
Chrome sends two requests when downloading a PDF (and cancels one of them)
problem still exist
If you dont have to show PDF with the extension (browser inline) you can try adding a header to your HTTP Response as follows:
response.setHeader("Content-Disposition", "attachment; filename=report.pdf");

Camel rest API to provide dynamic download

How can we provide document download using camel API, I need to provide an api using camel rest to response the file as download and I have the logic to create the pdf using apache fop, but i need to get some information how to respond the file as rest response using camel rest.
#RestController
public class MyController {
#Autowired
ICityService cityService;
#RequestMapping(
value = "/pdfreport",
method = RequestMethod.GET,
produces = MediaType.APPLICATION_PDF_VALUE
)
public ResponseEntity<InputStreamResource> citiesReport() throws IOException {
List<City> cities = (List<City>) cityService.findAll();
ByteArrayInputStream bis = GeneratePdfReport.citiesReport(cities);
HttpHeaders headers = new HttpHeaders();
headers.add("Content-Disposition", "inline;
filename = citiesreport.pdf");
return ResponseEntity
.ok()
.headers(headers)
.contentType(MediaType.APPLICATION_PDF)
.body(new InputStreamResource(bis));
}
}

Resources