How to insert a map<Integer, String> as #RequestParam with Postman - java

first of all, sorry for my english, it's not my main language, and I'm not sure the question is fully understandable.
I need to do some queries after receiving a Map as a #RequestParam of a Rest Web Service.
I'm trying to call the web service with Postman, and here is the full POST request
http://localhost:8080/CDRestApi/rest/cd/esibizione/getIdUdFromIstanzaMetadatoByMap/5/map?25=ALAN&26=IANESELLI
This is my WS code:
#RequestMapping(value = { "/getIdUdFromIstanzaMetadatoByMap/{id}/map" }, method = RequestMethod.POST, produces = {
MediaType.APPLICATION_JSON_VALUE })
#ResponseBody
public String selectIstanzaMetadato(#PathVariable Long id,
#RequestParam (value="map", required=true) Map<Integer,String> mapQuery) {
Integer key = 25;
System.out.println(mapQuery.get(key));
return mapQuery.get(key).toString();
}
And this is the postman answer:
{
"timestamp": 1505834218902,
"status": 500,
"error": "Internal Server Error",
"exception": "java.lang.NullPointerException",
"message": "No message available",
"path": "/CDRestApi/rest/cd/esibizione/getIdUdFromIstanzaMetadatoByMap/5/map"
}
the System.out print is:
17:16:58,891 INFO [stdout] (default task-4) null
I suppose the mapQuery object has no value, because it is not correctly valorized
I have already seen those posts, but they were not useful to me:
Map<String, String> as #RequestParam in Spring MVC
and
Spring MVC + RequestParam as Map + get URL array parameters not working
Do I miss the correct Postman POST request ? or it is a problem of the webservice itself ?

I resolved this getting the map and converting it into a map.
Map<Integer, String> mappaQuery = mapQuery.entrySet().stream().collect(Collectors.toMap(e -> Integer.parseInt(e.getKey()), Map.Entry::getValue));
It is not efficient, but it worked for the test purposes of Postman call; in the real call of the WS, I can pass a proper Map object.

Related

Should I use #RequestBody or #RequestParam for PatchMapping

I was working on a SpringBoot Rest Api.
I've a Comment entity. I just want to update comment's text. So I decided to use patchmapping.
I'm beginner on SpringBoot. I'm learning by the training. My plan was to find the comment by given Id. And update the text as a given String parameter.
When I use this controller with #RequestBody. And send a String via postman.
#PatchMapping("/updateStatus/{id}")
public ResponseEntity<CommentDto> updateTheUserStatus(#PathVariable Long id, #RequestBody String text){
return ResponseEntity.ok(commentService.changeStatus(id, text));
}
The Postman gives 500 Internal Error. But in the Database the text field is changing as I want.
{
"timestamp": "2022-04-13T08:17:13.615+00:00",
"status": 500,
"error": "Internal Server Error",
"path": "/v1/api/comment/updateStatus/4"
}
When I use this controller with #RequestParam Postman Gives 400 Bad Request and nothing is changing.
#PatchMapping("/updateStatusMe/{id}")
public #ResponseBody ResponseEntity<CommentDto> updateTheUserStatus1(#PathVariable Long id, #RequestParam String text){
return ResponseEntity.ok(commentService.changeStatus(id, text));
}
{
"timestamp": "2022-04-13T08:19:41.391+00:00",
"status": 400,
"error": "Bad Request",
"path": "/v1/api/comment/updateStatusMe/4"
}
I know that probably I'm totally wrong. But I'm asking this question for you to learn what am I missing. Thank you for your help!

Spring post json

