SpringBoot: HttpClientErrorException$BadRequest: 400: [no body] when calling restTemplate.postforEntity or restTemplate.exchange - spring

I am trying to hit a restful endpoint from my springboot application using restTemplate.exchange and restTemplate.postForEntity and I am getting 400 Bad request [no body] exception.
I tried every possible solution to figure out the issue. From the same code I used HttpURLConnection to hit the endpoint and it works fine. I am able to get valid response. I also tried hitting the endpoint from Postman and it works fine
Below is endpoint code
#RestController
#RequestMapping("auth")
#Slf4j
public class AuthController {
#PostMapping(value = "/as/resourceOwner",
consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE,
produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<Token> getToken(#RequestParam(required = false)MultiValuedMap<?, ?> params) {
log.info("token endpoint");
return new ResponseEntity<>(new Token(), HttpStatus.OK);
}
}
The below code with HttpURLConnection class works fine
public class Test {
public static void main(String[] args) {
try {
URL url = new URL("http://localhost:8080/fc-services-mock-auth/fmrco/as/resourceOwner");
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setDoOutput(true);
urlConnection.setRequestMethod("POST");
urlConnection.setRequestProperty("Content-Type", MediaType.APPLICATION_FORM_URLENCODED_VALUE);
OutputStream writer = urlConnection.getOutputStream();
writer.write("a=a&b=b".getBytes(StandardCharsets.UTF_8));
writer.flush();
writer.close();
BufferedReader reader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
String line = null;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
} catch (Exception e) {
System.out.println(e);
}
}
}
But the below code with restTemplate does not work
try {
HttpEntity httpEntity = new HttpEntity<>(createBody(), createHeaders());
ResponseEntity<String> response = restTemplate.exchange(new URI(endpointConfig.getTokenServiceUrl()),
HttpMethod.POST, httpEntity, String.class);
HttpEntity<MultiValueMap<String, String>> request =
new HttpEntity<>(createBody(), createHeaders());
ResponseEntity<TokenResponse> tokenResponse = restTemplate.postForEntity(
new URI(endpointConfig.getTokenServiceUrl()),
request,
TokenResponse.class);
logger.debug(" token process completed");
return tokenResponse.getBody();
} catch (Exception e) {
throw new TokenException(" token error: ", e);
}
private HttpHeaders createHeaders() {
HttpHeaders headers = new HttpHeaders();
headers.add("Content-Type", MediaType.APPLICATION_FORM_URLENCODED_VALUE);
return headers;
}
private MultiValueMap createBody() {
MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
map.add("client_id", applicationConfig.getTokenClientId());
map.add("client_secret", applicationConfig.getTokenClientSecret());
map.add("grant_type", "password");
map.add("username", applicationConfig.getTokenUsername());
map.add("password", applicationConfig.getTokenPassword());
return map;
}
Can anyone please tell me what is wrong here?
Additionally I have written another GET restful endpoint like below and while hitting the endpoint using exchange I still get the same error.
#GetMapping(value = "test", produces = MediaType.TEXT_PLAIN_VALUE)
public ResponseEntity<String> test() {
return new ResponseEntity<>("Hello", HttpStatus.OK);
}
try {
HttpHeaders headers = new HttpHeaders();
headers.setAccept(Arrays.asList(MediaType.TEXT_PLAIN));
HttpEntity<MultiValueMap<String, String>> entity =
new HttpEntity<>(null, headers);
ResponseEntity<String> response = restTemplate.exchange(
"http://localhost:8080/context/path",
HttpMethod.GET, entity, String.class);
} catch (Exception e) {
System.out.println(e);
}
Also, intentionally I tried making a POST call to the get endpoint to see if it returns 405 Method not allowed. But to my wonder it still returned 400 Bad Request no body.

I finally figured it out. The restTemplate is configured to use a proxy. I removed the proxy and it is working fine now.

