Configuring Spring RestTemplate - java

Have the following code for getting calling the REST service
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
String plainCreds = "test:test2";
byte[] plainCredsBytes = plainCreds.getBytes();
String base64Creds = DatatypeConverter.printBase64Binary(plainCredsBytes);
headers.add("Authorization", "Basic " + base64Creds);
headers.add("Content-type","application/x-www-form-urlencoded;charset=utf-8");
headers.set("Accept", MediaType.APPLICATION_XML_VALUE);
UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(baseUrl)
.queryParam("id", "id1234");
HttpEntity<String> entity = new HttpEntity<>(headers);
ResponseEntity<String> response = restTemplate.exchange(
builder.build().encode().toUri(),
HttpMethod.GET, entity, String.class);
Have the following doubts for this-
Can I use factory pattern for getting RestTemplate instead of using new. What will be the advantages and disadvantages of it.
Currently adding the credentials into headers in the above code. Is there some better way to achieve it(example in configuration or some other way that can be suitable for production code).
Thanks

The general usage pattern of RestTemplate is that you configure one in the way you want it and then reuse that througouht all your application. It is thread safe but can be expensive to create so creating as few as possible (ideally just one) and reusing them is what you should do.
There are ways of configuring the RestTemplate to automatically add basic authentication to all requests but IMO it's too complex to be worth it - you need to mess around a bit with Http Components and create your own request factory so I think the easiest solution is to just break out the manual step into a helper class.
--
public class RestTemplateUtils {
public static final RestTemplate template;
static {
// Init the RestTemplate here
template = new RestTemplate();
}
/**
* Add basic authentication to some {#link HttpHeaders}.
* #param headers The headers to add authentication to
* #param username The username
* #param password The password
*/
public static HttpHeaders addBasicAuth(HttpHeaders headers, String username, String password) {
String plainCreds = username + ":" + password;
byte[] plainCredsBytes = plainCreds.getBytes();
String base64Creds = DatatypeConverter.printBase64Binary(plainCredsBytes);
headers.add("Authorization", "Basic " + base64Creds);
return headers;
}
}
Your code now turns into:
HttpHeaders headers = RestTemplateUtils.addBasicAuth(new HttpHeaders(),
"test", "test");
headers.add("Content-type","application/x-www-form-urlencoded;charset=utf-8");
headers.set("Accept", MediaType.APPLICATION_XML_VALUE);
UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(baseUrl)
.queryParam("id", "id1234");
HttpEntity<String> entity = new HttpEntity<>(headers);
ResponseEntity<String> response = RestTemplateUtils.template.exchange(
builder.build().encode().toUri(),
HttpMethod.GET, entity, String.class);
Though I'd suggest adding a few more helper methods to create an entity and add any other standard headers to it.

Related

Spring Boot - Rest templates seems to ignore accept header set through the HttpEntity