I try to build my first api. I got problem when i want to register new user. The problem is when i want to send request from postman. I using also SwaggerUI, so when i use Post Request to my end point /registration in SwaggerUI by textfields always i got http status 201 so its works good. Problem is when i want to make Mock to this controller or when i want to send new user in postman request but not always. I show you in example
If i use postman -> post: localhost:8080/registration -> Raw -> JSON
{
"email": "testtest#gmail.com",
"id": 0,
"password": "Test1234567 ",
"username": "testtest"
}
Then i got message
{
"status": "BAD_REQUEST",
"timestamp": "01-03-2021 11:44:26",
"message": "Value cannot be empty!",
"debugMessage": null,
"subErrors": null
}
So its should be good because i used catch exception. But Value isnt empty, so whats happend?I dont know.
But when i go to x-www-form-urlencoded and there i put keys: email, username and password then, user is created!
Another, when im put this same info to Swagger then also my user is created.
Below i add my code from controller and test.
#Test
void shouldCreateNewUser() throws Exception {
UserRegistrationDto user = new UserRegistrationDto( null,"seba12345", "lelelele1908#gmail.com", passwordEncoder.encode("Respeck123"));
mockMvc.perform(post("/registration")
.header("header1", "1")
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(user)))
.andExpect(status().isCreated());
}
#PostMapping("/registration")
public ResponseEntity<UserRegistrationDto> registerUser(UserRegistrationDto userRegistrationDto) {
HttpHeaders headers = new HttpHeaders();
userService.save(userRegistrationDto);
return new ResponseEntity<>(userRegistrationDto, headers, HttpStatus.CREATED);
}
You need #RequestBody in your controller method to tell Spring that you want the content of the request body:
#PostMapping("/registration")
public void post(#RequestBody MyDTO dto) {
...
}

Missing request param when it is included in body

