How to upload a file and JSON data in Postman? - java

I am using Spring MVC and this is my method:
/**
* Upload single file using Spring Controller.
*/
#RequestMapping(value = "/uploadFile", method = RequestMethod.POST)
public #ResponseBody ResponseEntity<GenericResponseVO<? extends IServiceVO>> uploadFileHandler(
#RequestParam("name") String name,
#RequestParam("file") MultipartFile file,
HttpServletRequest request,
HttpServletResponse response) {
if (!file.isEmpty()) {
try {
byte[] bytes = file.getBytes();
// Creating the directory to store file
String rootPath = System.getProperty("catalina.home");
File dir = new File(rootPath + File.separator + "tmpFiles");
if (!dir.exists()) {
dir.mkdirs();
}
// Create the file on server
File serverFile = new File(dir.getAbsolutePath() + File.separator + name);
BufferedOutputStream stream = new BufferedOutputStream(new FileOutputStream(serverFile));
stream.write(bytes);
stream.close();
System.out.println("Server File Location=" + serverFile.getAbsolutePath());
return null;
} catch (Exception e) {
return null;
}
}
}
I need to pass the session id in postman and also the file. How can I do that?

In postman, set method type to POST.
Then select
Body -> form-data -> Enter your parameter name (file according to your code)
On the right side of the Key field, while hovering your mouse over it, there is a dropdown menu to select between Text/File. Select File, then a "Select Files" button will appear in the Value field.
For rest of "text" based parameters, you can post it like normally you do with postman. Just enter parameter name and select "text" from that right side dropdown menu and enter any value for it, hit send button. Your controller method should get called.

The Missing Visual Guide
You must first find the nearly-invisible pale-grey-on-white dropdown for File which is the magic key that unlocks the Choose Files button.
After you choose POST, then choose Body->form-data, then find the File dropdown, and then choose 'File', only then will the 'Choose Files' button magically appear:

Maybe you could do it this way:

Like this :
Body -> form-data -> select file
You must write "file" instead of "name"
Also you can send JSON data from Body -> raw field. (Just paste JSON string)

I got confused after seeing all of the answers, I couldn't find any proper screenshot to bring the Content Type column. After some time, I found it by my own. Hope this will help somebody like me.
Here is the steps:
click on red marked area of postman.
Now check the green marked option (Content Type).
Now change the search content type, in the yellow marked area.
In my case:
invoice_id_ls (key) contains the json data.
documents contains the file data.
placed_amount contains normal text string.

Select [Content Type] from [SHOW COLUMNS] then set content-type of "application/json" to the parameter of json text.

Don't give any headers.
Put your json data inside a .json file.
Select your both files one is your .txt file and other is .json file
for your request param keys.

If somebody wants to send json data in form-data format just need to declare the variables like this
Postman:
As you see, the description parameter will be in basic json format, result of that:
{ description: { spanish: 'hola', english: 'hello' } }

Kindly follow steps from top to bottom as shown in below image.
At third step you will find dropdown of type selection as shown in below image

Body > binary > Select File

If you need like
Upload file in multipart using form data and send json data(Dto object) in same POST Request
Get yor JSON object as String in Controller and make it Deserialize by adding this line
ContactDto contactDto = new ObjectMapper().readValue(yourJSONString, ContactDto.class);

If somebody needed:
body -> form-data
Add field name as array

