Authentication for POST REST API with spring restTemplate - spring

I want to use Spring RESTTemplate to post an Object to a web server and get one back.
Here the piece of code:
String authStringEncoded =
Base64.getEncoder().encodeToString
("582f3e4a9e933168ea1048e6:98c6f2736c5f02279d767ce7ddfe7e5d".getBytes("utf-8"));
HttpHeaders headers = new HttpHeaders();
headers.add("Authorization", "Basic " + authStringEncoded);
HttpEntity<String> request = new HttpEntity<String>(headers);
RestTemplate rt = new RestTemplate();
rt.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
rt.getMessageConverters().add(new StringHttpMessageConverter());
String uri = new String(REGISTERING_NEW_DEVICES.replace("{devicetype-id}", KIT_TYPE_ID));
TdkDevice deviceC3DF86B = new TdkDevice();
deviceC3DF86B.setId("C3DF86B");
deviceC3DF86B.setPal("44CFFFC9D5F8E8B2F36");
DeviceRegistration deviceRegistration = new DeviceRegistration();
deviceRegistration.getIds().add(deviceC3DF86B);
rt.postForObject(uri, HttpMethod.POST, request, deviceRegistration, DeviceRegistration.class);
But I got a compilation error:
The method postForObject(String, Object, Class<T>, Object...) in the type RestTemplate is not applicable for the arguments (String, HttpMethod, HttpEntity<String>, DeviceRegistration,
Class<DeviceRegistration>)

Your service call should be like following:
rt.postForObject(uri, request, DeviceRegistration.class);
According to spring RestTemplate api, postForObject method's parameters should be following:
Parameters:
url - the URL
request - the Object to be POSTed (may be null)
responseType - the type of the return value
uriVariables - the variables to expand the template
API Reference

Related

Passing RequestParam data to Spring RestController

I am using restTemplate.exchangemethod to invoke one service from another service.My request url does accept a request parameter.
url is of the formhttp://localhost:8035/sgapp/student/fetchDeptNo?sid
In the conttroller it is written as
#RestController
#RequestMapping(value="/sgapp/student")
public class SiController{
#GetMapping(value = "/fetchDeptNo",consumes = "application/x-www-form-urlencoded")
public ResponseEntity<String> getSid(#RequestParam(name = "sid")String sid){
String sid = myRepo.getSidCode(sid);
System.out.println("sid received from DB::"+sid);
return new ResponseEntity<String>(sid,HttpStatus.OK);
}
}
In the caller application I am invoking it as
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
HttpEntity<?> entity = new HttpEntity<>(headers);
Map paramMap = new HashMap<String, String>();
paramMap.put("sid", sidData);
HttpEntity<String> sidRespnse = restTemplate.exchange(
"http://localhost:8035/sgapp/student/fetchDeptNo", HttpMethod.GET, entity, String.class,
paramMap);
But I'm getting folllowing exception:
org.springframework.web.client.HttpClientErrorException: 400 null
at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:94) ~[spring-web-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:79) ~[spring-web-5.0.6.RELEASE.jar:5.0.6.RELEASE]
Can anyone provide any suitable solution to this???
That particular exchange method is used to substitute variables into the path.
If you want to pass query parameters, use UriComponentsBuilder to create the URL with query params:
UriComponentsBuilder builder =
UriComponentsBuilder
.fromHttpUrl(rootUri)
.queryParam("sid", sidData);
Then you can use RestTemplate as follows:
restTemplate.exchange(
builder.toUriString(),
HttpMethod.GET,
entity,
String.class);

413 request entity too large issue in HTTP Get method call

Please don't mistake it as already asked question. The main difference here is, this issue is coming in Get method call. All the solutions discussed here or other places talks about either POST method or multipart form data.
Configuration I have provided is as below:
String url = env.getProperty(ApplicationConstants.PMCC_MANAGER_REGION_QUERY_URL);
UriComponentsBuilder builder = UriComponentsBuilder.fromUriString(url).queryParam("inTIS_PMA_NUMBER","ALL");
URI uri = builder.build().toUri();
RestTemplate restTemplate = getRestTemplateBuilder().build();
HttpHeaders headers = new HttpHeaders();
headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
HttpEntity<String> entity = new HttpEntity<String>("parameters", headers);
ResponseEntity<String> response = restTemplate.exchange(uri, HttpMethod.GET, entity, String.class);
private RestTemplateBuilder getRestTemplateBuilder() {
Integer connectionTimeOut = 2000;
Integer readTimeOut = 3000;
RestTemplateBuilder restTemplateBuilder = new RestTemplateBuilder();
restTemplateBuilder.setConnectTimeout(connectionTimeOut);
restTemplateBuilder.setReadTimeout(readTimeOut);
SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
factory.setBufferRequestBody(false);
restTemplateBuilder.requestFactory(factory);
return restTemplateBuilder;
}
This code is part of Spring Boot application and deployed in WebLogic server.