I am making a call to one of the Jasper server API endpoints and I have to set the header "Accept" to "application/json" for the service to return a JSON response. I have validated the API from Postman -
When I try to simulate the same behavior from my Spring Boot rest client, I try to set the accept header to 'application/json' but Spring seems to ignore the same and adds the accept header as shown below -
I have validated the same by enabling DEBUG for rest template using the following parameter -
logging.level.org.springframework.web.client.RestTemplate=DEBUG
Below is the code snippet for my rest client -
HttpHeaders headers = new HttpHeaders();
headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
headers.setContentType(MediaType.APPLICATION_JSON);
headers.setBasicAuth(serviceUsername, servicePassword, StandardCharsets.UTF_8);
ResponseEntity<String> response = null;
String url = serviceEndpoint + "?reportUnitURI="
+ URLEncoder.encode(reportPath, StandardCharsets.UTF_8.toString()).replaceAll("\\+", "%20")
+ "&label=" + URLEncoder.encode(label, StandardCharsets.UTF_8.toString()).replaceAll("\\+", "%20");
LOGGER.info("URL : " + url);
HttpEntity<String> requestEntity = new HttpEntity<String>("",
headers);
response = restTemplate.exchange(url, HttpMethod.GET, requestEntity, String.class);
Can someone please help explain the behavior here?
Why does my header values for 'accept' gets ignored?
What could be done to pass the 'accept' header properly?
Even though the code sets the accept header, the HttpMessageConverter used my scenario (StringHttpMessageConverter) does not allow changes on the accept headers and maintains the default values.
To get past that I have modified the StringHttpMessageConverter behavior at runtime to allow setting the preferred accept header.
#Bean
public RestTemplate getRestTemplate() {
final RestTemplate restTemplate = new RestTemplate();
final List<HttpMessageConverter<?>> converters = new ArrayList<>();
for (HttpMessageConverter converter : restTemplate.getMessageConverters()) {
if (converter instanceof StringHttpMessageConverter) {
((StringHttpMessageConverter) converter).setWriteAcceptCharset(true);
((StringHttpMessageConverter) converter).setSupportedMediaTypes(Collections.singletonList(MediaType.APPLICATION_JSON));
converters.add(converter);
}
}
restTemplate.setMessageConverters(converters);
return restTemplate;
}
Now, the framework allows my REST client to modify the header, code snippet below -
HttpHeaders headers = new HttpHeaders();
headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
headers.setBasicAuth(serviceUsername, new String(new DecryptionService().decrypt(servicePassword)), StandardCharsets.UTF_8);
ResponseEntity<String> response = null;
try {
String url = serviceEndpoint + "?reportUnitURI=" + reportPath + "&label=" + processLabel(label, false);
HttpEntity<String> requestEntity = new HttpEntity<String>("",
headers);
response = restTemplate.exchange(url, HttpMethod.GET, requestEntity, String.class);
//more stuff

Proper way to get Oath2 access token and call another service in Java Spring Boot

I want to get the oath2 access token and using this I want to call an another service.
Below code does the same it gets the access token and call an another API using that. Using the below code I am able to do what ever I want with the below code.
But I am new to Spring Security I just want to know if there is a better way to do this. Like rather than making a separate call to get the token and then call the service can i do it in a single call? Or Using any other class provided by Spring can I write this in a better way ?
public class TestAPIToken{
#RequestMapping(value = "/showEmployees", method = RequestMethod.GET)
public ModelAndView showEmployees(#RequestParam("code") String code) throws JsonProcessingException, IOException {
String accessToken = getAccessToken();
System.out.println("API Token ---------" + accessToken);
HttpEntity<String> response = getResponseByCallingWithToken(accessToken);
System.out.println("API Response ---------" + response.getBody());
return null;
}
private HttpEntity<String> getResponseByCallingWithToken(String accessToken) {
HttpHeaders headers = new HttpHeaders();
headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
headers.add("Authorization", "Bearer " + accessToken);
UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(url)
.queryParam("msisdn", msisdn)
.queryParam("email", email);
HttpEntity<?> entity = new HttpEntity<>(headers);
HttpEntity<String> response = restTemplate.exchange(
builder.toUriString(),
HttpMethod.GET,
entity,
String.class);
reponse.getBody();
return response;
}
private String getAccessToken() {
ResponseEntity<String> response = null;
System.out.println("Authorization Code------" + code);
RestTemplate restTemplate = new RestTemplate();
// According OAuth documentation we need to send the client id and secret key in the header for authentication
String encodedCredentials = new String(Base64.encodeBase64(credentials.getBytes()));
HttpHeaders headers = new HttpHeaders();
headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
headers.add("Authorization", "Basic " + encodedCredentials);
MultiValueMap<String, String> body = new LinkedMultiValueMap<>();
body.add("scope","scope,value");
body.add("grant_type","scope,value");
HttpEntity<String> request = new HttpEntity<String>(body, headers);
String access_token_url = "http://localhost:8080/oauth2/token";
ResponseEntity<TokenModel> response = restTemplate.exchange(access_token_url, HttpMethod.POST, request, TokenModel.class);
String accessToken = response.getBody().access_token;
return accessToken;
}
}
class TokenModel{
String access_token;
String scope;
String token_type;
String expires_in;
}
I am new to Spring security. Please help even if this seems simple to you
NB: This question does not have an exact duplicate

How to make a rest api call in java and map the response object?

I'm currently developing my first java program who'll make a call to a rest api(jira rest api, to be more especific).
So, if i go to my browser and type the url =
"http://my-jira-domain/rest/api/latest/search?jql=assignee=currentuser()&fields=worklog"
I get a response(json) with all the worklogs of the current user.
But my problem is, how i do my java program to do this ?
Like,connect to this url, get the response and store it in a object ?
I use spring, with someone know how to this with it.
Thx in advance guys.
Im adding, my code here:
RestTemplate restTemplate = new RestTemplate();
String url;
url = http://my-jira-domain/rest/api/latest/search/jql=assignee=currentuser()&fields=worklog
jiraResponse = restTemplate.getForObject(url,JiraWorklogResponse.class);
JiraWorkLogResponse is a simple class with some attributes only.
Edit,
My entire class:
#Controller
#RequestMapping("/jira/worklogs")
public class JiraWorkLog {
private static final Logger logger = Logger.getLogger(JiraWorkLog.class.getName() );
#RequestMapping(path = "/get", method = RequestMethod.GET, produces = "application/json")
public ResponseEntity getWorkLog() {
RestTemplate restTemplate = new RestTemplate();
String url;
JiraProperties jiraProperties = null;
url = "http://my-jira-domain/rest/api/latest/search?jql=assignee=currentuser()&fields=worklog";
ResponseEntity<JiraWorklogResponse> jiraResponse;
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders = this.createHeaders();
try {
jiraResponse = restTemplate.exchange(url, HttpMethod.GET, new HttpEntity<Object>(httpHeaders),JiraWorklogResponse.class);
}catch (Exception e){
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(e.getMessage());
}
return ResponseEntity.status(HttpStatus.OK).body(jiraResponse);
}
private HttpHeaders createHeaders(){
HttpHeaders headers = new HttpHeaders(){
{
set("Authorization", "Basic something");
}
};
return headers;
}
This code is returning :
org.springframework.http.converter.HttpMessageNotWritableException
Anyone knows why ?
All you need is http client. It could be for example RestTemplate (related to spring, easy client) or more advanced and a little more readable for me Retrofit (or your favorite client).
With this client you can execute requests like this to obtain JSON:
RestTemplate coolRestTemplate = new RestTemplate();
String url = "http://host/user/";
ResponseEntity<String> response
= restTemplate.getForEntity(userResourceUrl + "/userId", String.class);
Generally recommened way to map beetwen JSON and objects/collections in Java is Jackson/Gson libraries. Instead them for quickly check you can:
Define POJO object:
public class User implements Serializable {
private String name;
private String surname;
// standard getters and setters
}
Use getForObject() method of RestTemplate.
User user = restTemplate.getForObject(userResourceUrl + "/userId", User.class);
To get basic knowledge about working with RestTemplate and Jackson , I recommend you, really great articles from baeldung:
http://www.baeldung.com/rest-template
http://www.baeldung.com/jackson-object-mapper-tutorial
Since you are using Spring you can take a look at RestTemplate of spring-web project.
A simple rest call using the RestTemplate can be:
RestTemplate restTemplate = new RestTemplate();
String fooResourceUrl = "http://localhost:8080/spring-rest/foos";
ResponseEntity<String> response = restTemplate.getForEntity(fooResourceUrl + "/1", String.class);
assertThat(response.getStatusCode(), equalTo(HttpStatus.OK));
The issue could be because of the serialization. Define a proper Model with fields coming to the response. That should solve your problem.
May not be a better option for a newbie, but I felt spring-cloud-feign has helped me to keep the code clean.
Basically, you will be having an interface for invoking the JIRA api.
#FeignClient("http://my-jira-domain/")
public interface JiraClient {
#RequestMapping(value = "rest/api/latest/search?jql=assignee=currentuser()&fields=", method = GET)
JiraWorklogResponse search();
}
And in your controller, you just have to inject the JiraClient and invoke the method
jiraClient.search();
And it also provides easy way to pass the headers.
i'm back and with a solution (:
#Controller
#RequestMapping("/jira/worklogs")
public class JiraWorkLog {
private static final Logger logger = Logger.getLogger(JiraWorkLog.class.getName() );
#RequestMapping(path = "/get", method = RequestMethod.GET, produces = "application/json")
public ResponseEntity<JiraWorklogIssue> getWorkLog(#RequestParam(name = "username") String username) {
String theUrl = "http://my-jira-domain/rest/api/latest/search?jql=assignee="+username+"&fields=worklog";
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<JiraWorklogIssue> response = null;
try {
HttpHeaders headers = createHttpHeaders();
HttpEntity<String> entity = new HttpEntity<>("parameters", headers);
response = restTemplate.exchange(theUrl, HttpMethod.GET, entity, JiraWorklogIssue.class);
System.out.println("Result - status ("+ response.getStatusCode() + ") has body: " + response.hasBody());
}
catch (Exception eek) {
System.out.println("** Exception: "+ eek.getMessage());
}
return response;
}
private HttpHeaders createHttpHeaders()
{
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
headers.add("Authorization", "Basic encoded64 username:password");
return headers;
}
}
The code above works, but can someone explain to me these two lines ?
HttpEntity<String> entity = new HttpEntity<>("parameters", headers);
response = restTemplate.exchange(theUrl, HttpMethod.GET, entity, JiraWorklogIssue.class);
And, this is a good code ?
thx (:

Calling RESTlet API from Spring Framework

I have a POST API written in Restlet framework which accepts the data in org.restlet.representation.Representation form, I want to hit the service with some variables and there values from Spring project. How to do that?
Right now I am using the HTTPHeaders to send the data but the API is not accepting the values, all the fields the API is showing as NULL. The code is as follows:
final String uri = "http://localhost:8080/MyServices/adduser";
String userid = "05580a6caa7244a6986ca834403f1a93";
String usertype = "buyer";
String username = "shivam42";
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
headers.add("userid", userid);
headers.add("usertype", usertype);
headers.add("username", username);
HttpEntity<String> entity = new HttpEntity<String>("parameters", headers);
ResponseEntity<String> result = restTemplate.exchange(uri, HttpMethod.POST, entity, String.class);
System.out.println(result);
And the service is like this:
#Post
public String newUser(Representation entity) {
Form form = new Form(entity);
String userid = form.getValues("userid");
String usertype = form.getValues("usertype");
String username = form.getValues("username");
System.out.println(userid);
System.out.println(usertype);
System.out.println(username);
return userid;
}
This is the code generated from curl Maybe someone can help me with this:
curl -X POST -H "Cache-Control: no-cache" -H "Postman-Token: 33e6a1c5-c1c9-694f-3d7f-26cbcea61870" -H "Content-Type: application/x-www-form-urlencoded" -d 'userid=05580a6caa7244a6986ca834403f1a93&usertype=buyer&username=shivam42' "http://localhost:8080/MyServices/adduser"
When I am calling the API from POSTMAN it is giving me the correct userid, now how to call it from Spring project? Am I doing something wrong?
#Shivam Thanks for updating the question. With the curl command in place I now see that the data you basically wanted to send is inside the request's body. Therefore the first approach with HttpHeaders won't work. Here's an example of how it could look like for your first approach using the exchange method of Springs RestTemplate:
#Test
public void test() {
RestTemplate restTemplate = new RestTemplate();
final String uri = "http://localhost:8080/adduser";
String userid = "05580a6caa7244a6986ca834403f1a93";
String usertype = "buyer";
String username = "shivam42";
// create request body
JSONObject request = new JSONObject();
request.put("userid", userid);
request.put("usertype", usertype);
request.put("username", username);
// set headers
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<String> entity = new HttpEntity<>(request.toString(), headers);
ResponseEntity<String> result = restTemplate.exchange(uri, HttpMethod.POST, entity, String.class);
System.out.println(result.getBody());
}
This should also work as expected and return the userid. See also POST request via RestTemplate in JSON for further information.
From the Spring forum I found the solution to this.
Now my code is:
final String uri = "http://localhost:8080/MyServices/adduser";
String userid = "05580a6caa7244a6986ca834403f1a93";
String usertype = "buyer";
String username = "shivam42";
MultiValueMap<String, String> params = new LinkedMultiValueMap<String, String>();
params.add("userid", userid);
params.add("usertype", usertype);
params.add("username", username);
RestTemplate restTemplate = new RestTemplate();
HttpMessageConverter formHttpMessageConverter = new FormHttpMessageConverter();
HttpMessageConverter stringHttpMessageConverternew = new StringHttpMessageConverter();
List<HttpMessageConverter<?>> messageConverters = new ArrayList<HttpMessageConverter<?>>();
messageConverters.add(stringHttpMessageConverternew);
messageConverters.add(formHttpMessageConverter);
restTemplate.setMessageConverters(messageConverters);
System.out.println(restTemplate.postForObject(uri, params, String.class));
In my case I am also getting the expected result If I exclude the following code:
HttpMessageConverter formHttpMessageConverter = new FormHttpMessageConverter();
HttpMessageConverter stringHttpMessageConverternew = new StringHttpMessageConverter();
List<HttpMessageConverter<?>> messageConverters = new ArrayList<HttpMessageConverter<?>>();
messageConverters.add(stringHttpMessageConverternew);
messageConverters.add(formHttpMessageConverter);
restTemplate.setMessageConverters(messageConverters);

Basic authentication for REST API using spring restTemplate

I am completely new in RestTemplate and basically in the REST APIs also. I want to retrieve some data in my application via Jira REST API, but getting back 401 Unauthorised. Found and article on jira rest api documentation but don't really know how to rewrite this into java as the example uses the command line way with curl. I would appreciate any suggestion or advice how to rewrite:
curl -D- -X GET -H "Authorization: Basic ZnJlZDpmcmVk" -H "Content-Type: application/json" "http://kelpie9:8081/rest/api/2/issue/QA-31"
into java using spring rest template. Where the ZnJlZDpmcmVk is a base64 encoded string of username:password. Thank you very much.
Taken from the example on this site, I think this would be the most natural way of doing it, by filling in the header value and passing the header to the template.
This is to fill in the header Authorization:
String plainCreds = "willie:p#ssword";
byte[] plainCredsBytes = plainCreds.getBytes();
byte[] base64CredsBytes = Base64.encodeBase64(plainCredsBytes);
String base64Creds = new String(base64CredsBytes);
HttpHeaders headers = new HttpHeaders();
headers.add("Authorization", "Basic " + base64Creds);
And this is to pass the header to the REST template:
HttpEntity<String> request = new HttpEntity<String>(headers);
ResponseEntity<Account> response = restTemplate.exchange(url, HttpMethod.GET, request, Account.class);
Account account = response.getBody();
You may use spring-boot RestTemplateBuilder
#Bean
RestOperations rest(RestTemplateBuilder restTemplateBuilder) {
return restTemplateBuilder.basicAuthentication("user", "password").build();
}
See documentation
(before SB 2.1.0 it was #basicAuthorization)
There are multiple ways to add the basic HTTP authentication to the RestTemplate.
1. For a single request
try {
// request url
String url = "https://jsonplaceholder.typicode.com/posts";
// create auth credentials
String authStr = "username:password";
String base64Creds = Base64.getEncoder().encodeToString(authStr.getBytes());
// create headers
HttpHeaders headers = new HttpHeaders();
headers.add("Authorization", "Basic " + base64Creds);
// create request
HttpEntity request = new HttpEntity(headers);
// make a request
ResponseEntity<String> response = new RestTemplate().exchange(url, HttpMethod.GET, request, String.class);
// get JSON response
String json = response.getBody();
} catch (Exception ex) {
ex.printStackTrace();
}
If you are using Spring 5.1 or higher, it is no longer required to manually set the authorization header. Use headers.setBasicAuth() method instead:
// create headers
HttpHeaders headers = new HttpHeaders();
headers.setBasicAuth("username", "password");
2. For a group of requests
#Service
public class RestService {
private final RestTemplate restTemplate;
public RestService(RestTemplateBuilder restTemplateBuilder) {
this.restTemplate = restTemplateBuilder
.basicAuthentication("username", "password")
.build();
}
// use `restTemplate` instance here
}
3. For each and every request
#Bean
RestOperations restTemplateBuilder(RestTemplateBuilder restTemplateBuilder) {
return restTemplateBuilder.basicAuthentication("username", "password").build();
}
I hope it helps!
As of Spring 5.1 you can use HttpHeaders.setBasicAuth
Create Basic Authorization header:
String username = "willie";
String password = ":p#ssword";
HttpHeaders headers = new HttpHeaders();
headers.setBasicAuth(username, password);
...other headers goes here...
Pass the headers to the RestTemplate:
HttpEntity<String> request = new HttpEntity<String>(headers);
ResponseEntity<Account> response = restTemplate.exchange(url, HttpMethod.GET, request, Account.class);
Account account = response.getBody();
Documentation:
https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/http/HttpHeaders.html#setBasicAuth-java.lang.String-java.lang.String-
(maybe) the easiest way without importing spring-boot.
restTemplate.getInterceptors().add(new BasicAuthorizationInterceptor("user", "password"));
Reference Spring Boot's TestRestTemplate implementation as follows:
https://github.com/spring-projects/spring-boot/blob/v1.2.2.RELEASE/spring-boot/src/main/java/org/springframework/boot/test/TestRestTemplate.java
Especially, see the addAuthentication() method as follows:
private void addAuthentication(String username, String password) {
if (username == null) {
return;
}
List<ClientHttpRequestInterceptor> interceptors = Collections
.<ClientHttpRequestInterceptor> singletonList(new BasicAuthorizationInterceptor(
username, password));
setRequestFactory(new InterceptingClientHttpRequestFactory(getRequestFactory(),
interceptors));
}
Similarly, you can make your own RestTemplate easily
by inheritance like TestRestTemplate as follows:
https://github.com/izeye/samples-spring-boot-branches/blob/rest-and-actuator-with-security/src/main/java/samples/springboot/util/BasicAuthRestTemplate.java
Instead of instantiating as follows:
TestRestTemplate restTemplate = new TestRestTemplate();
Just do it like this:
TestRestTemplate restTemplate = new TestRestTemplate(user, password);
It works for me, I hope it helps!
HttpHeaders headers = new HttpHeaders();
headers.setBasicAuth(username, password);
then continue with the same procedure mentioned by the others here:
HttpEntity<String> request = new HttpEntity<String>(headers);
ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.GET,
request, String.class);
Use setBasicAuth to define credentials
HttpHeaders headers = new HttpHeaders();
headers.setBasicAuth("myUsername", myPassword);
Then create the request like you prefer.
Example:
HttpEntity<String> request = new HttpEntity<String>(headers);
ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.GET,
request, String.class);
String body = response.getBody();
I'm using spring version 5.3.15 for my unit test environment. I used withBasicAuth for my tests :
#SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class MyTestClass {
...
#Autowired
private TestRestTemplate restTemplate;
...
#Test
#SneakyThrows
public void TestGetSettings(){
DtoClass dtoClass = this.restTemplate
.withBasicAuth(UserServices.DEFAULT_USER, UserServices.DEFAULT_PASSWORD)
.getForObject(String.format("http://localhost:%d/setting",
port), DtoClass.class);
assertThat(dtoClass.getClientAddress()).isNotEmpty();
}
...
}
As you see this method only work for basic authentication. If you look at the details of the withBasicAuth method, you will find that the method source will be like this:
// TestRestTemplate.java file:
...
public class TestRestTemplate {
...
private final RestTemplateBuilder builder;
...
public TestRestTemplate withBasicAuth(String username, String password) {
TestRestTemplate template = new TestRestTemplate(this.builder, username, password, this.httpClientOptions);
...
}
}
As a result, for other types of authentication you can use the RestTemplateBuilder as a builder which is mentioned in other answers.
Follow Step By Step
I added Client Credentials In application.Properties file like below...
http.basicauth.username = yourUserName
http.basicauth.password = yourPassword
And , Then I created one class With two fields Because I'm loading those two fields from the Application.Properties file : username and password . Make sure your class is annotated with #Component..
#Value("${http.basicauth.username}")
private String username;
#Value("${http.basicauth.password}")
private String password;
And Then , You need to autowired above class From Wherever you want..
// I'm getting a username and password from application.properties file
String userCredentials = referenceClassName.getUsername()+":"+referenceClassName.getPassword();
// Encoded User Credentials and Convert it into a String
String encodedUserCredentials= Base64.getMimeEncoder().encodeToString(userCredentialsBytes.getBytes());
headers.set("Authorization", "Basic " +base64UserCredentials);
HttpEntity request = new HttpEntity(headers);
String url = "externalUrl";
// Getting a Json String body
String body = restTemplate.exchange(url,HttpMethod.GET,request,String.class).getBody();
Note :: For getting an Access Token from String Json body , That's why I converted it into a Json Object
JsonObject tokenJsonObject = new JsonParser().parse(body).getAsJsonObject();
// Getting access token as string from tokenJsonObject
String accessToken = tokenJsonObject.has("access_token") && !tokenJsonObject.get("access_token").isJsonNull() ? tokenJsonObject.get("access_token").getAsString() : "";
If you have any concerns, please let me know in comments..Hope It will helpful to you..
I have been using Spring above 5.1.x
// create headers for basic auth
var headers = new HttpHeaders();
headers.setBasicAuth("username", "password");

Categories