You can try something like:-
public void fetchAuthenticationToken() {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
headers.setAccept(List.of(MediaType.APPLICATION_JSON));
MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
map.add("client_id", applicationConfig.getTokenClientId());
map.add("client_secret", applicationConfig.getTokenClientSecret());
map.add("grant_type", "client_credentials");
map.add("username", applicationConfig.getTokenUsername());
map.add("password", applicationConfig.getTokenPassword());
HttpEntity<MultiValueMap<String, String>> entity = new HttpEntity<>(map, headers);
String tokenEndPoint = "{your endpoints URL}";
ResponseEntity<TokenResponse> responseEntity = testRestTemplate.exchange(tokenEndPoint,
HttpMethod.POST, entity, TokenResponse.class, new HashMap<String, String>());
assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.OK);
TokenResponse token = responseEntity.getBody();
assertThat(token).isNotNull();
System.out.println("Auth Token value is "+ token)
}

Related

no suitable HttpMessageConverter found for response type [class java.lang.Object] and content type [multipart/form-data;boundary=XXX;charset=UTF-8]

I am doing multipart formdata post call from UI to upload a file.
From UI, the call goes to component A controller which you can consider it as a common component or bus which just read the stream pass the stream to other component B controller through rest call which uploads the file and sends back metadata about uploaded file in json format.
Issue: The call successfully goes till component B controller, file got uploaded but when the response of component B reaches component A, I am getting below error
"message" : "Could not extract response: no suitable HttpMessageConverter found for response type [class java.lang.Object] and content type [multipart/form-data;boundary=HWhdmg6KNJw_kaP4wWnLyoAb9htc8StF4;charset=UTF-8]"
Can someone help pls?
Components A code
#PostMapping(value = "/v3/documents",consumes = MediaType.MULTIPART_FORM_DATA_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity uploadMultipartDocument(HttpServletRequest httpServletRequest,HttpServletResponse httpServletResponse) {
ResponseEntity<?> responseEntity = null;
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.MULTIPART_FORM_DATA);
headers.set(HznAppsHeaderConstant.DOCUMENT_TYPE, HznAppsUtil.getHeaderFromCustomHeaderParameterProvider(customHeaderParameterProvider, HznAppsHeaderConstant.DOCUMENT_TYPE));
InputStream stream =null;
MultiValueMap<String, Object> params= new LinkedMultiValueMap<String, Object>();
try{
ServletFileUpload upload = new ServletFileUpload();
FileItemIterator iterStream = upload.getItemIterator(req);
while (iterStream.hasNext()){
FileItemStream item = iterStream.next();
stream = item.openStream();
if (!item.isFormField() && item.getFieldName().equalsIgnoreCase("file")) {
InputStreamResource inputStream = new InputStreamResource(stream) {
#Override
public String getFilename() {
return item.getName();
}
#Override
public long contentLength() {
return -1;
}
};
params.add("file", inputStream);
break;
}
}
final HttpEntity<MultiValueMap<String, Object>> httpEntity = new HttpEntity<MultiValueMap<String, Object>>(params, headers);
restTemplate.getInterceptors().clear();
SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
requestFactory.setBufferRequestBody(false);
restTemplate.setRequestFactory(requestFactory);
responseEntity = restTemplate.exchange("Component B URL", HttpMethod.POST, httpEntity, Object.class);
} catch (Exception e) {
e.printStackTrace();
}
return responseEntity;
}
Component B code
#RequestMapping(value = "/api/v3/documents", produces = {"application/json"}, consumes = {"multipart/form-data"}, method = RequestMethod.POST)
public ResponseEntity uploadMultipartDocument(HttpServletRequest request) {
ResponseDocument responseDocument = null;
try {
responseDocument = documentsService.uploadMultiPartDocument(request,documentType); // Doing Soap call to upload document and its works fine in this method
} catch (Exception e) {
e.printStackTrace();
}
return new ResponseEntity<>(responseDocument, HttpStatus.OK);
}
Thanks

Spring Boot RestTemplate: Bad request when directly copying from postman

