How to solve android retrofit post image error 500 - java

So I tried to upload image with multipart but i received 500 error code. I've tried it on postman and it worked well and it worked too with this code but without image. Am I wrong at multipart thing?
ApiService
Filepath
MediaType
Swagger

I think Scoped storage issue. Stream the file using input stream.
Try like below
contentResolver.openInputStream(it)?.use { inputStream ->
val tempFile = createTempFile(this, fileName, extension)
copyStreamToFile(it, tempFile)
val filePath = tempFile.absolutePath
val requestFile: RequestBody = File(filePath).asRequestBody(fileType?.toMediaTypeOrNull())
val body: MultipartBody.Part = MultipartBody.Part.createFormData("file", fileName, requestFile)
}

Related

How to integrate signed URL in java?

I am trying to useDOLBY.IO's media API to transcode and save the output file to cloud. I have two URLs {URL1:input to dolby; URL2: to store output from dolby}. And both the URLs are signed URLs from the same cloud.
I tried using some java code to accomplish this but in the end I still can't get the result.
Here is the code:
#PostMapping("/transcode")
public String Video_Transcode1() throws IOException, JSONException {
OkHttpClient client = new OkHttpClient();
String data=generate_Access_token( );
MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "{\"inputs\":[{\"source\":\"https://vb-object-storage.ap-south-1.linodeobjects.com/The%20Hindu%20Daily%20News%20Analysis%20__%203rd%20July%202022%20__%20UPSC%20Current%20Affairs%20__%20Prelims%20%2722%20%26%20Mains%20%2722%28360%29.mp4?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20220707T073322Z&X-Amz-SignedHeaders=host&X-Amz-Expires=604799&X-Amz-Credential=ZVADROBVHWLK1FOYT225%2F20220707%2Fap-south-1%2Fs3%2Faws4_request&X-Amz-Signature=0aa4b388ea3197dd8a03253f5f7313b4209b8acf5e0a4308dc5e543801d22c73\"}],\"outputs\":[{\"kind\":\"mp4\",\"destination\":\"https://vb-object-storage.ap-south-1.linodeobjects.com/The%20Hindu%20Daily%20News%20Analysis%20__%203rd%20July%202022%20__%20UPSC%20Current%20Affairs%20__%20Prelims%20%2722%20%26%20Mains%20%2722%28360%29.mp4?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20220707T073322Z&X-Amz-SignedHeaders=host&X-Amz-Expires=604799&X-Amz-Credential=ZVADROBVHWLK1FOYT225%2F20220707%2Fap-south-1%2Fs3%2Faws4_request&X-Amz-Signature=0aa4b388ea3197dd8a03253f5f7313b4209b8acf5e0a4308dc5e543801d22c73\"}]}");
Request request = new Request.Builder()
.url("https://api.dolby.com/media/transcode")
.post(body)
.addHeader("Accept", "application/json")
.addHeader("Content-Type", "application/json")
.addHeader("Authorization","Bearer "+data)
.build();
Response response = client.newCall(request).execute();
return response.toString();
}
Here the data is generated from another function (ie:Access token)
I have encoded two URLs as json here:
RequestBody body = RequestBody.create(mediaType, "{\"inputs\":[{\"source\":\"https://vb-object-storage.ap-south-1.linodeobjects.com/The%20Hindu%20Daily%20News%20Analysis%20__%203rd%20July%202022%20__%20UPSC%20Current%20Affairs%20__%20Prelims%20%2722%20%26%20Mains%20%2722%28360%29.mp4?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20220707T073322Z&X-Amz-SignedHeaders=host&X-Amz-Expires=604799&X-Amz-Credential=ZVADROBVHWLK1FOYT225%2F20220707%2Fap-south-1%2Fs3%2Faws4_request&X-Amz-Signature=0aa4b388ea3197dd8a03253f5f7313b4209b8acf5e0a4308dc5e543801d22c73\"}],\"outputs\":[{\"kind\":\"mp4\",\"destination\":\"https://vb-object-storage.ap-south-1.linodeobjects.com/The%20Hindu%20Daily%20News%20Analysis%20__%203rd%20July%202022%20__%20UPSC%20Current%20Affairs%20__%20Prelims%20%2722%20%26%20Mains%20%2722%28360%29.mp4?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20220707T073322Z&X-Amz-SignedHeaders=host&X-Amz-Expires=604799&X-Amz-Credential=ZVADROBVHWLK1FOYT225%2F20220707%2Fap-south-1%2Fs3%2Faws4_request&X-Amz-Signature=0aa4b388ea3197dd8a03253f5f7313b4209b8acf5e0a4308dc5e543801d22c73\"}]}");
Is there any look around to bring the solution.
it looks like both signed URLs might be GET urls?
For the Dolby.io Transcode API, your inputs should be GET signed urls and your outputs should be PUT signed URLs.
Additionally, it also looks like you are using the same input path/filename and output path/filename:
https://vb-object-storage.ap-south-1.linodeobjects.com/The%20Hindu%20Daily%20News%20Analysis%20__%203rd%20July%202022%20__%20UPSC%20Current%20Affairs%20__%20Prelims%20%2722%20%26%20Mains%20%2722%28360%29.mp4
You will want to use different paths for input and output, something like:
https://vb-object-storage.ap-south-1.linodeobjects.com/output/outputfile.mp4
(note the "output" added to the path and the change of the output filename)