spring boot application periodic post request via resttemplate in json

Below is my spring boot code snippet to post json data to server url every few min to tell that I am alive and running(which loads my json input data to db). purpose of this post request is to update the status on application monitoring tool.
What could be the right approach to implment this behaviour in my spring boot app? Is their any decorator api to do such post request to url, every few miuntes through out the application.? how can I know the time of successful post request to do next post request ? Please help me. Thanks in advance.
RestTemplate restTemplate = new RestTemplate();
String url = "endpoint url";
String requestJson = "{\"I am alive\":\"App name?\"}";
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<String> entity = new HttpEntity<String>(requestJson,headers);
String answer = restTemplate.postForObject(url, entity, String.class);
System.out.println(answer);
Why don't you use the #Scheduled annotation? This will seutes.nd your REST request every 3 minutes...
#Component
public class Heartbeater {
#Scheduled(fixedDelay = 180000)
public void heartbeat() {
// Your code is below...
RestTemplate restTemplate = new RestTemplate();
String url = "endpoint url";
String requestJson = "{\"I am alive\":\"App name?\"}";
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<String> entity = new HttpEntity<String>(requestJson,headers);
String answer = restTemplate.postForObject(url, entity, String.class);
System.out.println(answer);
}

How to not escape form body characters in Spring RestTemplate when making a POST request?

I have following code where I am making a POST form request. The request body contains username and password. Password contains # characters, which is replaced by RestTemplate with %40 and I am getting "unauthorized" error as the password is wrong now.
Following is the debug info from bufferOutput(request body)
merchant_id=firstname+de-lastname%40gmail.com&password=%40Password
Here is the code snippet that is making the call.
MultiValueMap<String, String> formData = new LinkedMultiValueMap<String, String>();
String url = "SOME_URL";
formData.add("username", "xay#gmail.com");
formData.add("password", "#name321");
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
HttpEntity<MultiValueMap<String,String>> requestEntity = new HttpEntity<MultiValueMap<String,String>>(formData,headers);
RestTemplate restTemplate = new RestTemplate();
restTemplate.getMessageConverters()
.add(0, new StringHttpMessageConverter(Charset.forName("UTF-8")));
restTemplate.exchange(url, HttpMethod.POST, requestEntity, Authentication.class,"321");
The question is how to tell restTemplate not to escape body data ?
Note that the request has to be a post form request and I can not use UriComponentsBuilder to fix the problem.
I think you need to add a FormHttpMessageConverter to your RestTemplate rather than a StringHttpMessageConverter.

Spring RestTemplate redirect 302

I'm trying to use spring rest template to do a post request to login in.
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
LinkedMultiValueMap<String, Object> mvm = new LinkedMultiValueMap<String, Object>();
mvm.add("LoginForm_Login", "login");
mvm.add("LoginForm_Password", "password");
ResponseEntity<String> result = restTemplate.exchange(uriDWLogin, HttpMethod.POST, requestEntity, String.class);
My ResponseEntity status is 302, i want to follow this request to get the body response , because i didn't get the body for this request.
18:59:59.170 MAIN [http-nio-8080-exec-83] DEBUG c.d.s.c.DemandwareCtlr - loginToSandbox - StatusResponse - 302
18:59:59.170 MAIN [http-nio-8080-exec-83] DEBUG c.d.s.c.DemandwareCtlr - loginToSandbox - BodyResponse -
What can I do to solve this problem ?!
The redirection is followed automatically if the request is a GET request (see this answer). To make it happen on POST requests, one option might be to use a different request factory, like HttpComponentsClientHttpRequestFactory, and set it to use an HttpClient with the required settings to follow the redirect (see LaxRedirectStrategy):
final RestTemplate restTemplate = new RestTemplate();
final HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory();
final HttpClient httpClient = HttpClientBuilder.create()
.setRedirectStrategy(new LaxRedirectStrategy())
.build();
factory.setHttpClient(httpClient);
restTemplate.setRequestFactory(factory);
I haven't tested, but this should work.

Resources