#PostMapping(value = "/dummy/v1/user/session", consumes = MediaType.ALL_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<GlobalResponseBO> loginUserAuthenticationdummy(#RequestHeader Consumer<HttpHeaders> headers, #RequestBody LoginRequestDummy request) {
//ResponseEntity<LoginResponseDummy> response = userService.loginDummy(headers,request);
GlobalResponseBO globalResponseBO = handleSuccessResponse("LoginResponse"," response");
log.info(globalResponseBO.toString());
return ResponseEntity.ok().body(globalResponseBO);
}
"trace": "org.springframework.web.bind.MissingRequestHeaderException: Required request header 'headers' for method parameter type Consumer is not present\r\n\tat org.springframework.web.method.annotation.RequestHeaderMethodArgumentResolver.handleMissingValue(RequestHeaderMethodArgumentResolver.java:87)\r
Related
Context
I have two controllers: /testParams and /callTestParams
Controller /testParams receives an object of type Example and I can call this controller from Postman without any problem.
Controller /callTestParams calls /testParams internally using RestTemplate but the response is a 500 Internal Server Error. I supose that the implementation of /callTestParams is equivalent to the call maded by Postman.
Here is the code:
#RequestMapping(value = "/testParams",
method = RequestMethod.POST, produces = "application/json", consumes = "application/json")
public ResponseEntity<Object> testParams(
#RequestBody Example credentials
) {
JSONObject params = new JSONObject( credentials );
System.out.println( params.get("clientId") + " from JSONObject");
System.out.println( credentials.getClientId() + " from GraphCredentials");
return new ResponseEntity<>(credentials,HttpStatus.OK);
}
#RequestMapping(value = "/callTestParams",
method = RequestMethod.POST, produces = "application/json", consumes = "application/json")
public ResponseEntity<Object> callTestParams() {
String url = "http://localhost:8080/GraphClient/testParams";
HttpHeaders headers = new HttpHeaders();
headers.set( HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE );
JSONObject params = new JSONObject();
params.put("clientId", "value1" );
RestTemplate restTemplate = new RestTemplate();
HttpEntity<?> entity = new HttpEntity<>(params,headers);
HttpEntity<Object> response = restTemplate.exchange(
url,
HttpMethod.POST,
entity,
Object.class
);
return new ResponseEntity<>(response.getBody(), HttpStatus.OK);
}
This is the response from Postman for /testParams
Headers:
(Content-Type,application/json)
Request Body:
JSON (appplication/json)
{"clientId":"value1"}
Response:
{
"clientId": "value1",
"clientSecret": null,
"tenantId": null,
"scope": null,
"grantType": null,
"microsoftLoginBaseURL": "https://login.microsoftonline.com/"
}
This is the response from Postman for /callTestParams
{
"timestamp": "2022-01-09T03:39:06.878+0000",
"status": 500,
"error": "Internal Server Error",
"message": "500 Internal Server Error",
"path": "/GraphClient/callTestParams"
}
This is the error in the console>
Forwarding to error page from request [/testParams] due to exception [JSONObject["clientId"] not found.]: org.json.JSONException: JSONObject["clientId"] not found.
In the parameter of the body of the HttpEntity constructor you need to pass params as String
HttpEntity<?> entity = new HttpEntity<>(params.toString(),headers);
I have this Feign Client in my spring boot application :
#Component
#FeignClient(value = "apiKeyManager", url = "http://localhost:8081/", configuration = FileUploadConfiguration.class)
public interface ApiKeyClient {
#RequestMapping(method = RequestMethod.POST, value = "/api/public/getAppName", consumes = "application/json", produces = "application/json")
ResponseEntity getAppName(#RequestBody AppNameRequestDto appNameRequestDto);
}
And I have this code in my service, which calls it :
AppNameRequestDto request = new AppNameRequestDto(apiKey);
ResponseEntity verification = apiKeyClient.getAppName(request);
return verification;
The actual endpoint being called by the feign client looks like this :
#PostMapping(value = "getAppName", consumes = "application/json", produces = "application/json")
public ResponseEntity getAppName(#RequestBody AppNameRequestDto appNameRequestDto){
try {
return new ResponseEntity(apiKeyManagementService.getAppName(appNameRequestDto.getApiKey()), HttpStatus.OK);
} catch (Exception e) {
return new ResponseEntity("Failed to locate application by API_KEY : " + appNameRequestDto.getApiKey(), HttpStatus.NOT_FOUND);
}
}
When I run this code - I get this response :
{
"headers": {
<REMOVED FOR BREVITY>
},
"body": null,
"statusCode": "OK",
"statusCodeValue": 200
}
But when I make the call to the underlying API directly, I get the response I am expecting - an entity with an accompanies 200 status :
{
"applicationName": "MyNewFileUploadServiceApplication6"
}
while i am executing below code i am getting error like
"org.springframework.web.client.HttpClientErrorException: 400 null".
but when i use postman to call this "http://localhost:2018/test" it is working.
static final String URL_EMPLOYEES = "http://localhost:2018/test";
HttpHeaders headers = new HttpHeaders();
headers.setAccept(Arrays.asList(new MediaType[] {
MediaType.APPLICATION_JSON}));
// Request to return XML format
headers.setContentType(MediaType.APPLICATION_JSON);
headers.set("replyMsg", "str");
// HttpEntity<Employee[]>: To get result as Employee[].
HttpEntity<String> entity = new HttpEntity<String>(headers);
// RestTemplate
RestTemplate restTemplate = new RestTemplate();
// Send request with GET method, and Headers.
ResponseEntity<String> response =
restTemplate.exchange(URL_EMPLOYEES,
HttpMethod.POST, entity,String.class);
HttpStatus statusCode = response.getStatusCode();
// Status Code: 200
if (statusCode == HttpStatus.OK) {
// Response Body Data
msg=response.getBody();
if (msg != null) {
System.out.println(msg);
}
}
//my clint controller class
#RestController
public class TextController {
#RequestMapping(value="/test",method = RequestMethod.POST)
public String myData2(#RequestBody String payload) {
return "done";
}
}
any suggetions?
If you're using Jackson as your JSON parser, you can simply declare your parameter with the type TextNode. This is the Jackson type representing JSON strings.
public String updateName(#PathVariable(MY_ID) String myId, #RequestBody TextNode name) {
You can then use its asText method to retrieve its text value.
Here you are setting headers Content-Type with type JSON and passing the body of type text/String.
headers.setContentType(MediaType.APPLICATION_JSON); //setting your Content type as JSON.
So, First you need to change this to
headers.setContentType(MediaType.TEXT_PLAIN); //setting your Content type as Pure Text String.
and add some code after this line
// HttpEntity<Employee[]>: To get result as Employee[].
HttpEntity<String> entity = new HttpEntity<String>(headers);
add this code
// HttpEntity<Employee[]>: To get result as Employee[].
HttpEntity<String> entity = new HttpEntity<String>(headers);
// RestTemplate
RestTemplate restTemplate = new RestTemplate();
// Send request with GET method, and Headers.
String entity_Str = new ObjectMapper().writeValueAsString(entity);
ResponseEntity<String> response =
restTemplate.exchange(URL_EMPLOYEES,
HttpMethod.POST, entity_Str, String.class);
This might work for you.. Thanks :)
please i have this error when trying to create a customer. Can some one help me? May be i am missing some thing. I have even try to change the #PostMapping to #RequestMapping till yet. Thks
My Controller code
`#PostMapping("CREATE_CUSTOMER_ENDPOINT")
#ResponseStatus(value = HttpStatus.OK)
#ApiResponses(value = {
#ApiResponse(code = 201, message = "The Customer was Created", response = CustomerDto.class),
#ApiResponse(code = 400, message = "Bad Request", response = ResponseError.class),
#ApiResponse(code = 500, message = "Unexpected error")
})
public ResponseEntity createCustomer(final HttpServletRequest request, #RequestBody CustomerDto customerDto)
{
if (log.isDebugEnabled()){
log.debug("[CustomerResource] POST {} : Creating customer ", CREATE_CUSTOMER_ENDPOINT);
}
if(customerDto.getUidpk()!=null) {
ResponseError error = new ResponseError(HttpStatus.BAD_REQUEST.getReasonPhrase(), "A customer Already exist with an Uidpk");
log.error("[CustomerResource] The customer Already exist ({}) with an Uidpk", customerDto.getUidpk());
return new ResponseEntity<>(error, null, HttpStatus.BAD_REQUEST);
}
CustomerDto result = customerService.createCustomer(customerDto);
log.debug("[CustomerResource] Customer created ({})", result.getUidpk());
return new ResponseEntity<>(result, HeaderUtil.putLocationHeader(request.getRequestURL().toString() + "/" + result.getUidpk()), HttpStatus.CREATED);
} `
My endpoints
private static final String CUSTOMER_SEARCH_USER_ID_ENDPOINT = "/customers/{userId:.+}";
private static final String CREATE_CUSTOMER_ENDPOINT= "/customer";
private static final String UPDATE_CUSTOMER_ENDPOINT= "/customer";
private static final String DELETE_CUSTOMER_ENDPOINT = CREATE_CUSTOMER_ENDPOINT + "/{uidpk}";
This is the response of Postman
Postman sample
When you send JSON payloads in HTTP request, you need to specify Content-Type HTTP header with value application/json.
It will call another REST API with a GET request.
#RequestMapping(value = "xxxx/{id}", method = RequestMethod.GET)
public #ResponseBody GetObjet GET( #PathVariable("id") String id,
#RequestHeader(value="X-Auth-Token") String Token) {
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.add("X-Auth-Token", Token);
HttpEntity entity = new HttpEntity(headers);
ResponseEntity<GetObjet> response = restTemplate.exchange(url, HttpMethod.GET, entity, GetObjet.class);
return response.getBody();
}
Always 400 Error. It means that bad request or some errors in the request body. But this is GET so the resquest bodys is always empty. So this way to add header may be not right. Any ideas?
You can obtain the headers including the notation #RequestHeader in your method
public void displayHeaderInfo(#RequestHeader("Accept-Encoding") String encoding,
#RequestHeader("Keep-Alive") long keepAlive) {
}
o
You can read more about the request here
And the other way to abtain the URL is:
#RequestMapping(value = "/restURL")
public String serveRest(#RequestBody String body, #RequestHeader HttpHeaders headers){
//Use headers to get the information about all the request headers
long contentLength = headers.getContentLength();
...
StreamSource source = new StreamSource(new StringReader(body));
YourObject obj = (YourObject) jaxb2Mashaller.unmarshal(source);
...
}
Try using:
RestTemplate.getForEntity(url, GetObject.class);
You have some methods to request data from a rest API, such as getForEntity and getForObject, use the one you needed.