spring boot resttemplate api call by providing userid and password - spring-boot

I want to get data from another application controller by providing userid and password.
Getting Error- HTTP Error 405 (Method Not Allowed)
RestTemplate restTemplate = new RestTemplate();
String plainCreds = "USER1:password";
byte[] plainCredsBytes = plainCreds.getBytes();
byte[] base64CredsBytes = Base64.encodeBase64(plainCredsBytes);
String base64Creds = new String(base64CredsBytes);
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
headers.add("Authorization", "Basic " + base64Creds);
HttpEntity<String> request = new HttpEntity<String>(headers);
ResponseEntity<String> response1 = restTemplate.exchange(uri, HttpMethod.GET, request, String.class);
System.out.println("Result--------"+ response1.toString());

Related

RestTemplate removes cookie. (Migration from CloseableHttpClient)

I need migrate from CloseableHttpClient to RestTemplate in my desctop client application. RestTemplate response has an empty "Set-cookie" header.
Source code (works ok): // returns the Set-Cookie header = "JSESSIONID=D2442..."
List<BasicNameValuePair> parameters = asList(
new BasicNameValuePair("username", username),
new BasicNameValuePair("password", password));
HttpPost httpPost = new HttpPost(url);
httpPost.setEntity(new UrlEncodedFormEntity(parameters));
CloseableHttpClient client = createDefault()
CloseableHttpResponse response = client.execute(httpPost);
Target code: // returns the Set-Cookie header = ""
String url = url;
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
MultiValueMap<String, String> map= new LinkedMultiValueMap<>();
map.add("username", username);
map.add("password", password);
ParameterizedTypeReference<Map<String, String>> responseType = new ParameterizedTypeReference<>() {};
HttpEntity<Object> request = new HttpEntity<>(map, headers);
ResponseEntity<Map<String, String>> tokensInfo = restTemplate.exchange(
url, HttpMethod.POST, request, responseType
);
Help, please.
Add to the target code:
HttpClient httpClient = HttpClientBuilder.create().build();
ClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(httpClient);
restTemplate.setRequestFactory(factory);

How to send LocalDate in RestTemplate parameter

In below I called web service with String parameter named "samana"
String samana= "000ABC";
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
HttpEntity<String> requestEntity = new HttpEntity<String>(null, headers);
Table res = restTemplate
.exchange("http://localhost:8090/tharindu/findAllComputers?saman=").concat(samana), HttpMethod.GET, requestEntity, Table.class)
.getBody();
How to pass LocalDate parameter in RestTemplate webservice
LocalDate samana = LocalDate.now();
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
HttpEntity<String> requestEntity = new HttpEntity<String>(null, headers);
Table res = restTemplate
.exchange("http://localhost:8090/tharindu/findAllComputers?saman=").concat(samana), HttpMethod.GET, requestEntity, Table.class)
.getBody();

How to request POST using RestTemplate, authorized using user password

