I am using javax to create a REST service to send an Java Object from one system to another.
I send the data like follows:
WebTarget wt = client.target(baseUrl.toString()).path(restUrlSuffix);
response = wt.request(MediaType.APPLICATION_JSON).post(Entity.json(transferJSON));
I defined a method which should receive the entity as a JSON:
#POST
#Path("/post")
#Consumes("application/json")
#Produces("application/json")
public Response saveWorkflowDefinition(#Valid String json) {
.....
.....
String message = "Message to return";
Response res = Response.ok(message).build();
return res;
}
With this method everything is fine. Data arrives as JSON, colud be transformed back to my java class and I can work with the object again.
Also it seems, that the Response is correct.
If I debug my code, the response is properly filled.
But on the side where I want to receive this response and check it, the entity part is empty.
I have no idea why?
Screen 1 is my response before sending it:
Screen 2 is the response after receiving it:
I found a solution.
I had to add a "valid" readEntity to my WebTarget request.
I my case I have written a response object, maybe a String.class might work too. I need my response class later in my code to transfer some more detailed information.
response = wt.request(MediaType.APPLICATION_JSON).post(Entity.json(transferJSON)).readEntity(WFResponse.class);
Related
I want to make a GET request to my server that receives two parameters, uniqueConfig and commitHash. The code for this operation in my Controller class is as follows:
#GetMapping("/statsUnique")
public ResponseEntity<Object> hasEntry(#RequestParam("uniqueConfig") String uniqueConfig,
#RequestParam("commitHash") String commitHash) {
Optional<Stats> statsOptional =
codecService.findByUniqueConfigAndCommitHash(uniqueConfig, commitHash);
if (statsOptional.isPresent()) {
return ResponseEntity.status(HttpStatus.OK).body(true);
}
return ResponseEntity.status(HttpStatus.OK).body(false);
}
The issue is, when I try to make the GET request using Postman, the server returns a 400 - Bad Request with the following error message:
MissingServletRequestParameterException: Required request parameter 'uniqueConfig' for method parameter type String is not present]
my JSON on Postman looks like this:
{
"commitHash": "ec44ee022959410f9596175b9424d9fe1ece9bc8",
"uniqueConfig": "bowing_22qp_30fr_29.97fps_fast-preset"
}
Please note that those aren't the only attributes and I've tried making the same request with all of them on the JSON. Nonetheless, I receive the same error.
What am I doing wrong here?
A GET request doesn't (or at least shouldn't) have a body. Parameters defined by the #RequestParam annotations should be sent in the query string, not a JSON body, i.e., the request should be something like
http://myhost/statsUnique?commitHash=commitHash&uniqueConfig=bowing_22qp_30fr_29.97fps_fast-preset
I am currently sending a resource to a client, I am using code that has been done already and I am modifying it, there is a line shown below in this code that I don't understand. Well I understand that I am sending or posting a resource, I understand this method takes the url of the client, that it takes the type of HTTP request for example in this case POST, but I dont understant why this method takes nService.getStringHttpEntityWithPayload(payLoad) and Resource.class? Also the response entity it is returning will it be a class only or a class with a status and a headers?
ResponseEntity<Resource> responseEntity = restTemplate.exchange(
eURL,
HttpMethod.POST,
nService.getStringHttpEntityWithPayload(payLoad),
Resource.class);
why this method takes nService.getStringHttpEntityWithPayload(payLoad) and Resource.class?
The method getStringHttpEntityWithPayload is returning a HttpEntity which is composed of a body and header data to be sent to a URL. The method is creating the request message by adding the content type header, letting the receiving service know that the body contains JSON data.
The parameter Resource.class is used to determine what class to deserialize the response body from the service into. It defines the generic type of the return value: ResponseEntity<Resource>.
Also the response entity it is returning will it be a class only or a class with a status and a headers?
I'm not sure what you mean by "class only". The ResponseEntity is similar to HttpEntity (in fact class ResponseEntity<T> extends HttpEntity<T>). The ResponseEntity class contains the response body and headers, as well as the HTTP Status code of the response.
I am trying to do a get call with request body(JSON) as the request parameter list exceeds the limit. I am able to send the request via postman/insomnia and request is reaching till controller without any error. But the "requstBody" is empty at controller. What i am missing here?
#GET
#Path("\path")
#Consumes(APPLICATION_JSON)
#Produces(APPLICATION_JSON)
public Response getResponse(String requestBody) throws IOException { }
When I replaced #GET with #POST, requestBody has value. For GET call do we need to add anything more?
I am trying to do a get call with request body(JSON) as the request parameter list exceeds the limit. I am able to send the request via postman/insomnia and request is reaching till controller without any error. But the "requstBody" is empty at controller. What i am missing here?
One thing you are missing is the fact that the semantics of a request body with GET are not well defined.
RFC 7231, Section 4.3.1:
A payload within a GET request message has no defined semantics; sending a payload body on a GET request might cause some existing implementations to reject the request.
There are two ways for sending parameters in an Http Get method. PathVariable and RequestParam. In this way, sent parameters are visible in the request URL. for example:
www.sampleAddress.com/countries/{parameter1}/get-time?city=someValues
In the above request, parameter1 is a path variable and parameter2 is a request parameter. So an example of a valid URL would be:
www.sampleAddress.com/countries/Germany/get-time?city=berlin
To access these parameters in a java controller, you need to define a specific name for the parameters. For example the following controller will receive this type of requests:
#GetMapping(value = "/countries/{parameter1}/get-time", produces = "application/json; charset=utf-8")
public String getTimeOfCities(
#PathVariable(value = "parameter1") String country,
#RequestParam(value = "city") String city
){
return "the method is not implemented yet";
}
You are able to send RequestBody through a Get request but it is not recommended according to this link.
yes, you can send a body with GET, and no, it is never useful
to do so.
This elaboration in elasticsearch website is nice too:
The HTTP libraries of certain languages (notably JavaScript) don’t allow GET requests to have a request body. In fact, some users are suprised that GET requests are ever allowed to have a body.
The truth is that RFC 7231—the RFC that deals with HTTP semantics and
content—does not define what should happen to a GET request with a
body! As a result, some HTTP servers allow it, and some—especially
caching proxies—don’t.
If you want to use Post method, you are able to have RequestBody too. In the case you want to send data by a post request, an appropriate controller would be like this:
#PostMapping(value = "/countries/{parameter1}/get-time", produces = "application/json; charset=utf-8")
public String getTimeOfCitiesByPost(
#PathVariable(value = "parameter1") String country,
#RequestParam(value = "city") String city,
#RequestBody Object myCustomObject
){
return "the method is not implemented yet";
}
myCustomObject could have any type of data you defined in your code. Note that in this way, you should send request body as a Json string.
put #RequestBody on String requestBody parameter
#RequestMapping("/path/{requestBody}")
public Response getResponse(#PathVariable String requestBody) throws IOException { }
I already search tutorial in spring for method POST, insert the data with response entity (without query) and I getting error in ajax. I want to confirm, What is format url from ajax to java? below my assumption:
localhost:8080/name-project/insert?id=1&name=bobby
is the above url is correct? because I failed with this url. the parameter is id and name.
mycontroller:
#PostMapping(value={"/insertuser"}, consumes={"application/json"})
#ResponseStatus(HttpStatus.OK)
public ResponseEntity<?> insertUser(#RequestBody UserEntity user) throws Exception {
Map result = new HashMap();
userService.insertTabelUser(user);
return new ResponseEntity<>(result, HttpStatus.CREATED);
}
my daoimpl:
#Transactional
public String insertUser(UserEntity user) {
return (String) this.sessionFactory.getCurrentSession().save(user);
}
the code running in swagger (plugin maven) but not run in postman with above url.
Thanks.
Bobby
I'm not sure, but it seems that you try to pass data via get params (id=1&name=bobby), but using POST http method implies to pass data inside body of http request (in get params, as you did, data is passed in GET method) . So you have to serialize your user data on client side and add this serialized data to request body and sent it to localhost:8080/name-project/insert.
As above answer suggest. You are trying to pass data as query parameters.but you are not reading those values in your rest API.either you need to read those query parameters in your API and then form an object or try to pass a json serialized object to your Post api as recommendation. Hope it helps.
I am trying to write a java client for restful resource. The response for my request is a list of objects. I have the following code for the request. BUt i get some unmarshall exception. Could anyone let me know how to solve this ?
GenericType<List<Response>> genType = new GenericType<List<Response>>() {};
GenericType<List<Response>> response = (GenericType<List<Response>>)resource.path(paramPath).accept(MediaType.APPLICATION_JSON).get(genType);
my resource has the following code
#GET
#Path("/app/{Id}")
#Produces(MediaType.APPLICATION_JSON)
public List<Response> getAllKeyValuesByAppId(#PathParam("Id") Long Id){
...
...
}
Can you test you REST method without unmarshaling?
Are you sure that the message body contains exactly what you expect?