Save a PDF generated by SpringBoot in Angular

I am trying to save a PDF using Angular and Spring Boot.
When I make an API call, my Java code is fetching the data from the database and transforming it to a byte-stream. This stream is sent as response.
if(format.equals(Constant.PDF_FORMAT)) {
ByteArrayInputStream stream = reportPDF.generateReportDocument(dtos);
HttpHeaders headers = new HttpHeaders();
headers.add("Content-Disposition", "inline; filename=report.pdf");
return ResponseEntity.ok()
.headers(headers)
.contentType(MediaType.APPLICATION_PDF)
.body(new InputStreamResource(stream));
}
I have to use this response and save the data into a PDF.
Component.ts
public getReports(type?: string): void {
this.params['expected-format'] = type;
if (type === 'json') {
this.Service.getPilotReports(this.params).subscribe((res) => {
this.reportsData = res;
this.pilotBankSpinnerService.closeSpinner();
});
} else {
this.Service.customGetForDownload(this.params).subscribe(
(data: Blob) => {
var file = new Blob([data], { type: 'application/pdf' });
var fileURL = URL.createObjectURL(file);
window.open(fileURL);
var a = document.createElement('a');
a.href = fileURL;
a.target = '_blank';
a.download = 'reports.pdf';
document.body.appendChild(a);
a.click();
},
(error) => {
console.log('getPDF error: ', error);
}
);
}
}
Service.ts
public customGetForDownload<blob, T>(url: string, params: any): any {
const headers = new HttpHeaders({ 'Content-Type': 'application/json', responseType: 'blob' });
const httpParams = this.http.constructParams(params);
const absoluteUrl = this.getAbsoluteUrl(url);
return this.httpClient.get(absoluteUrl, {
headers: headers,
params: httpParams,
responseType: 'blob' as 'json',
observe: 'response',
});
}
Though the file is getting saved. When I try to open the file, it says "Failed to load pdf document".
Syntax Issues
First I see a syntax error:
missing argument in method-call: ByteArrayInputStream stream = reportPDF.generateReportDocument(dtos, ); (after the comma)
With this syntax error you most likely receive a compilation-error on console.
Assume this is a lapse and you can fix it to something like ByteArrayInputStream stream = reportPDF.generateReportDocument(dtos); then it should compile.
Boots without errors? Then test the endpoint!
Assume further your server application boots and runs without errors, then you could test the HTTP-endpoint with a HTTP-call.
You can test using a HTTP-client like CURL, postman or maybe even a browser.
Then you should receive a response with HTTP status code 200 and the body containing the PDF-file as binary with MIME-type application/pdf and specified header Content-Dispositon.
The browser is expected to prompt you with a download-dialogue.
Responding with a binary in Spring
Your InputStreamResource is a valid way, but you should be confident when using it.
In a Spring controller method, you can return the binary data in different types:
ResponseEntity<byte[]> as byte-array
ResponseEntity<ByteArrayOutputStream> as stream (not input-stream for reading input)
ResponseEntity<Resource> as abstract binary content, see Spring's Resource
ResponseEntity<File> as entire file
See also
Spring boot Angular2 file download not working
PDF Blob is not showing content, Angular 2
Return generated pdf using spring MVC
There are also some response-directed ways especially in Spring:
return a InputStreamResource as you did
return a StreamingResponseBody is very convenient
write to a HttpServletResponse, probably the oldest way
See: How To Download A File Directly From URL In Spring Boot
From input to output
Remember: Input is for reading (e.g. from a request), output is for writing (e.g. to a response). So you need an output type, like byte[] or ByteArrayOutputStream etc for your response-body.
When reading input into ByteArrayInputStream stream you could copy from that input to an output-stream with e.g. Apache-Commons IOUtils: IOUtils.copy(in, out);.
Or simply return the byte-array: byte[] data = stream.readAllBytes();
See: Java InputStream to Byte Array and ByteBuffer | Baeldung