Can some one tell how I can use RestTemplate to POST a HttpEntity object using Authorization. I am using below code in test application
Client Side :
public class FifthWay extends Thread {
public void run() {
String plainCreds = "anuj:khare";
byte[] plainCredsBytes = plainCreds.getBytes();
byte[] base64CredsBytes = Base64.encodeBase64(plainCredsBytes);
String base64Creds = new String(base64CredsBytes);
HttpHeaders headers = new HttpHeaders();
headers.add("Authorization", "Basic " + base64Creds);
HttpEntity<String> postRequest = new HttpEntity<String>("FifthWay",headers);
RestTemplate rt = new RestTemplate();
rt.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
rt.getMessageConverters().add(new StringHttpMessageConverter());
String postUri = new String("http://169.194.48.182:8080/trade-capture-service/deals/persist");
ResponseEntity<String> responseForPost = rt.exchange(postUri,HttpMethod.POST, postRequest, String.class);
String responseStringForPost = responseForPost.getBody();
System.out.println(responseStringForPost);
}
}
Server side :
#Controller
#RequestMapping("/deals")
public class RestController {
...
...
#RequestMapping(value = "/check", method = RequestMethod.GET)
public #ResponseBody
String justACheck() {
System.out.println("It Works");
return "It works";
}
Getting errors like :
Exception in thread "Thread-4" org.springframework.web.client.HttpClientErrorException: 415 Unsupported Media Type
OR
Exception in thread "Thread-4" org.springframework.web.client.HttpClientErrorException: 400 Bad Request
Please help
Here is the example of RestTemplate exchange :
RestTemplate restTemplate = new RestTemplate();
restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
HttpHeaders requestHeaders = new HttpHeaders();
final HttpEntity entity = new HttpEntity(restCanvas, requestHeaders);
return restTemplate.exchange(canvasAddUrl + value, HttpMethod.POST, entity, Integer.class);
Here canvasAddURL is the URL you wish to call with context-path. If you want to add a cookie to it, lemme know, i have removed that code as it is most of the time not necessary. The return value for this is ResponseEntity<Integer> . Check it out.

Session closed error when performing subsequence requests to client via Spring RestTemplate

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);
all goes well, but when I try to send a second request, It generates an error saying :
Business Manager closes your session after 15 minutes
What can I do to solve this problem ?!
When you receive the response in your first request you should store your session id which is received via cookie. You will retrieve it in a set-cookie response header which you can get via:
//first request
RestTemplate template = new RestTemplate();
ResponseEntity<String> forEntity = template.getForEntity("http://google.bg", String.class);
forEntity.getHeaders().get("Set-Cookie").stream().forEach(System.out::println);
then in every subsequent request you should set the Cookie request header with the values received in the first request:
//subsequent request
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.set("Cookie",cookies.stream().collect(Collectors.joining(";")));
HttpEntity<String> entity = new HttpEntity<String>(headers);
restTemplate.exchange("http://url", HttpMethod.POST, entity, String.class);
I have a StaticRestTemplate class, this way I get the same RestTemplate instance.
public class StaticRestTemplate {
public volatile static RestTemplate rest = new RestTemplate();
public static volatile String jsessionid = "";
// This way, I can test on local or server just by changing one URL.
public static volatile String baseURL = "http://192.168.178.60:8080/";
}
Login code :
public static RestTemplate rest = new RestTemplate();
rest.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
StaticRestTemplate.jsessionid = rest.execute(StaticRestTemplate.baseURL+"j_spring_security_check", HttpMethod.POST,
new RequestCallback() {
#Override
public void doWithRequest(ClientHttpRequest request) throws IOException {
request.getBody().write(("j_username=" + email + "&j_password=" + password).getBytes());
}
}, new ResponseExtractor<String>() {
#Override
public String extractData(ClientHttpResponse response) throws IOException {
List<String> cookies = response.getHeaders().get("Cookie");
if (cookies == null) {
cookies = response.getHeaders().get("Set-Cookie");
}
String cookie = cookies.get(cookies.size() - 1);
int start = cookie.indexOf('=');
int end = cookie.indexOf(';');
return cookie.substring(start + 1, end);
}
});
return null;
}
Now, my JsessionID is saved, and I can use it directly for subsequent requests this way :
rest.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
HttpHeaders requestHeaders = new HttpHeaders();
// This is where I add the cookie value
requestHeaders.add("Cookie", "JSESSIONID=" + StaticRestTemplate.jsessionid);
HttpEntity<String> requestEntity = new HttpEntity<>(requestHeaders);
HttpEntity<String> rssResponse = rest.exchange(
StaticRestTemplate.baseURL+"dashboard",
HttpMethod.GET,
requestEntity,
String.class);
StaticRestTemplate.replyString = rssResponse.getBody();
return StaticRestTemplate.replyString;
If there are doubts, let me know.
You can try to disable cookie management with factory for your RestTemplate:
HttpClient httpClient = HttpClientBuilder.create()
.disableCookieManagement()
.useSystemProperties()
.build();
factory.setHttpClient(httpClient);

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