I need to get a cookie from a server using Spring RestTemplate. Do you guys know how I can perform this?
Thank you for your help!
final String url = "http://codeflex.co:8080/rest/Management/login";
RestTemplate template = new RestTemplate();
Credentials cred = new Credentials();
cred.setUserName("admin#codeflex.co");
cred.setPassword("godmode");
HttpEntity<Credentials> request = new HttpEntity<>(cred);
HttpEntity<String> response = template.exchange(url, HttpMethod.POST, request, String.class);
HttpHeaders headers = response.getHeaders();
String set_cookie = headers.getFirst(HttpHeaders.SET_COOKIE);
code from the example
HttpHeaders requestHeaders = new HttpHeaders();
requestHeaders.add("Cookie", "JSESSIONID=" + session.getValue());
HttpEntity requestEntity = new HttpEntity(null, requestHeaders);
ResponseEntity rssResponse = restTemplate.exchange(
"https://jira.example.com/sr/jira.issueviews:searchrequest-xml/18107/SearchRequest-18107.xml?tempMax=1000",
HttpMethod.GET,
requestEntity,
Rss.class);
Rss rss = rssResponse.getBody();
from http://springinpractice.com/2012/04/08/sending-cookies-with-resttemplate
Related
I have a PUT API to call to send my data that expects a Multipart Request. (Swagger has the API listed as Paramter Type formData; Data Type file).
I have this code working fine via Apache's Http Library, but to match the rest of the program I would like to use Spring Rest Template to make the same call.
//Via Apache:
Uri uri = "http://putmyresults.com";
ResultObject results = buildResultObject(myData);
MultipartEntityBuilder meb = MultipartEntityBuilder.create();
meb.addBinaryBody("file", results.convertToBytes(), ContentType.create("application/octet-stream"),"MyResultFile");
HttpEntity entity = meb.build();
put.setEntity(entity);
put.setHeader(new BasicHeader("Authorization","myToken"));
put.setHeader("Accept","application/json,application,octet-stream");
getMyCloseableHttpClient().execute(put);
//process response codes...
//Sample working REST for GET request:
Uri uri = "http://getmyresults.com/section5/resultId?sectionId=foo";
RestTemplate rest = new RestTemplate;
org.springframework.http.HttpEntity header = new HttpHeaders();
header.set("Authorization","myToken");
header.setContentType(MediaType.APPLICATION_JSON);
header.setAccept(Arrays.asList(MediaType.APPLICATION_JSON,MediaType.APPLICATION_OCTET_STREAM));
HttpEntity<String> entity = new HttpEntity("parameters", headers);
rest.exchange(uri, HttpMethod.GET, entity, Resource.class);
//process response...
But I can't seem to make the PUT request via REST. This is what I have so far:
Uri uri = "http://putmyresults.com";
MultiValueMap<String,Object> map = new LinkedMultiValueMap<>();
ResultObject results = buildResultObject(myData);
byte[] bytes = results.convertToBytes();
HttpHeaders header = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
org.springframework.http.HttpEntity<byte[]> entity = new HttpEntity<>(bytes,headers);
map.add("MyResultFile",entity);
HttpHeaders tokenHeader = new HttpHeaders();
tokenHeader.set(new BasicHeader("Authorization","myToken"));
tokenHeader.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<String> tokenEntity = new HttpEntity("parameters", headers);
map.add("parameters",tokenEntity);
org.springframework.http.HttpEntity<<MultiValueMap<String,Object> requestMap = new org.springframework.http.HttpEntity<>(map);
new RestTemplate().exchange(uri,HttpMethod.PUT,requestMap,String.class);
Server Header:
#PutMapping(path = "/xyz")
public ResponseEntity putRequest{
HttpServletRequest request,
HttpServletResponse response,
#PathVariable String id,
#RequestParam("file") MultipartFile uploadedFile,
#RequestParam String sample,
#RequestParam String sample2 throws Exception {
uploadedFile.getBytes(); ...
}
}
Thanks for your help.
Try this:
MultiValueMap<String, Object> multipartRequest = new LinkedMultiValueMap<>();
// creating an HttpEntity for the binary part
HttpHeaders header = new HttpHeaders();
pictureHeader.setContentType(MediaType.MULTIPART_FORM_DATA);
HttpEntity<ByteArrayResource> file = new HttpEntity<>(pngPicture, pictureHeader);
multipartRequest.add("file", file);
HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>
(multipartRequest, header);
ResultObject result = restTemplate.put(UPLOAD_URL, requestEntity);
You need to add the content type as multipart along with content disposition. Make sure to import spring classes as there are same classes in Apache Http library.
String uri = "http://putmyresults.com";
MultiValueMap<String,Object> multipartRequest = new LinkedMultiValueMap<>();
ResultObject results = buildResultObject(myData);
byte[] bytes = results.convertToAvroBytes()
HttpHeaders fileHeader = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
headers.setContentDispositionFormData("file","mydata");
HttpEntity<byte[]> entity = new HttpEntity<>(bytes,fileHeader);
multipartRequest.add("file",entity);
HttpHeaders header = new HttpHeaders();
header.setContentType(MediaType.MULTIPART_FORM_DATA);
HttpEntity<MultiValueMap<String,Object>> requestMap = new HttpEntity<>(multipartRequest,header);
String response = new RestTemplate().exchange(uri,HttpMethod.PUT,requestMap,String.class);
Reference:multipart-file-upload-using-spring-rest-template-spring-web-mvc
With the help of #user2683814 and this article, this is what works for me:
import org.springframework.http.*; //Used with 5.1.9.RELEASE
Uri uri = "http://putmyresults.com";
byte[] bytes = MyObject.getMyBytes();
MultiValueMap<String,String> fileMap = new LinkedMultiValueMap<>();
ContentDisposition cd = ContentDisposition.builder("form-data").
name("file").filename("myFile").build();
filemap.add(HttpHeaders.CONTENT_DISPOSITION,cd.toString());
HttpEntity<byte[]> fileEntity = new HttpEntity<>(bytes,fileMap);
MultiValueMap<String,Object> body = new LinkedMultiValueMap<>();
body.add("file",fileEntity);
HttpHeaders tokenHeader = new HttpHeaders();
tokenHeader.set("Authorization","myToken");
tokenHeader.setContentType(MediaType.MULITPART_FORM_DATA);
HttpEntity<MultiValueMap<String,Object>> requestMap = new HttpEntity<>(body,securedTokenHeaders);
new RestTemplate().exchange(uri,HttpMethod.PUT,requestMap,String.class)
I'm getting this error "org.springframework.web.client.HttpClientErrorException$BadRequest: 400 Bad Request" while trying to internally call POST API from another GET API in spring boot. following is the code. also I'm getting multipart file as input in the get api and wants to send that file to this internal post api
Path tempFile = Files.createTempFile(null, null);
Files.write(tempFile, newFile.getBytes());
File fileToSend = tempFile.toFile();
FileSystemResource fr = new FileSystemResource(fileToSend);
String baseUrl = "someURL which is correct";
URI uri = new URI(baseUrl);
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.MULTIPART_FORM_DATA);
//headers.set("Content-type", "multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW");
headers.set("Ocp-Apim-Subscription-Key","{key which i dont want to display}");
MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
body.add("newFile", fr);
HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(body, headers);
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<String> response = restTemplate.postForEntity(uri, requestEntity, String.class);
return response;
Pass baseUrl string instead of uri in restTemplate.postForEntity method and try
Following code snippet receives 401 unauthorized exception :
String uri = "https://api/example.json?status=all";
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity entity = new HttpEntity(headers);
ResponseEntity <String> results = restTemplate.exchange(uri, HttpMethod.GET, entity, String.class;
This is our rest template config
#Bean
public RestTemplate infoBloxRestTemplate() {
RestTemplate restTemplate=new RestTemplate();
ArrayList<ClientHttpRequestInterceptor> interceptors = new ArrayList<>();
interceptors.add(httpBasicAuthenticationInterceptor());
restTemplate.setInterceptors(interceptors);
restTemplate.getMessageConverters().add(jacksonConverter());
restTemplate.setRequestFactory(genericHttpRequestFactory());
return restTemplate;
}
We are trying to make a POST call which works successfully with Postman and returns proper response.
final HttpHeaders headers = new HttpHeaders();
headers.add("Accept", "application/json");
headers.add("Content-Type", "application/json");
HttpEntity<Object> httpEntity = new HttpEntity<Object>(record, headers);
StringBuilder uri = new StringBuilder(infobloxRestClient.createUrl("/record:host"));
infobloxRestClient.getRestTemplate().exchange(uri.toString(), HttpMethod.POST, httpEntity, String.class);
But this POST invocation fails with below error. Here is my stack trace:
com.sun.xml.ws.server.sei.TieHandler createResponse
SEVERE: null
java.lang.UnsupportedOperationException
at java.util.Collections$UnmodifiableCollection.add(Unknown Source)
at org.springframework.http.HttpHeaders.add(HttpHeaders.java:558)
at com.test.externalinterfaces.HTTPBasicAuthenticationInterceptor.intercept(HTTPBasicAuthenticationInterceptor.java:30)
at org.springframework.http.client.InterceptingClientHttpRequest$RequestExecution.execute(InterceptingClientHttpRequest.java:81)
at org.springframework.http.client.InterceptingClientHttpRequest.executeInternal(InterceptingClientHttpRequest.java:67)
at org.springframework.http.client.AbstractBufferingClientHttpRequest.executeInternal(AbstractBufferingClientHttpRequest.java:46)
at org.springframework.http.client.AbstractClientHttpRequest.execute(AbstractClientHttpRequest.java:49)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:488)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:452)
Any help on this regard will be very helpful.
To get more people know this issue:
#Sameer, I found the problem is you're using HttpHeaders ,you can try to build your header with this code
MultiValueMap<String, String> headers =new LinkedMultiValueMap<String, String>();
And not use the HttpHeaders and then in your HttpEntity to build the object entity as
new HttpEntity<Object>(record, headers);
Then it should solve problem .
Try creating the RestTemplate object in the following way,
ResTemplate restTemplate = new RestTemplate(new HttpComponentsClientHttpRequestFactory());
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
headers.set("Authorization", authorizationProperty); //Can also use add(String headerName, String headerValue)
This way it should works.
I have a RESTful API I'm trying to connect with via Android and RestTemplate. All requests to the API are authenticated with HTTP Authentication, through setting the headers of the HttpEntity and then using RestTemplate's exchange() method.
All GET requests work great this way, but I cannot figure out how to accomplish authenticated POST requests. postForObject and postForEntity handle POSTs, but have no easy way to set the Authentication headers.
So for GETs, this works great:
HttpAuthentication httpAuthentication = new HttpBasicAuthentication("username", "password");
HttpHeaders requestHeaders = new HttpHeaders();
requestHeaders.setAuthorization(httpAuthentication);
HttpEntity<?> httpEntity = new HttpEntity<Object>(requestHeaders);
MyModel[] models = restTemplate.exchange("/api/url", HttpMethod.GET, httpEntity, MyModel[].class);
But POSTs apparently don't work with exchange() as it never sends the customized headers and I don't see how to set the request body using exchange().
What is the easiest way to make authenticated POST requests from RestTemplate?
Ok found the answer. exchange() is the best way. Oddly the HttpEntity class doesn't have a setBody() method (it has getBody()), but it is still possible to set the request body, via the constructor.
// Create the request body as a MultiValueMap
MultiValueMap<String, String> body = new LinkedMultiValueMap<String, String>();
body.add("field", "value");
// Note the body object as first parameter!
HttpEntity<?> httpEntity = new HttpEntity<Object>(body, requestHeaders);
ResponseEntity<MyModel> response = restTemplate.exchange("/api/url", HttpMethod.POST, httpEntity, MyModel.class);
Slightly different approach:
MultiValueMap<String, String> headers = new LinkedMultiValueMap<String, String>();
headers.add("HeaderName", "value");
headers.add("Content-Type", "application/json");
RestTemplate restTemplate = new RestTemplate();
restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
HttpEntity<ObjectToPass> request = new HttpEntity<ObjectToPass>(objectToPass, headers);
restTemplate.postForObject(url, request, ClassWhateverYourControllerReturns.class);
I was recently dealing with an issue when I was trying to get past authentication while making a REST call from Java, and while the answers in this thread (and other threads) helped, there was still a bit of trial and error involved in getting it working.
What worked for me was encoding credentials in Base64 and adding them as Basic Authorization headers. I then added them as an HttpEntity to restTemplate.postForEntity, which gave me the response I needed.
Here's the class I wrote for this in full (extending RestTemplate):
public class AuthorizedRestTemplate extends RestTemplate{
private String username;
private String password;
public AuthorizedRestTemplate(String username, String password){
this.username = username;
this.password = password;
}
public String getForObject(String url, Object... urlVariables){
return authorizedRestCall(this, url, urlVariables);
}
private String authorizedRestCall(RestTemplate restTemplate,
String url, Object... urlVariables){
HttpEntity<String> request = getRequest();
ResponseEntity<String> entity = restTemplate.postForEntity(url,
request, String.class, urlVariables);
return entity.getBody();
}
private HttpEntity<String> getRequest(){
HttpHeaders headers = new HttpHeaders();
headers.add("Authorization", "Basic " + getBase64Credentials());
return new HttpEntity<String>(headers);
}
private String getBase64Credentials(){
String plainCreds = username + ":" + password;
byte[] plainCredsBytes = plainCreds.getBytes();
byte[] base64CredsBytes = Base64.encodeBase64(plainCredsBytes);
return new String(base64CredsBytes);
}
}
Very useful
I had a slightly different scenario where I the request xml was itself the body of the POST and not a param. For that the following code can be used - Posting as an answer just in case anyone else having similar issue will benefit.
final HttpHeaders headers = new HttpHeaders();
headers.add("header1", "9998");
headers.add("username", "xxxxx");
headers.add("password", "xxxxx");
headers.add("header2", "yyyyyy");
headers.add("header3", "zzzzz");
headers.setContentType(MediaType.APPLICATION_XML);
headers.setAccept(Arrays.asList(MediaType.APPLICATION_XML));
final HttpEntity<MyXmlbeansRequestDocument> httpEntity = new HttpEntity<MyXmlbeansRequestDocument>(
MyXmlbeansRequestDocument.Factory.parse(request), headers);
final ResponseEntity<MyXmlbeansResponseDocument> responseEntity = restTemplate.exchange(url, HttpMethod.POST, httpEntity,MyXmlbeansResponseDocument.class);
log.info(responseEntity.getBody());