I am posting a POJO where I get an error saying the field is not included.
Asset POJO
public class Asset {
private MultipartFile[] files;
private String name;
private String meta;
//Constructor/Getters n Setters
}
Resource Method
#PostMapping("asset")
public ResponseEntity uploadAsset(#RequestParam("asset") Asset asset) {
System.out.println(asset);
return new ResponseEntity(HttpStatus.ACCEPTED);
}
PostMan JSON Body
{
"asset" : {
"files": [
"#/home/Downloads/1.jpeg",
"#/home/Downloads/2.jpeg"
],
"name": "assetName",
"meta": "assetMeta"
}
}
PostMan JSON Response
{
"timestamp": "2019-10-29T20:46:19.536+0000",
"status": 400,
"error": "Bad Request",
"message": "Required Asset parameter 'asset' is not present",
"path": "/asset"
}
I don't understand why I get the Required Asset parameter 'asset' is not present message when I have it in the JSON body. Any ideas on this?
Use #RequestBody rather than #RequestParam
public ResponseEntity uploadAsset(#RequestBody Asset asset) {
Based on your payload, Spring is expecting an object that looks like this:
public class SomeClass {
private Asset asset;
}
Change your payload to look like this:
{
"files": [
"#/home/Downloads/1.jpeg",
"#/home/Downloads/2.jpeg"
],
"name": "assetName",
"meta": "assetMeta"
}
RequestParam
Annotation which indicates that a method parameter should be bound to a web request parameter.
RequestBody
Annotation indicating a method parameter should be bound to the body of the web request. The body of the request is passed through an HttpMessageConverter to resolve the method argument depending on the content type of the request. Optionally, automatic validation can be applied by annotating the argument with #Valid.
HttpMessageConverter
Strategy interface that specifies a converter that can convert from and to HTTP requests and responses.
You need to check converter dependency. because you using application/json.
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.8</version>
</dependency>
Q : Missing request param when it is included in body
A : Use #RequestBody annotation.
I tried #Jordans answer and the endpoint was called with all values set to null :(
Doing more research I came across this statement https://stackoverflow.com/a/51982230/2199102 and tried it out.
Combining #Jordans answer and then the annotation change, I was able to get the answer I wanted

How to send a Content-Type form-data request using rest assured?

I need to invoke a form-data typed API using Rest Assured. Here is my code.
private Map<String, String> getFormParamsMap() {
Map<String, String> formParams = new HashMap<>();
formParams.put("creatorId", "Instructor1");
formParams.put("creatorPlatform", "Web");
formParams.put("creatoredSource", "File");
formParams.put("creatoredType", "Auto");
formParams.put("deckId", "5a605b472e02d86561172dad");
formParams.put("userId", "kind");
return formParams;
}
public void invoke() {
response = given()
.header("Content-Type", "application/form-data")
.header(AUTHORIZATION_HEADER_NAME, accessToken) //Some API contains access token to run with the API
.headers(headers)
.formParams(getFormParamsMap()) // requestParamsMap here.
.when()
.post(invokingEndpoint);
}
When I execute this, I am getting the below error.
Message: java.lang.IllegalArgumentException: Don't know how to encode creatorPlatform=Web&creatoredType=Auto&deckId=5a605b472e02d86561172dad&creatorId=Instructor1&creatoredSource=File&userId=kind as a byte stream.
Please use EncoderConfig (EncoderConfig#encodeContentTypeAs) to specify how to serialize data for this content-type.
For example: "given().config(RestAssured.config().encoderConfig(encoderConfig().encodeContentTypeAs("application/form-data", ContentType.TEXT))). .."
Stack Trace:
io.restassured.internal.http.EncoderRegistry.encodeStream(EncoderRegistry.java:130)
When I use .config(RestAssured.config().encoderConfig(encoderConfig().encodeContentTypeAs("application/form-data", ContentType.TEXT))) in the invoke() method, it gives the result as below.
{
"status": 400,
"message": "Content type 'application/x-www-form-urlencoded;charset=ISO-8859-1' not supported",
"error": "Bad Request",
"exception": "org.springframework.web.HttpMediaTypeNotSupportedException"
}
My request is not x-www-form-urlencoded type, it is form-data type. I can execute it using postman.
Appreciate your support on this.
Thanks.
I have solve this issue by using encodeContentTypeAs("multipart/form-data", ContentType.TEXT)
Ex:-
public void invoke() {
response = given()
.config(
RestAssured.config()
.encoderConfig(
encoderConfig()
.encodeContentTypeAs("multipart/form-data", ContentType.TEXT)))
.headers(headers)
.formParams(formParams)
.when()
.post(oAuthBaseURI).then().extract().response();
}
Please add the consumer as well.
See here for the encoders available for Rest Assured.
This might be causing the problem -
encodeContentTypeAs("application/form-data", ContentType.TEXT)
You can also try this -
.encoderConfig(encoderConfig().appendDefaultContentCharsetToContentTypeIfUndefined(false).encodeContentTypeAs("application/form-data", ContentType.TEXT));
As far as I can tell, headers(headers) method replaces all headers, and then RestAssured uses x-www-form-urlencoded content type as default.
Try adding "Content-Type" header after the call to headers(headers).

Java Spring MVC - Send JSON request body error

I am trying to send a JSON string as a request to my application. This is my code:
#RequestMapping(
value = "/mylink/upload",
method = RequestMethod.POST,
consumes ="application/json",
produces = "application/json")
public
#ResponseBody
List<Upload> upload(
#RequestParam(value = "hdfsLocation") String hdfsLocation
) throws Exception {
return S3HdfsTransfer.uploadFromHDFS(hdfsLocation);
}
I am trying to send a request with Postman. The method I use is POST, the header contains: Accept "application/json",Content-Type "application/json", the request body is the following:
{
"hdfsLocation" : "hdfs://145.160.10.10:8020"
}
This is the response I get. If I put the parameter in the URL, it works.
{
"httpStatus": 500,
"appErrorId": 0,
"message": "Required String parameter 'hdfsLocation' is not present",
"trackingId": "8c6d45fd-2da5-47ea-a213-3d4ea5764681"
}
Any idea what I am doing wrong?
Thanks,
Serban
Looks like you have confused #RequestBody with #RequestParam. Do either of following :
Pass the request param as a request param(not as a body). Like, (encoded)
http://example.com?hdfsLocation=http%3A%2F%2Fexample.com%3FhdfsLocation%3Dhdfs%3A%2F%2F145.160.10.10%3A8020
Replace the #RequestParam with #RequestBody. If you are sending a body, don't send it along with request param. Those are two different things.
I guess you over looked :)
Shouldn't it be #RequestBody instead of #RequestParam?
Also, even after using #RequestBody, the whole of the JSON string:
{
"hdfsLocation" : "hdfs://145.160.10.10:8020"
}
will be the value of String hdfsLocation and not just the hdfs url. Hence, you'll have to JSON parse that JSON by yourself to get just the hdfs url.

Categories

Resources