#FormParam parameter always null in my JAX-RS resource service - java

Here is a service that I request with a curl :
time curl -i -XPOST 'http://localhost:9080/my/service' -H "Authorization:OAuth MyToken" -H "Content-Type: application/json" -d "ids=516816b2e4b039526a235e2f,516816b2e4b039526a235e2f"
The resource :
#Path("/my")
#Consumes({"application/xml", "application/json"})
#Produces({"application/xml", "application/json", "text/json"})
#Restricted
public class MyResource {
#POST
#Path("/service")
public Map<String ,Object> myService(#FormParam("ids") String myIds) {
// service things
}
}
That service worked fine, but it suddenly fails. Now the parameter myIds is always null, and the result of the curl is 400 bad request...
I didn't change anything in this resource so it should still be working.
If anybody has an idea, let me know.
Thanks!

In your curl-command, you are posting form data along with the Content-Type: application/json. Clearly this data is not valid JSON, hence the 400 bad request.
If you want to post form data, you need to use the content type application/x-www-form-urlencoded

Related

Curl POST request to Java SpringBoot backend receives all numbers as 0's

I have a Java SpringBoot backend server and I wanted to test the controller classes with curl. However, whenever I send a request with the following format (in a powershell terminal):
curl --request POST --header "Content-Type: application/json" --data '{\"key\": 5}' http://localhost:8080/request
All the numerical values are changed to zeroes. And if in the DTO class I change them to Integer instead of int, then they are received as null. For strings, everything works perfectly.
This is what my controller methodlooks like:
#RestController
#RequestMapping("/request")
class MyController {
#PostMapping
public ResponseEntity<MuseumTO> createMuseum(#RequestBody RequestDTO request) {
System.out.println(request.key);
// ...
}
}
And the DTO class:
class RequestDTO {
public int key
}
GET requests work fine, and I've tried with two different backends, so I assume my problem is coming from the curl request's format. However, I've looked online and from what I've seen this is supposed to work.
There is a small issue in your CURL request. No need to use an escape character with "key". You are using a backslash with double quotes (\") that is not required.
Please try this CURL request.
curl --request POST --header "Content-Type: application/json" --data '{"key": 5}' http://localhost:8080/request

How to annotate a Java List form-urlencoded parameter for Swagger?

I have this API endpoint which expects one form-urlencoded array parameter. This is the relevant Java snippet:
#POST
#Consumes(MediaType.APPLICATION_FORM_URLENCODED)
#Produces(MediaType.APPLICATION_JSON)
public Response addItems(#Parameter(description = "Items to add") #FormParam("items") List<Long> items) {
return service.addItems(items);
}
I can't reach the endpoint from the generated Swagger UI because of the following error:
RESTEASY003870: Unable to extract parameter from http request: javax.ws.rs.FormParam("items") value is '1%2C2%2C3'
From what I read, Swagger is making this request:
curl -X 'POST' \
'http://localhost:8080/items' \
-H 'accept: */*' \
-H 'Content-Type: application/x-www-form-urlencoded' \
-d 'items=1,2,3'
It looks to me that the culprit is how Swagger serializes the array: Swagger sends this items=1,2,3 while RESTEasy expect this items=1&items=2&items=3.
I've already read the relevant Swagger documentation and tried every style/explode combination, including the ones that looks to have most sense for me (style = ParameterStyle.SIMPLE, explode = TRUE which by the way should be default behavior) with no luck.
So, how should I annotate this endpoint in order to Swagger to be able to invoke it?
I used https://github.com/quarkusio/quarkus-quickstarts/tree/main/openapi-swaggerui-quickstart and added your method to FruitResource
According to swagger documentation if you want to use form urlencoded
application/x-www-form-urlencoded is used to send simple ASCII text data as key=value pairs. The payload format is similar to query parameters.
at https://swagger.io/docs/specification/describing-request-body/, so it says use query params and I changed your function to
#POST
#Consumes(MediaType.APPLICATION_FORM_URLENCODED)
#Produces(MediaType.APPLICATION_JSON)
public Response addItems(
#Parameter(description = "Items to add") #QueryParam(
"items"
) List<Long> items
) {
return service.addItems(items);
}
and open the dev-ui
As you can see UI is preventing to add wrong parameters, correct ui below
and created curl command is working as expected.
curl -X 'POST' \
'http://localhost:8080/fruits?items=1&items=2' \
-H 'accept: */*' \
-d ''
in case you want to test the code it is here.

