How to fetch data from http response entity? - java

I am using SpringBoot to fetch access Token from my client. I could not separate the Access Token from the responseEntity. Is there a way to Fetch the AccessToken data alone?
Here is the code:
public ResponseEntity generate_Access_token() {
String url = "https://zoom.us/oauth/token";
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
final Gson gson = new Gson();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
MultiValueMap<String, String> map= new LinkedMultiValueMap<String, String>();
map.add("grant_type", "account_credentials");
map.add("client_id", "XXX");
map.add("client_secret", "XXX");
map.add("account_id", "XXX");
HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<MultiValueMap<String, String>>(map, headers);
ResponseEntity<String> response = restTemplate.postForEntity( url, request , String.class );
//ResponseEntity<String> response_data=new ResponseEntity<String>(response.toString(), HttpStatus.CREATED);
ResponseEntity<AccessTokenResponse> response_data = restTemplate.postForEntity( url, request , AccessTokenResponse.class );
return response_data.getAccessToken();
}
class AccessTokenResponse{
#JsonProperty("access_token")
String accessToken;
//other props you are interested in
//+ getters/setters
public String getAccessToken() {
return accessToken;
}
public void setAccessToken(String accessToken) {
this.accessToken = accessToken;
}
}
}
The response:
{
"access_token": "eyJhbGciOiJIUzUxMiIsInYiOiIyLjAiLCJraWQiOiJlNDI1NDFkYi0zMTllLTRiMGYtOWIwMC04YTVlZmY4NTI2NTAifQ.eyJ2ZXIiOjcsImF1aWQiOiJjNWFjZThhNGRiNDY0NTJhM2YxNGNkZjcyZjY1MjU2NSIsImNvZGUiOiIxYldicXNVNVR3V1hDUEY5M2ZTbjdBR21xT1NKOXBUS0kiLCJpc3MiOiJ6bTpjaWQ6NjFtN2ppSXFUM2VMWDRuS0xZVUdGZyIsImdubyI6MCwidHlwZSI6MywiYXVkIjoiaHR0cHM6Ly9vYXV0aC56b29tLnVzIiwidWlkIjoianYwWWZyUDlRLWFLTlctTFVlSXRDZyIsIm5iZiI6MTY1NjMxNzM2MiwiZXhwIjoxNjU2MzIwOTYyLCJpYXQiOjE2NTYzMTczNjIsImFpZCI6IkJ4MnVOWHpHUWwtSHVDN3BITWF2NWciLCJqdGkiOiJlYTYwMDkwYS0wMWY1LTQwODctODgxMi0wNmQ2Mzk1NTI2ZGUifQ.nKiYXxCDbhQRsyR2pTu0nwegQKBHsSR9JT7CBnad5pPfBi4pVBISjGp6icRv2Nyv_L7lNzVBK8clW7Z5zM9TUg",
"token_type": "bearer",
"expires_in": 3599,
"scope": "meeting:read:admin user:master user:read:admin user:write:admin"
}

Make your life easier, not harder - use plain DTO
class AccessTokenResponse{
#JsonProperty("access_token");
String accessToken
//other props you are interested in
//+ getters/setters
}
and then
AccessTokenResponse response = restTemplate.postForObject( url, request , AccessTokenResponse.class );
response.getAccessToken(); //here you have it

Related

How to sent Http POST request with application/x-www-form-urlencoded

I'm trying to generate a token from an external website, the post request must be application/x-www-form-urlencoded but I'm getting errors. I assume that I'm not making the right call for the content type application/x-www-form-urlencoded but I can't figuer out how!!
PS: I'm using springboot with java 8
here is the code:
public String getNewAccesToken() {
//Initilazing variabels
try {
JsonObject properties = new JsonObject();
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
headers.set("Cookie", cookie);
properties.addProperty("client_id", clientId);
properties.addProperty("client_secret", clientSecret);
properties.addProperty("grant_type", grantType);
HttpEntity<String> requestEntity = new HttpEntity<>(properties.toString(), headers);
log.debug(requestEntity);
ResponseEntity<String> response = restTemplate.exchange(requestUrl, HttpMethod.POST, requestEntity,
String.class);
log.debug("---------------------------------");
log.debug(response);
if (Util.isJSONValid(response.getBody())) {
JsonParser parser = new JsonParser();
JsonObject jsonString = (JsonObject) parser.parse(response.getBody());
return jsonString.get("accessToken").getAsString();
} else {
error.setCode(ConstantGateway.JSON_ERROR_CODE);
error.setMessage(ConstantGateway.JSON_ERROR_STATUS);
return error.toString();
}
} catch (HttpStatusCodeException e) {
error.setCode(String.valueOf(e.getStatusCode().value()));
error.setMessage(e.getResponseBodyAsString());
return error.toString();
} catch (Exception e) {
// TODO: handle exception
error.setCode(ConstantGateway.IL_INTERNAL_ERROR_CODE);
error.setMessage(e.getMessage());
return error.toString();
}
}
and here is what I get when calling this function:
org.zwz.vas.internal.api.model.ErrorModel#16dd359c
However when I make the call from Postman I get the right response which is :
{
"access_token": "RdWt3DNIfxmihnubGX0Fgfcb0KNHLZV79OfN9Y6Ky6Z3fxAfF_Pm7uP0jnFrG1fHplyBMZ74BIKleQ8jmswdGy4e87NV-uZsMzgS1nQAONc2nBxgU1_jkMBhL4vvIniJNd99oYNzGeanCYYki0yorrrlLrOGTncusv1BgFFHU_CBGuUtGmZYLfJAJW4XcZLhXMC9xpT2aWAvgRXZW69pOhfU1Fgs7aVwou85UVI2b4j1GfX0pCtJtluiTgXsuWqdck7_at1dqfopHpjWAywYrweStMXGm8T59nyQi_oXWmo",
"token_type": "bearer",
"expires_in": 1199
}
THANK YOU IN ADVANCE
I find the mistake I did, I was sending a wrong request format which is not compatibale with application/x-www-form-urlencoded type. The right code is below:
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
headers.set("Cookie", cookie);
MultiValueMap<String, String> properties= new LinkedMultiValueMap<String, String>();
properties.add("client_id", clientId);
properties.add("client_secret", clientSecret);
properties.add("grant_type", grantType);
HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<MultiValueMap<String, String>>(properties, headers);
ResponseEntity<String> response = restTemplate.postForEntity( requestUrl, request , String.class );