How do I save a large file from a URL to the local

I have tried this below code which is working fine with the small size files.
URL url = new URL(downloadLink);
ReadableByteChannel rbc = Channels.newChannel(url.openStream());
FileOutputStream fos = new FileOutputStream(newFile);
fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
fos.close();
rbc.close();
If the file is a large file, it is giving an error like :
java.io.IOException:Server returned HTTP response code: 400 for URL:https://dl.dropboxusercontent.com/1/view/79q8i6f9zqx7y2w/Paragliding in Himalayas.avi
Can anyone help me.
The URL you're trying to download is invalid. URLs can't contain spaces. You need to URL encode it:
https://dl.dropboxusercontent.com/1/view/79q8i6f9zqx7y2w/Paragliding%20in%20Himalayas.avi
Have a look at: how do I encode a complete http url String correctly?, for an approach to encoding the URL. Unfortunately, just using URLEncoder.encode() won't cut it, since it encodes slashes, etc.
You can hand this task over to Os itself by using DownloadManager
private fun startDownload(url: String) {
val request = DownloadManager.Request(Uri.parse(url))
request.allowScanningByMediaScanner()
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED)
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, url.substring(url.lastIndexOf("/")))
val dm = activity!!.getSystemService(DOWNLOAD_SERVICE) as DownloadManager
dm.enqueue(request)
Toast.makeText(getApplicationContext(), "Downloading File", Toast.LENGTH_LONG).show()
}

[Java][RestAssured] How to save application/octet-stream response as jpg image?

I want to download images from website using RestAssured. My code:
Response response = given()
.log().all()
.cookie(cookie)
.get(format(image_endpoint, "46581657"));
Endpoint returns status code 200 and image in "application/octet-stream" type. How can I save it as jpg file?
I have tried:
String bin = getImageResponse()
.prettyPrint();
saveFile("foto.jpg", bin); //this method only save string to file
But I cannot open jpg file. How can I save it?
MIME type application/octet-stream consists of bytes encoded in Base64. Use Base64 class for decoding.
private void saveFile(String path, String octetStream) throws IOException{
byte[] bytes = Base64.getDecoder().decode(octetStream);
try(FileOutputStream fos = new FileOutputStream(path)){
fos.write(bytes);
}
}
I know nothing about RestAssured, so maybe there is any way provided by framework.

PUT Method: Not able to send "fileName" form Data using Jersey API using java?

following is the code I have written to PUT a image to a jersey server.
byte[] img = image(file);// coverts file into byte strea
FormDataMultiPart form = new FormDataMultiPart();
form.field("fileName", file);
FormDataBodyPart fdp = new FormDataBodyPart("fileUpload",
new ByteArrayInputStream(img),
MediaType.APPLICATION_OCTET_STREAM_TYPE);
form.bodyPart(fdp);
ClientResponse rs = wr.type(MediaType.APPLICATION_FORM_URLENCODED).put(
ClientResponse.class, form);
When I am running the code, i am able to send the byte stream to the server, but its returning error that it is not able to find the filename i am providing in form.field, so returning a 400 bad request error?
i am not able to understand what i am missing here?
I was able to fix the my problem. I was not adding multipart. This link helped me
Following is what i did to replace the body-part definition
FormDataBodyPart f = new FormDataBodyPart(FormDataContentDisposition
.name("fileUpload").fileName(file).build(),
new ByteArrayInputStream(img),
MediaType.APPLICATION_OCTET_STREAM_TYPE);
MultiPart multiPart = new FormDataMultiPart().bodyPart(f);
ClientResponse rs = wr.type(MediaType.MULTIPART_FORM_DATA).put(
ClientResponse.class, multiPart);

Categories