So I have an API request where I am copying the details directly from postman where it works. I am however getting a bad request error.
#Service
public class GraphApiService {
#Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
#Autowired
RestTemplate restTemplate;
#Autowired
Constants constants;
private final Logger logger = LoggerFactory.getLogger(this.getClass());
public ResponseEntity<String> getAccessTokenUsingRefreshToken(Credential cred) throws IOException{
try {
//https://learn.microsoft.com/en-us/graph/auth-v2-user
// section 5. Use the refresh token to get a new access token
String url = "url";
JSONObject body = new JSONObject();
body.put("grant_type", "refresh_token");
body.put("client_id", "clientid");
body.put("scope","User.Read offline_access Files.Read Mail.Read Sites.Read.All");
body.put("redirect_uri", "http://localhost");
body.put("client_secret","secret");
body.put("refresh_token", "token");
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
HttpEntity<String> request = new HttpEntity<String>(body.toString(), headers);
ResponseEntity<String> response= restTemplate.postForEntity(url, request,String.class);
return response;
}
catch(HttpClientErrorException e){
logger.error(e.getResponseBodyAsString());
logger.error(e.getMessage());
return null;
}
}
I would appreciate any help. The bad request error message from microsoft graph isn't a descriptive one that will help
You're sending JSON payload with FORM_URLENCODED header.
Either you need to check if API accepts json payload, if so you need to change content-type to application/json or you can post form data as follows.
public ResponseEntity<String> getAccessTokenUsingRefreshToken(Credential cred) throws IOException{
try {
//https://learn.microsoft.com/en-us/graph/auth-v2-user
// section 5. Use the refresh token to get a new access token
String url = "url";
MultiValueMap<String, String> multiValueMap= new LinkedMultiValueMap<String, String>();
multiValueMap.add("grant_type", "refresh_token");
multiValueMap.add("client_id", "clientid");
//.....
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(multiValueMap, headers);
ResponseEntity<String> response= restTemplate.postForEntity(url, request, String.class);
return response;
}catch(HttpClientErrorException e){
logger.error(e.getResponseBodyAsString());
logger.error(e.getMessage());
return null;
}
}

Spring-boot Resttemplate response.body is null while interceptor clearly shows body

With Spring-boot 1.5.10.RELEASE, I am getting response.body as null.
Here is how I am using RestTemplate
RestTemplate restTemplate = new RestTemplate();
List<ClientHttpRequestInterceptor> interceptors = new ArrayList<>();
interceptors.add(new LoggingRequestInterceptor());
restTemplate.setInterceptors(interceptors);
String url = "http://someurl/Commands";
MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
params.add("cmd", "{\"operation\":\"getSomeDetails\"}}");
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(params, headers);
ResponseEntity<String> response = restTemplate.postForEntity(url, request, String.class);
System.out.println("This is always null: " + response.getBody());
While above program always prints null,
following interceptor prints valid response body
public class LoggingRequestInterceptor implements ClientHttpRequestInterceptor {
final static Logger log = LoggerFactory.getLogger(LoggingRequestInterceptor.class);
#Override
public ClientHttpResponse intercept(final HttpRequest request, final byte[] body,
final ClientHttpRequestExecution execution) throws IOException {
traceRequest(request, body);
ClientHttpResponse response = execution.execute(request, body);
traceResponse(response);
return response;
}
private void traceResponse(ClientHttpResponse response) throws IOException {
StringBuilder inputStringBuilder = new StringBuilder();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(response.getBody(), "UTF-8"));
String line = bufferedReader.readLine();
while (line != null) {
inputStringBuilder.append(line);
inputStringBuilder.append('\n');
line = bufferedReader.readLine();
}
log.debug("============================response begin==========================================");
log.debug("Status code : {}", response.getStatusCode());
log.debug("Status text : {}", response.getStatusText());
log.debug("Headers : {}", response.getHeaders());
log.debug("Response body: {}", inputStringBuilder.toString());
log.debug("=======================response end=================================================");
}
}
Although the accepted answer has the reason, I believe the solution is also necessary.
Spring has a BufferingClientHttpRequestFactory that acts as a wrapper to Rest Template's default SimpleClientHttpRequestFactory.
It can be passed to a Rest Template during creation. This forces the Rest Template to make interceptors use a copy of the response rather than destroying it.
ClientHttpRequestFactory factory = new BufferingClientHttpRequestFactory(new SimpleClientHttpRequestFactory());
RestTemplate restTemplate = new RestTemplate(factory);
Source :
http://objectpartners.com/2018/03/01/log-your-resttemplate-request-and-response-without-destroying-the-body/
You're consuming the response body in traceResponse; that's your problem. Also, please update your question to be specific; "all latest" means nothing. What's latest today isn't so tomorrow.
Below code will resolve issue.
#Bean public RestTemplate restTemplate() {
final RestTemplate restTempate = new RestTemplate(new BufferingClientHttpRequestFactory(new
SimpleClientHttpRequestFactory()));
final List<ClientHttpRequestInterceptor> interceptors = new ArrayList<>();
interceptors.add(new LogHttpInterceptor());
restTempate.setInterceptors(interceptors);
return restTemplate;}
While log interceptor will be like below
public class LogHttpInterceptor implements ClientHttpRequestInterceptor {
final static Logger log = LoggerFactory.getLogger(LogHttpInterceptor.class);
#Override
public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException {
traceRequest(request, body);
ClientHttpResponse response = execution.execute(request, body);
traceResponse(response);
return response;
}
private void traceRequest(HttpRequest request, byte[] body) throws IOException {
log.info("===========================================================================request begin");
log.debug("URI : {}", request.getURI());
log.debug("Method : {}", request.getMethod());
log.debug("Headers : {}", request.getHeaders() );
log.debug("Request body: {}", new String(body, "UTF-8"));
log.info("=============================================================================request end");
}
private void traceResponse(ClientHttpResponse response) throws IOException {
StringBuilder inputStringBuilder = new StringBuilder();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(response.getBody(), "UTF-8"));
String line = bufferedReader.readLine();
while (line != null) {
inputStringBuilder.append(line);
inputStringBuilder.append('\n');
line = bufferedReader.readLine();
}
log.info("==========================================================================response begin");
log.debug("Status code : {}", response.getStatusCode());
log.debug("Status text : {}", response.getStatusText());
log.debug("Headers : {}", response.getHeaders());
log.debug("Response body: {}", inputStringBuilder.toString());
log.info("===========================================================================response end");
}
Let me know if doesn't work
After some time of searching I tried to use HttpComponentsClientHttpRequestFactory() instead of SimpleClientHttpRequestFactory()
ClientHttpRequestFactory factory = new BufferingClientHttpRequestFactory(new HttpComponentsClientHttpRequestFactory());
That solved the issue for me.
Create your RestTemplate like this
#Bean
public RestTemplate interceptedRestTemplate() {
RestTemplate restTemplate = new RestTemplate(new BufferingClientHttpRequestFactory(
new SimpleClientHttpRequestFactory()
));
restTemplate.setInterceptors(List.of(<i>your interceptor</i>));
return restTemplate;
}
worked for me.