How do I mock RestTemplate exchange using junit 5 (Jupiter)

I tried with below code but in response body I got empty records.
Please help me on below code.
Java Code:
public Customer getCustomers(String customerId, String authorization) {
MultiValueMap<String, String> headers = new LinkedMultiValueMap<>();
headers.set("Authorization", authorization);
HttpEntity<Customer> request = new HttpEntity<>(headers);
Map<String, Object> params = new HashMap<>();
params.put("CustomerId", customerId);
String url = "https://localhost:8080/api/customer/{CustomerId}/get";
ResponseEntity<Customer> response = restTemplate.exchange(
url,
HttpMethod.GET,
request,
Customer.class,
params
);
Customer customer = null;
if (response != null && response.getBody() != null) {
customer = response.getBody();
}
return customer;
}
Test Code:
#Test
public void testGetCustomersSuccess() {
Customer customer = new Customer();
customer.setCountryCode("countryCode");
customer.setCreatedFrom("createdFrom");
customer.setCustomerlandline("224153");
customer.setCustomermobile("1522252");
customer.setEmail("email");
customer.setFirstname("firstName");
customer.setFiscalCode("fiscalCode");
customer.setFirstname("lastName");
customer.setId("5");
MultiValueMap<String, String> headers=new LinkedMultiValueMap<>();
headers.set(Authorization,"12152");
ResponseEntity<Customer> response=new ResponseEntity<Customer>(HttpStatus.OK);
when(restTemplate.exchange(Mockito.any(String.class),
Mockito.<HttpMethod> any(),
Mockito.<HttpEntity<Customer>> any(),
Mockito.<Class<Customer>> any(),
Mockito.<String, Object> anyMap()))
.thenReturn(response);
assertEquals(response.getBody(),serviceClientImpl.getCustomers("5", "12152"));
}
You need to set the value of customer in your response.
The values you are setting in customer object is not being used anywhere.
Try this:
ResponseEntity<Customer> response=new ResponseEntity<Customer>(customer,HttpStatus.OK);

Authorization for Google Drive Push Notifications for Java

I am trying to get push notifications from a resource on Google Drive to my server. I have been looking at this example:
https://developers.google.com/drive/v3/web/push
And I have tried translating that to Java into something like this:
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
MultiValueMap<String, String> map = new LinkedMultiValueMap<String, String>();
map.add("id", "36d00d08-000d-4723-91bc-a1a6ec302e59");
map.add("type", "web_hook");
map.add("address", "https://mydomain.appspot.com/rest/drive");
HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<MultiValueMap<String, String>>(map, headers);
ResponseEntity<String> response = restTemplate.postForEntity(uri, request, String.class);
I have previously been using Googles libs for Drive to access files. In those cases I didn't need to create the request in such a "manual" way. I have used the class GoogleAuthorizationCodeFlow with a token to authorize my requests. I'm not sure how I should do that with RestTemplate. I am guessing that I need to do something like:
headers.set("Authorization", X);
What should X be here? Is that even the right way to approach authorization?
Edit:
Here is my attempt by reading a secret. The result is HTTP 401:
#Override
public String startListening() throws IOException {
final String fileId = "omitted";
String uri = "https://www.googleapis.com/drive/v3/files/" + fileId + "/watch";
HttpHeaders headers = getHeaders(getSecret());
HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<MultiValueMap<String, String>>(getProperties(), headers);
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<String> response = restTemplate.postForEntity(uri, request, String.class);
return response.getStatusCode() + " " + response.getBody() + " " + response.getHeaders();
}
private static HttpHeaders getHeaders(String theString) {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
headers.set("Authorization", "Bearer " + theString);
return headers;
}
private static MultiValueMap<String, String> getProperties() {
MultiValueMap<String, String> map = new LinkedMultiValueMap<String, String>();
map.add("id", "some uid");
map.add("type", "web_hook");
map.add("address", "https://mydomain.appspot.com/rest/drive");
return map;
}
private static String getSecret() throws IOException {
InputStream in =
ConcreteDriveListenerFactory.class.getResourceAsStream("/drive_secret.json");
StringWriter writer = new StringWriter();
IOUtils.copy(in, writer, "UTF-8");
return writer.toString();
}
As #DalmTo has mentioned, X is for token. With regard to sample POST request for Drive API try this code snippet from this SO thread. It also uses a POST method.
public static void main(String argv[]) throws Exception {
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpPost post = new HttpPost(
"https://www.googleapis.com/drive/v2/files");
post.addHeader("Content-Type", "application/json");
post.addHeader("Authorization",
"Bearer XXXXXXXXXXXXXXXXXXXXXXXXX");
JsonObject jsonObject = new JsonObject();
jsonObject.addProperty("title", "Test folder");
jsonObject
.addProperty("mimeType", "application/vnd.google-apps.folder");
post.setEntity(new StringEntity(jsonObject.toString()));
httpClient.execute(post);
}