Use below code in spring rest side :
#PostMapping(value = Constant.API_INITIAL + "/uploadFile")
public UploadFileResponse uploadFile(#RequestParam("file") MultipartFile file,String jsonFileVo) {
FileUploadVo fileUploadVo = null;
try {
fileUploadVo = new ObjectMapper().readValue(jsonFileVo, FileUploadVo.class);
} catch (Exception e) {
e.printStackTrace();
}

If you want to make a PUT request, just do everything as a POST request but add _method => PUT to your form-data parameters.

The way to send mulitpart data which containts a file with the json data is the following, we need to set the content-type of the respective json key fields to 'application/json' in the postman body tab like the following:

You can send both Image and optional/mandatory parameters.
In postman, there is Params tab.

I needed to pass both: a file and an integer. I did it this way:
needed to pass a file to upload:
did it as per Sumit's answer.
Request type : POST
Body -> form-data
under the heading KEY, entered the name of the variable ('file' in my backend code).
in the backend:
file = request.files['file']
Next to 'file', there's a drop-down box which allows you to choose between 'File' or 'Text'. Chose 'File' and under the heading VALUE, 'Select files' appeared. Clicked on this which opened a window to select the file.
2.
needed to pass an integer:
went to:
Params
entered variable name (e.g.: id) under KEY and its value (e.g.: 1) under VALUE
in the backend:
id = request.args.get('id')
Worked!

For each form data key you can set Content-Type, there is a postman button on the right to add the Content-Type column, and you don't have to parse a json from a string inside your Controller.

first, set post in method and fill link API
Then select Body -> form-data -> Enter your parameter name (file according to your code)

If you are using cookies to keep session, you can use interceptor to share cookies from browser to postman.
Also to upload a file you can use form-data tab under body tab on postman, In which you can provide data in key-value format and for each key you can select the type of value text/file. when you select file type option appeared to upload the file.

If you want the Id and File in one object you can add your request object to a method as standard and then within Postman set the Body to form-data and prefix your keys with your request object name. e.g. request.SessionId and request.File.

The steps of uploading a file through postman along with passing some input data is very well discussed in below blog along with the screenshot. In this blog, the api code is written in node js. You can go through it once to have more clarity.
https://jksnu.blogspot.com/2021/09/how-to-create-post-request-with.html

At Back-end part
Rest service in Controller will have mixed #RequestPart and MultipartFile to serve such Multipart + JSON request.
#RequestMapping(value = "/executesampleservice", method = RequestMethod.POST,
consumes = {"multipart/form-data"})
#ResponseBody
public boolean yourEndpointMethod(
#RequestPart("properties") #Valid ConnectionProperties properties,
#RequestPart("file") #Valid #NotNull #NotBlank MultipartFile file) {
return projectService.executeSampleService(properties, file);
}
At front-end :
formData = new FormData();
formData.append("file", document.forms[formName].file.files[0]);
formData.append('properties', new Blob([JSON.stringify({
"name": "root",
"password": "root"
})], {
type: "application/json"
}));
See in the image (POSTMAN request):
Click to view Postman request in form data for both file and json

To send image along with json data in postman you just have to follow the below steps .
Make your method to post in postman
go to the body section and click on form-data
provide your field name select file from the dropdown list as shown below
you can also provide your other fields .
now just write your image storing code in your controller as shown below .
postman :
my controller :
public function sendImage(Request $request)
{
$image=new ImgUpload;
if($request->hasfile('image'))
{
$file=$request->file('image');
$extension=$file->getClientOriginalExtension();
$filename=time().'.'.$extension;
$file->move('public/upload/userimg/',$filename);
$image->image=$filename;
}
else
{
return $request;
$image->image='';
}
$image->save();
return response()->json(['response'=>['code'=>'200','message'=>'image uploaded successfull']]);
}
That's it hope it will help you

Related

Sending dynamic fieldnames for RequestBody multipart/form-data in spring

I am currently doing an experiment to build the API which users can submit freely at their own will without restriction, no boundary on field names and the contents as well. And the API would just print out the inputs in a key,value pairs. For the files, I would just print out the whole bytes of the base64 converted of it.
For example, I have the request A like this:
{
"name": "John Doe",
"lucky_number": 75
}
Then the API will get the output:
Hello user, your first key is name and its value is John Doe, your next key is lucky_number and its value is 75. Thank you for using.
Then, I make another request with the fields below. The image actually was filled with actual image/jpg file.
"pokemon": "pikachu",
"image": <File>JFIFw9d1j3f0881ehfce0cn2e0f2
So, it will print out most likely:
Hello user, your first key is pokemon and its value is pikachi, your next key is image and its value is cApovnquGCaisa1b23IAbqxcaiFoPqR==. Thank you for using..
Can this actually be achieved? As for what I have known, I can make such dynamic request if the request body was formatted in JSON file that Spring can easily get it to the Java Object format. But what about this multipart? And as far as I know, I can get the multipart only with the defined fieldname, and this code below most likely can only handle one file with field file, but what if the user actually send 3 files or even more as there's no boundary as the expected behavior?
#PostMapping("/fun", consumes = { "multipart/mixed", "multipart/form-data" }, produces = {"text/plain"}
public String postForFun(#RequestPart("file") MultipartFile file, #RequestBody Object dynamicFields) {
}

Some problem Logic with response POST in spring boot