Spring RestTemplate, getting junk response when http status code is 404

I am writing a rest proxy (it exposes the API and delegates call to other server) and it works fine for the normal case and also for 500 http status code, we get the response from the rest client.
But when we get 404 status code, the Rest API server returns the message but we get junk values from the RestTemplate. We need to pass the same response to other API user but cannot get the same response.
Message returned from REST API Server:
{
"status_code":"0",
"error":{
"code":"404",
"description":"Source not found"
}
}
Getting the below response by RestTemplate client:
Not able to paste the content, attaching the screen shot of the response.
Please see the code below.
#RequestMapping(value = "/api/**")
public #ResponseBody String apiProxy(#RequestBody String body, HttpMethod method, HttpServletRequest request,
HttpServletResponse response) throws URISyntaxException {
RestTemplate restTemplate = new RestTemplate(
new BufferingClientHttpRequestFactory(new SimpleClientHttpRequestFactory()));
restTemplate.setInterceptors(Collections.singletonList(new RestClientLoggingInterceptor()));
restTemplate.setErrorHandler(new CustomResponseErrorHandler());
restTemplate.getMessageConverters().add(new StringHttpMessageConverter());
HttpHeaders httpHeaders = new HttpHeaders();
Enumeration<String> headers = request.getHeaderNames();
String headerName = null;
String headerValue = null;
while (headers.hasMoreElements()) {
headerName = headers.nextElement();
headerValue = request.getHeader(headerName);
httpHeaders.set(headerName, headerValue);
}
HttpEntity<String> httpEntity = new HttpEntity<String>(body, httpHeaders);
URI uri = new URI(ServerProtocol, null, ServerDomain, Integer.valueOf(ServerPort),
request.getRequestURI(), request.getQueryString(), null);
ResponseEntity<String> responseEntity = null;
try {
responseEntity = restTemplate.exchange(uri, method, httpEntity, String.class);
} catch (RestClientResponseException e) {
response.setStatus(e.getRawStatusCode());
return e.getResponseBodyAsString();
}
response.setStatus(responseEntity.getStatusCode().value());
return responseEntity.getBody();
}
ResponseErrorHandler Class
public class CustomResponseErrorHandler extends DefaultResponseErrorHandler {
private static final Logger logger = LogManager.getLogger(CustomResponseErrorHandler.class);
#Override
public void handleError(ClientHttpResponse response) throws IOException {
logger.error("Response error: {} {}", response.getStatusCode(), response.getStatusText());
}
}
RestClientLoggingInterceptor Class
#Override
public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution)
throws IOException {
ClientHttpResponse response = execution.execute(request, body);
logger.debug("request method:" + request.getMethod());
logger.debug("request URI:" + request.getURI());
logger.debug("request headers:" + request.getHeaders());
logger.debug("request body:" + new String(body, Charset.forName("UTF-8")));
logger.debug("response status code:" + response.getStatusCode());
logger.debug("response headers:" + response.getHeaders());
logger.debug("response body:" + IOUtils.toString(response.getBody(), "UTF-8"));
return response;
}
Thanks
Cannot parse gzip encoded response with RestTemplate from Spring-Web
This was helpful to me for this same issue. You can try this out.