How to use Spring RestTemplate instead of Apache Httpclient?

I want to use Spring RestTemplate instead of Apache HttpClient for working with a remote API
With HttpClient
// build request JSON
JSONObject json = new JSONObject();
json.put("username", username);
json.put("serial", serial);
json.put("keyId", keyId);
json.put("otp", otp);
String json_req = json.toString();
// make HTTP request and get response
HttpPost request = new HttpPost(AuthServer);
request.setHeader("Content-Type", "application/json");
request.setEntity(new StringEntity(json_req));
response = client.execute(request);
With RestTemplate
Map<String, String> paramMap = new HashMap<String,String>();
paramMap.put("username", userName);
paramMap.put("serial", serial);
paramMap.put("keyId", keyId);
paramMap.put("otp", otp);
String mapAsJson = new ObjectMapper().writeValueAsString(paramMap);
HttpHeaders requestHeaders = new HttpHeaders();
requestHeaders.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<String> request = new HttpEntity<String>(mapAsJson,requestHeaders);
try {
ResponseEntity<String> response = restTemplate.exchange(AuthServer, HttpMethod.POST, request, String.class);
return response.getHeaders();
} catch (HttpClientErrorException e) {
return null;
}
}
The code with HttpClient works but that with RestTemplate does not. I don't know how to use StringEntity in RestTemplate.
Spring version is 3.0.0, and JVM is 1.6.
RestTemplate is better suited to working with objects. As an example:
AuthenticationRequest.java
class AuthenticationRequest {
private String username;
private String serial;
private String key;
private String otp;
}
AuthenticationResponse.java
class AuthenticationResponse {
private boolean success;
}
AuthenticationCall.java
class AuthenticationCall {
public AuthenticationResponse execute(AuthenticationRequest payload) {
HttpEntity<AuthenticationRequest> request = new HttpEntity<AuthenticationRequest>(payload, new HttpHeaders());
return restTemplate.exchange("http://www.domain.com/api/endpoint"
, HttpMethod.POST
, request
, AuthenticationResponse.class).getBody();
}
}
These classes can be used as follows:
if(new AuthenticationCall().execute(authenticationRequest).isSuccess()) {
// Authentication succeeded.
}
else {
// Authentication failed.
}
All of this requires there to be a JSON library such as Jackson or GSON on the classpath.

Restful Spring postForObject missing all property values

I try to simulate restful server:
private void btnPostActionPerformed(java.awt.event.ActionEvent evt) {
RestTemplate restTemplate = new RestTemplate();
Issuer issuer = new Issuer();
issuer.setCountry("Teacher 1");
issuer.setIssuerName("Department 1");
String url = txtHost.getText()+txtGet.getText();
restTemplate.postForObject(url, issuer, Issuer.class) ;
}
Controller code:
#RequestMapping(value = "/issuer/addIssuer", method = RequestMethod.POST)
#ResponseBody
public Issuer addIssuer(#ModelAttribute("issuer") Issuer issuer) {
if (issuer != null) {
logger.info("Inside addIssuer, adding: " + issuer.toString());
} else {
logger.info("Inside addIssuer...");
}
issuers.put(issuer.getTicker(), issuer);
return issuer;
}
I have fill some attributes, but when I debug the server, all values is null.
INFO : com.avaldes.tutorial.RestController - Inside addIssuer, adding: [null, null, null, null]
IssuerName and country is null too..
What is wrong with my code?
You are using #ModelAttribute in your controller. In that case you'll need to send your data as application/x-www-form-urlencoded:
MultiValueMap<String, Object> variables = new LinkedMultiValueMap<>();
variables.add("country", "Teacher 1");
variables.add("issuerName", "Department 1");
RestTemplate restTemplate = new RestTemplate();
HttpHeaders requestHeaders = new HttpHeaders();
requestHeaders.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(variables, requestHeaders);
String url = txtHost.getText()+txtGet.getText();
ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.POST, requestEntity, Issuer.class);

Categories

Resources