I will have to do some development and I will need your logic please,
I'll try to be as clear as possible
I have a JSON file that will be sent to a Web Service to process it.
When the file arrives on this Web Service, I have to parse it.
First question :
Is it a #PostMapping to recover this file?
Since it's a file, I get it as a file like this:
#PostMapping( value="/getFile",
consumes = {"multipart/form-data"})
public void postFile(#RequestParam() MultipartFile file) throws IOException
I recover the file well, but the concern is that the #RequestParam parameter expects a file name, except that when the file is sent to the web service, I do not know its name yet,
Second Question :
So how do you parse this file into a string?
Thank you in advance for your precious help
For the first question:
Yep, #PostMapping is the right way to go. Regarding the file name bit, #RequestParam() does not expect the file name to be passed, it expects the "key" of the key-value pair where the value is the file being uploaded.
For example, when sending a file via a RestTemplate call, the file would be included in the POST call as somewhat like this:
MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
body.add("uploadFile", getFileToUpload());
Here the key is "uploadFile", so your controller will look like this :
#PostMapping( value="/getFile",
consumes = {"multipart/form-data"})
public void postFile(#RequestParam("uploadFile") MultipartFile file) throws IOException
Checkout this tutorial : https://spring.io/guides/gs/uploading-files/
For the second question:
ByteArrayInputStream stream = new ByteArrayInputStream(file.getBytes());
String myFileString = IOUtils.toString(stream, StandardCharsets.UTF_8);
This should do. Cheers

How to send multipart/form-data and nested json in the same request in postman?

I have a REST api that takes data of nested json including multipart file
While testing the REST api through postman I am having problems.
I don't exactly know how to send the diverse types of data that I need - multipart/form-data file and nested json.
I have used REST in each case separately in other projects but I am unable to combine them in one request.
To use multipart/form-data I have to select form-data in the Body, then File from the dropdown in the key field, click on the select files button on the value field and select the file I want to upload.
To use nested json I have to select raw in the dropdown, and select json at the right of it and simply add the nested json in the body.
But how do I combine these two approaches?
I need multipart/form-data as well as nested json in the same request. How do I send these from postman? I am trying various approaches as you can see in the screenshots but I am not getting anywhere.
Thanks in advance
P.S. If it matters, I am using java (spring boot) for the backend.
Your first approach is correct. However to pass the most complicated data it will be a nightmare to do from that location. If passing data from postman is the requirement then you can use the pre-request script in the postman. Below is the example:-
For pre-req, I have kept a basic js object.
Try with this feature.
I followed the above answer and it worked for me.
Step 1: set json data value in pre-request Script.
var data = {
name:"COD Black Ops",
cost:60,
}
pm.variables.set("somedata",JSON.stringify(data));
Step 2: set form values.
enable content type option from (...) like button next to description column in order to set the value of your json field as "application/json".
Step 3: express code for handling form data
const multer = require('multer')
const upload = multer(<options>)
app.post('/stats', upload.single('uploaded_file'), function (req, res) {
// req.file is the name of your file in the form above, here 'uploaded_file'
// req.body will hold the text fields, if there were any
console.log(req.file, req.body)
});

How to create a Filename + Queryparameter Request

I'm writing a page with a list of files. Every file should be previewable and downloadable. Therefore every file needs two anchor-links. One for download and one for preview. The download-link was no problem as the mediatype is always "application/octet-stream" but the preview link must pass the filename with extension as the request url so that the browser can create a specific request for the mediatype that is given by the filename extension. In addition to that filename I want to pass a query parameter which is the id of the file, as there can be multiple files with the same name.
So my controller method for preview looks something like this:
#GetMapping(value = "/show/{filename}", produces = {MediaType.IMAGE_PNG_VALUE,MediaType.IMAGE_JPEG_VALUE, MediaType.APPLICATION_PDF_VALUE, MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE, MediaType.TEXT_PLAIN_VALUE})
public #ResponseBody byte[] show(#RequestParam("fileid") Long fileId, Model model)
{
...
}
The thymeleaf template anchor looks like that:
<a th:href="#{/files/show/${file.filename}(fileid=${file.id})}" style="height:24px;" title="Preview">
As seen the filename should be a route-parameter and the id is a query-parameter. Thymeleaf however creates the following url:
/files/show/${file.filename}?fileid=13
It successfully inserts the fileid and creates a queryformat but it fails to replace the filename.
Am I doing something wrong? What is the correct format for a thymeleaf link of that kind?
The standard url syntax supports both path paramters and normal parameters in the same expression. In general, I would avoid string concatenation when building links.
Here's how I would format this:
th:href="#{/files/show/{filename}(filename=${file.filename}, fileid=${file.id})}"
Ok...After more research I could solve it myself. The right form of the thymeleaf URL is one of the two:
th:href="#{'/files/show/' + ${file.filename}(fileid=${file.id})}"
of
th:href="#{|/files/show/${file.filename}(fileid=${file.id})|}"
Both will work.

How to filter responses types in HtmlUnit?

While crawling a webpage I am getting various response types (image/text/html/json/css/js etc). I only need the .json files not the other ones. How can I filter other response types using HtmlUnit?
Problem is: The required data is stored in a specific .json file and that .json file doesn't have a unique url. So I am planning to filter other response type and download the content of all the json files. Later on I will clean the data.
Please help. Just an idea will be enough.
You can see modify the request and responses, as hinted here.
Check if the URL contains .json string, and then save it.
new WebConnectionWrapper(webClient) {
public WebResponse getResponse(WebRequest request) throws IOException {
WebResponse response = super.getResponse(request);
if (request.getUrl().toExternalForm().contains(".json")) {
String content = response.getContentAsString("UTF-8");
//save content
}
return response;
}
};

Categories

Resources