How to set an "Accept:" header on Spring RestTemplate request?

I want to set the value of the Accept: in a request I am making using Spring's RestTemplate.
Here is my Spring request handling code
#RequestMapping(
value= "/uom_matrix_save_or_edit",
method = RequestMethod.POST,
produces="application/json"
)
public #ResponseBody ModelMap uomMatrixSaveOrEdit(
ModelMap model,
#RequestParam("parentId") String parentId
){
model.addAttribute("attributeValues",parentId);
return model;
}
and here is my Java REST client:
public void post(){
MultiValueMap<String, String> params = new LinkedMultiValueMap<String, String>();
params.add("parentId", "parentId");
String result = rest.postForObject( url, params, String.class) ;
System.out.println(result);
}
This works for me; I get a JSON string from the server side.
My question is: how can I specify the Accept: header (e.g. application/json,application/xml, ... ) and request method (e.g. GET,POST, ... ) when I use RestTemplate?
I suggest using one of the exchange methods that accepts an HttpEntity for which you can also set the HttpHeaders. (You can also specify the HTTP method you want to use.)
For example,
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
HttpEntity<String> entity = new HttpEntity<>("body", headers);
restTemplate.exchange(url, HttpMethod.POST, entity, String.class);
I prefer this solution because it's strongly typed, ie. exchange expects an HttpEntity.
However, you can also pass that HttpEntity as a request argument to postForObject.
HttpEntity<String> entity = new HttpEntity<>("body", headers);
restTemplate.postForObject(url, entity, String.class);
This is mentioned in the RestTemplate#postForObject Javadoc.
The request parameter can be a HttpEntity in order to add additional
HTTP headers to the request.
You could set an interceptor "ClientHttpRequestInterceptor" in your RestTemplate to avoid setting the header every time you send a request.
public class HeaderRequestInterceptor implements ClientHttpRequestInterceptor {
private final String headerName;
private final String headerValue;
public HeaderRequestInterceptor(String headerName, String headerValue) {
this.headerName = headerName;
this.headerValue = headerValue;
}
#Override
public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException {
request.getHeaders().set(headerName, headerValue);
return execution.execute(request, body);
}
}
Then
List<ClientHttpRequestInterceptor> interceptors = new ArrayList<ClientHttpRequestInterceptor>();
interceptors.add(new HeaderRequestInterceptor("Accept", MediaType.APPLICATION_JSON_VALUE));
RestTemplate restTemplate = new RestTemplate();
restTemplate.setInterceptors(interceptors);
If, like me, you struggled to find an example that uses headers with basic authentication and the rest template exchange API, this is what I finally worked out...
private HttpHeaders createHttpHeaders(String user, String password)
{
String notEncoded = user + ":" + password;
String encodedAuth = Base64.getEncoder().encodeToString(notEncoded.getBytes());
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
headers.add("Authorization", "Basic " + encodedAuth);
return headers;
}
private void doYourThing()
{
String theUrl = "http://blah.blah.com:8080/rest/api/blah";
RestTemplate restTemplate = new RestTemplate();
try {
HttpHeaders headers = createHttpHeaders("fred","1234");
HttpEntity<String> entity = new HttpEntity<String>("parameters", headers);
ResponseEntity<String> response = restTemplate.exchange(theUrl, HttpMethod.GET, entity, String.class);
System.out.println("Result - status ("+ response.getStatusCode() + ") has body: " + response.hasBody());
}
catch (Exception eek) {
System.out.println("** Exception: "+ eek.getMessage());
}
}
Calling a RESTful API using RestTemplate
Example 1:
RestTemplate restTemplate = new RestTemplate();
// Add the Jackson message converter
restTemplate.getMessageConverters()
.add(new MappingJackson2HttpMessageConverter());
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
headers.set("Authorization", "Basic XXXXXXXXXXXXXXXX=");
HttpEntity<String> entity = new HttpEntity<String>("parameters", headers);
restTemplate.getInterceptors()
.add(new BasicAuthorizationInterceptor(USERID, PWORD));
String requestJson = getRequetJson(Code, emailAddr, firstName, lastName);
response = restTemplate.postForObject(URL, requestJson, MYObject.class);
Example 2:
RestTemplate restTemplate = new RestTemplate();
String requestJson = getRequetJson(code, emil, name, lastName);
HttpHeaders headers = new HttpHeaders();
String userPass = USERID + ":" + PWORD;
String authHeader =
"Basic " + Base64.getEncoder().encodeToString(userPass.getBytes());
headers.set(HttpHeaders.AUTHORIZATION, authHeader);
headers.setContentType(MediaType.APPLICATION_JSON);
headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
HttpEntity<String> request = new HttpEntity<String>(requestJson, headers);
ResponseEntity<MyObject> responseEntity;
responseEntity =
this.restTemplate.exchange(URI, HttpMethod.POST, request, Object.class);
responseEntity.getBody()
The getRequestJson method creates a JSON Object:
private String getRequetJson(String Code, String emailAddr, String name) {
ObjectMapper mapper = new ObjectMapper();
JsonNode rootNode = mapper.createObjectNode();
((ObjectNode) rootNode).put("code", Code);
((ObjectNode) rootNode).put("email", emailAdd);
((ObjectNode) rootNode).put("firstName", name);
String jsonString = null;
try {
jsonString = mapper.writerWithDefaultPrettyPrinter()
.writeValueAsString(rootNode);
}
catch (JsonProcessingException e) {
e.printStackTrace();
}
return jsonString;
}
Short solution without HttpHeaders creating:
RequestEntity<Void> request = RequestEntity.post(URI.create(url))
.accept(MediaType.APPLICATION_JSON)
.contentType(MediaType.APPLICATION_JSON)
// any other headers
.header("PRIVATE-TOKEN", "token")
.build();
ResponseEntity<String> response = restTemplate.exchange(request, String.class);
return response.getBody();
UPDATE: but in case specific headers HttpHeaders become simple:
RequestEntity.post(URI.create(AMOCRM_URL + url))
.contentType(MediaType.APPLICATION_JSON)
.headers(
new HttpHeaders() {{
setBearerAuth(getAccessToken());
}})
.body(...)
Here is a simple answer. Hope it helps someone.
import org.springframework.boot.devtools.remote.client.HttpHeaderInterceptor;
import org.springframework.http.MediaType;
import org.springframework.http.client.ClientHttpRequestInterceptor;
import org.springframework.web.client.RestTemplate;
public String post(SomeRequest someRequest) {
// create a list the headers
List<ClientHttpRequestInterceptor> interceptors = new ArrayList<>();
interceptors.add(new HttpHeaderInterceptor("Accept", MediaType.APPLICATION_JSON_VALUE));
interceptors.add(new HttpHeaderInterceptor("ContentType", MediaType.APPLICATION_JSON_VALUE));
interceptors.add(new HttpHeaderInterceptor("username", "user123"));
interceptors.add(new HttpHeaderInterceptor("customHeader1", "c1"));
interceptors.add(new HttpHeaderInterceptor("customHeader2", "c2"));
// initialize RestTemplate
RestTemplate restTemplate = new RestTemplate();
// set header interceptors here
restTemplate.setInterceptors(interceptors);
// post the request. The response should be JSON string
String response = restTemplate.postForObject(Url, someRequest, String.class);
return response;
}

Resources