I'm trying to implement a gradle task to upload an APK file to my web service using http-builder-ng. I'm struggling with the encoding part.
An APK file effectively is a ZIP format file, so I tried using the content type application/zip but it's not recognized by the encoders provided:
task publish(...) {
// ...
post {
request.contentType = 'multipart/form-data'
request.encoder 'multipart/form-data', OkHttpEncoders.&multipart
request.body = multipart {
part 'file', 'myApp.apk', 'application/zip', new File(System.getProperty('user.dir'), 'myApp.apk')
}
response.success { fs, content ->
prinln "success"
}
}
}
The error message is following:
Could not find encoder for content-type (application/zip)
Can anybody help me which encoder to use and how?
Related
I have a simple API function to upload a file similar to:
#PostMapping(value = "/documents",
consumes = {MediaType.MULTIPART_FORM_DATA_VALUE})
public Mono<ResponseEntity<String>> uploadDocument(#RequestPart Mono<FilePart> file){
return storeDocumentService
.upload(file)
.map(fileLocation->ResponseEntity.ok(fileLocation))
}
The code works ok and uploads the file. The problem comes when I want to make the response a bit better by returning the link to the uploaded file. For this I want to use HATEOAS 'org.springframework.boot:spring-boot-starter-hateoas'. As soon as I add the dependency 'org.springframework.boot:spring-boot-starter-hateoas' to my 'build.gradle' the endpoint stops working and I get a response:
{
"timestamp": "2023-02-20T04:28:10.620+00:00",
"status": 415,
"error": "Unsupported Media Type",
"path": "/documents"
}
and also I get in the logs:
2023-02-20T05:28:10.618+01:00 WARN 2993 --- [nio-8080-exec-4] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.web.HttpMediaTypeNotSupportedException: Content-Type 'application/pdf' is not supported]
It is important to point out that I upload a ".pdf" file with a header "Content-Type:multipart/form-data". And most important the only change in the working code and not working code is that i just add the dependency for HATEOAS 'org.springframework.boot:spring-boot-starter-hateoas'
For Uploading File We can easily use the type MultiPartFile , This will handles all the types of files and we can easily retrive the fileInputStream(data) from it.
The following code may helps you!..
#PostMapping("uploadExcelData")
public ResponseEntity<?> uploadExcelData(#RequestParam MultipartFile file) throws IOException {
List<...> dataList = fileHandling.convertFileAsJson(file);
if (!dataList.isEmpty()) {
return ....
} else {
return ResponseEntity.ok("No Records found !!");
}
}
I hope the above code will helps you to handle the File in the Endpoint.
I have a news aggregator site that grabs an image from a remote URL but the script is breaking with the following error when I try to crop the file after grabbing:
Expected the file at /home/vagrant/code/storage/media-library/temp/pemA8JMvkodnsavxgk5ZLXXHxeU3wo7n/tiny.jpg have mimetype image/jpeg, but found a file with mimetype image/png
I have no control over this image so I was wondering if there is a way to either correct the mimetype or to catch the error and remove the offending article?
Thanks in advance for your help
edit:
For clarity I am grabbing the image with:
$article->addMediaFromUrl($item['article']['image'])->toMediaCollection('article');
and then running:
$article->save();
The model has the following function:
public function registerMediaConversions(Media $media = null): void {
$this->addMediaConversion('listing')
->fit(Manipulations::FIT_CROP, 140, 140)
->performOnCollections('article');
}
To anyone struggling with this in the future, I solved this with:
try {
$article->save();
} catch (InvalidTinyJpg $e) {
echo "Skipped invalid file\n";
}
Hello i need to download an audio file from an external URL and it works but without the .mp3 extension, which is required for the player to recognize it, here is my code:
getAudio(token:String,interestPointId:string,link:string, audioId):string{
const downloadManager = new Downloader();
var path:string;
const imageDownloaderId = downloadManager.createDownload({
url:link
});
downloadManager
.start(imageDownloaderId, (progressData: ProgressEventData) => {
console.log(`Progress : ${progressData.value}%`);
console.log(`Current Size : ${progressData.currentSize}%`);
console.log(`Total Size : ${progressData.totalSize}%`);
console.log(`Download Speed in bytes : ${progressData.speed}%`);
})
.then((completed: DownloadEventData) => {
path=completed.path;
console.log(`Image : ${completed.path}`);
})
.catch(error => {
console.log(error.message);
});
return path;
}
is just a modified version from the example (https://market.nativescript.org/plugins/nativescript-downloader)
the goal is to download the file and get the path to it while the name should be something like ~path/idAudio.mp3
any help is welcome, thanks in advance!
You can set the fileName and the path on the createDownload it is not documented (I forgot) there is interface you can use so what you need to is the following also i would recommend you not try to save the file to the project root e.g ~/blah/blah.mp3 that would fail on a real ios device
downloadManager.createDownload({
url:link
path:somePath,
fileName: 'idAudio.mp3'
}
In a project I want to upload video. in my request I use 'path' => 'mimes:mp4,mov,avi,mpg,mpeg;quicktime|nullable',
When uploading a .mov video I always get the error "The video path must be a file of type: mp4, mov, avi, mpg, mpeg, quicktime.". The meme type of the video is video/quicktime.
Uploading .mp4 files works perfect, didn't test with other video types yet. Does anyone have a solution?
You can manually check for mime-type if the validation is not working for you:
$video = Input::file('path');
$mime = $video->getMimeType();
$accepted_mimes = array("video/x-flv", "video/mp4", "application/x-mpegURL",
"video/MP2T", "video/3gpp", "video/quicktime",
"video/x-msvideo", "video/x-ms-wmv");
if(in_array($mime, $accepted_mimes)) {
//valid video format begin upload
} else {
//invalid video mime type
// return back with errors
return redirect->back()->withErrors(['msg', 'Invalid video']);
}
For a list of all available mime-types see here
.mov Is just a container. So maybe the mime type / codec is still wrong. You should first verify this with a tool like this: https://mediaarea.net/. As a solution to you problem however (which is less secure) you could only verify the extension (pathname).
Here you see an example of a .mxf file but with an MPEG codec to help you understand that containers do not have only one mime type (and codec) that belongs to it most of the time.
Warning for just validating file extensions: this is very insecure and could lead to all kinds of trouble. Like people uploading php files or other type of files.
$Video= request('PostDetailsVideo');//this is name of posted file
$rules=[
'PostDetailsVideo' => 'required|mimetypes:video/x-ms-wmv,video/x-msvideo,video/quicktime,video/3gpp,video/MP2T,application/x-mpegURL,video/mp4,video/x-flv|max:32768'
];
$CheckIsVideo = Validator::make($request->all(),$rules);
if($CheckIsVideo->fails()){//this not video
return response()->json([
'Success'=> false,
], 200);
}
else
return response()->json([
'Success'=> true,
], 200);
I have a REST endpoint that generates random images. I'm using Spring REST Docs, but the Response is all garbled in the http-response.adoc file. Is there an easy way for Mock MVC and REST Docs to store the file somewhere so my .adoc files can reference it?
Not the perfect but working solution:
class ImageSnippet implements Snippet {
private final String filePath;
public ImageSnippet(String filePath) {
this.filePath = filePath;
}
#Override
public void document(Operation operation) throws IOException {
byte[] picture = operation.getResponse().getContent();
Path path = Paths.get(filePath);
Files.deleteIfExists(path);
Files.createDirectories(path.getParent());
Files.createFile(path);
try (FileOutputStream fos = new FileOutputStream(path.toFile())) {
fos.write(picture);
}
}
}
And usage in MockMvc test (image folder path is important):
mockMvc.perform(get("/my-profile/barcode")
.accept(MediaType.IMAGE_PNG))
.andExpect(status().isOk())
.andDo(document("my-profile/barcode",
new ImageSnippet("build/asciidoc/html5/images/barcode.png")));
In .adoc template:
image::barcode.png[]
And here is my build.gradle Asciidoctor configuration (imagesdir is important):
asciidoctor {
dependsOn test
backends = ['html5']
options doctype: 'book'
attributes = [
'source-highlighter': 'highlightjs',
'imagesdir' : './images',
'toc' : 'left',
'toclevels' : 3,
'numbered' : '',
'icons' : 'font',
'setanchors' : '',
'idprefix' : '',
'idseparator' : '-',
'docinfo1' : '',
'safe-mode-unsafe' : '',
'allow-uri-read' : '',
'snippets' : snippetsDir,
linkattrs : true,
encoding : 'utf-8'
]
inputs.dir snippetsDir
outputDir 'build/asciidoc'
sourceDir 'src/docs/asciidoc'
sources {
include 'index.adoc'
}
}
What you can do is implement a custom Snippet which saves the resulting response. You can use the RestDocumentationContext attribute of the operation you receive to obtain the output directory.
mockMvc.perform(get("/example"))
.andDo(document("some-example", operation -> {
var context = (RestDocumentationContext) operation.getAttributes().get(RestDocumentationContext.class.getName());
var path = Paths.get(context.getOutputDirectory().getAbsolutePath(), operation.getName(), "response-file.png");
Files.createDirectories(path.getParent());
Files.write(path, operation.getResponse().getContent());
}));
However this will create a .png file in your output directory which generally isn't really useful if you have Asciidoc in a source directory that needs to embed it. So what you can instead do is create an Asciidoc file which contains custom HTML of an image tag with its source being a base64 representation of the response.
mockMvc.perform(get("/example"))
.andDo(document("some-example", operation -> {
var context = (RestDocumentationContext) operation.getAttributes().get(RestDocumentationContext.class.getName());
var path = Paths.get(context.getOutputDirectory().getAbsolutePath(), operation.getName(), "response-file.adoc");
var outputStream = new ByteArrayOutputStream();
outputStream.write("++++\n".getBytes());
outputStream.write("<img src=\"data:image/png;base64,".getBytes());
outputStream.write(Base64.getEncoder().encode(operation.getResponse().getContent()));
outputStream.write("\"/>\n".getBytes());
outputStream.write("++++\n".getBytes());
Files.createDirectories(path.getParent());
Files.write(path, outputStream.toByteArray());
}));
Although a bit more overhead in terms of space, if you use this, you don't need to mess with referencing build files from your sources.
An alternative way if you don't need/want to show the images in the docs: Use a ContentModifyingOperationPreprocessor to replace the bytes with some string that makes it clear to the readers of the documentation that there will be some image bytes in the response.
For example:
mockMvc.perform(get("/api/users/{id}/avatar", user.getId().asString())
.with(createCustomerAuth()))
.andExpect(status().isOk())
.andDo(document("get-user-avatar-example",
null,
Preprocessors.preprocessResponse(new ContentModifyingOperationPreprocessor(new ContentModifier() {
#Override
public byte[] modifyContent(byte[] originalContent, MediaType contentType) {
return "<< IMAGE BODY HERE >>".getBytes(StandardCharsets.UTF_8);
}
}))));
This generates an adoc file like this:
[source,http,options="nowrap"]
----
HTTP/1.1 200 OK
Content-Type: image/png
Content-Length: 15
Cache-Control: max-age=3600
<< IMAGE BODY HERE >>
----