Behavior of google cloud end point api

I defined a google cloud end point using java. the class method annotations looks like:
#Api(
name = "instaSmartApi",
version = "v1",
)
public class InstaSmartSvc {
#ApiMethod(name = "analyzeImage")
public Message analyzeImage(#Named("imgURL") String imgURL) {
...
}
I call it using curl which works is:
curl -H "Content-Type: application/json" -X POST -d '{"imgUrl" : "www.google.com"}' https://instasmarttagger.appspot.com/_ah/api/instaSmartApi/v1/analyzeImage/abc.jpg
this works fine except it ignores what i passed in request body.
The way I was expecting it to work:
curl -H "Content-Type: application/json" -X POST -d '{"imgUrl" : "www.google.com"}' https://instasmarttagger.appspot.com/_ah/api/instaSmartApi/v1/analyzeImage
But this returns not found. I am not sure why i have to append the method parameter in the end to make it work. Ideally i should pass that in the body. Please advise

Query parameter not being extracted - JAX-RS and Jersey

I'm using Jersey 2.19 to implement a REST API but I'm having difficulty using #QueryParam to extract the query parameters from a POST request even though my resource method is being called.
This is my resource method:
#POST
#Produces(MediaType.TEXT_PLAIN)
public Response test(#QueryParam("test-param") String testParam)
{
String response = "testParam is: " + testParam + "\n";
return Response.status(Response.Status.OK).entity(response).build();
}
I'm using cURL to submit the HTTP POST request as follows:
curl -X POST http://192.168.0.2:8080/myApp/test --data test-param=Hello
The value returned is always null.
What am I doing wrong?
The --data in curl will provide the whole text test-param=Hello. The correct way to request it is:
curl -X POST http://192.168.0.2:8080/myApp/test?test-param=Hello
try to use curl -X POST '192.168.0.2:8080/myApp/test?test-param=Hello';
-d, --data
(HTTP) Sends the specified data in a POST request to the HTTP server, in the same way that a browser does when a user has filled in an HTML form and presses the submit button. This will cause curl to pass the data to the server using the content-type application/x-www-form-urlencoded. Compare to -F, --form.

Jersey Test Equivalent to curl request

First trip into the Java web services world. Trying to write a test for a post request. The post looks like this in curl:
url -v -X POST -H 'Content-Type: application/json' -d '{"transaction_zips": ["78732"],"condition": "good"}' http://localhost:8080/PricingService/vin/1GTEC19J37E152026/usedValues
I've attempted:
#Test
public void testVinPricing200() {
int status = target.path("PricingService/vin/1GTEC19J37E152026/usedValues").request(MediaType.APPLICATION_JSON_TYPE).
post(Entity.entity("{\"transaction_zips\": [\"78732\"],\"condition\": \"good\"}", MediaType.APPLICATION_JSON)).getStatus();
assertEquals(200, status);
}
This results in:
Failed tests: testVinPricing200(com.comp.platform.PricingServiceTest): expected:<200> but was:<406>
So the question is simple, I'm obviously not posting correctly, what am I doing wrong?
The difference between your curl request and your junit test in your junit test you are requesting a response of type MediaType.APPLICATION_JSON_TYPE, but your webservice is not capable of responding via JSON.
Http Status code: 406
The resource identified by the request is only capable of generating response entities
which have content characteristics not acceptable according to the accept headers sent in
the request.

Categories