Can someone please explain to me what is happening in the following code?
If I run:
RestTemplate rest = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.add("header1", "data");
headers.add("header2", "data");
HttpEntity<String> entity = new HttpEntity<>("body", headers);
ResponseEntity<JSONObject> response =
rest.exchange("https://example.com/../{username}/{path}", HttpMethod.GET, entity, JSONObject.class, "user%123", "path");
Spring tells me that the URL used is https://example.com/../username/path where username = user%25123 even though I set the username = user%123.
This is looking to me to be not a Spring issue, rather a URL encoding issue, but can anyone tell me where this extra 25 comes from?
%25 is a URL-encoded percent sign, so user%123 encodes to user%25123
More info: https://www.w3schools.com/tags/ref_urlencode.ASP
Related
I want to pass a hosted file over the rest template to another end point. I have to pass the hosted file URL as a String.
See the below code.
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.MULTIPART_FORM_DATA);
MultiValueMap<String, Object> map = new LinkedMultiValueMap<>();
map.add(ATTACHMENT,new FileSystemResource(request.getAttachment()));
HttpEntity<MultiValueMap<String,Object>> outBoundRequest = new HttpEntity<>(map, headers);
return restTemplate.exchange(uri[0],HttpMethod.POST,outBoundRequest,Response.class);
Suppose I am passing "http://www.africau.edu/images/default/sample.pdf";
Why I am getting "Illegal char <:> at index 4: http:\www.africau.edu\images\default\sample.pdf"?
Can anyone help me out here.
Thanks,
Dasun.
Is there a way to upload files to Azure blob storage using rest template in Java - Spring framework ? I see all examples using SDK and it was successful but we are told not to use SDK - Java.
I know question is 10,000 feet high, but any pointers/direction will help a lot.
No idea why not to use SDK, Also no idea who might be told you.
Anyway, Yes you can use RestTemplate or even better webClient.
All you have to do is to map the request sent with the SDK to the cloud.
You have to add header authentication manually. serialize the file I suppose.
And it's a lot of work when you do have a supported SDK for client.
For example , here is a simple request sent with WebClient for Redmine server
String url = "http://localhost:3001/projects.json"; //Redmine local server
RestTemplate restTemplate = new RestTemplate();
JSONObject object = new JSONObject(); //Json object that will need to be sent to redmine
object.put("name", "dummyName"); // Should look like this
object.put("identifier", "dummyId"); // {"project":{"identifier":"dummyId","name":"dummyName"}}
JSONObject body = new JSONObject();
body.put("project", object);
String plainCreds = "user:bitnami1"; // default basic auth encoding
byte[] plainCredsBytes = plainCreds.getBytes();
byte[] base64CredsBytes = Base64.encodeBase64(plainCredsBytes);
String base64Creds = new String(base64CredsBytes);
HttpHeaders headers = new HttpHeaders();
headers.add("Authorization", "Basic " + base64Creds);
headers.add("Content-Type", "application/json");
RequestEntity<JSONObject> requestEntity = RequestEntity
.post(new URI(url))
.accept(MediaType.APPLICATION_JSON)
.headers(headers)
.body(body);
ResponseEntity<String> r = restTemplate.exchange(requestEntity, String.class);
And this is who the same example will look like using RestTemplate
String url = "http://localhost:3001/projects.json"; //Redmine local server
RestTemplate restTemplate = new RestTemplate();
JSONObject object = new JSONObject(); //Json object that will need to be sent to redmine
object.put("name", "dummyName"); // Should look like this
object.put("identifier", "dummyId"); // {"project":{"identifier":"dummyId","name":"dummyName"}}
JSONObject body = new JSONObject();
body.put("project", object);
String plainCreds = "user:bitnami1"; // default basic auth encoding
byte[] plainCredsBytes = plainCreds.getBytes();
byte[] base64CredsBytes = Base64.encodeBase64(plainCredsBytes);
String base64Creds = new String(base64CredsBytes);
HttpHeaders headers = new HttpHeaders();
headers.add("Authorization", "Basic " + base64Creds);
headers.add("Content-Type", "application/json");
HttpEntity<Object> entity = new HttpEntity<Object>(body, headers);
ResponseEntity<String> result = restTemplate.exchange("http://localhost:3001/projects.json",
HttpMethod.POST,
entity,
String.class);
Both of these, Were only possible because am trying to match this curl request
curl --location --request POST 'localhost:3001/projects.json' \
--header 'Authorization: Basic dXNlcjpiaXRuYW1pMQ==' \
--header 'Content-Type: application/json' \
--data-raw '{"project":{"identifier":"dummyId","name":"dummyName"}}'
So once You know what the request looks like, You can use RestTemplate or WebClient, or any other similar class to build up your request.
I have an external API that I am invoking. The API takes two files as input. One File is .txt and other file is .JOSN.
I need to call this API through spring. This api is multipart/form-data.
public String doAPICall(String uri, String token) {
File idFile = new File ("c:\tmp\id_file.txt");
File jsonFile = new File ("c:\tmp\jsonFile.json");
MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
body.add("idFile", new FileSystemResource(idFile));
body.add("jsonFile", new FileSystemResource(jsonFile));
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.MULTIPART_FORM_DATA);
headers.set("Authorization", "Bearer " + token);
HttpEntity<MultiValueMap<String, Object>> requestEntity= new HttpEntity<>(body, headers);
RestTemplate restTemplate = new RestTemplate();
String result = restTemplate.exchange(
uri, HttpMethod.POST,requestEntity,
String.class).getBody().toString();
System.out.println(result);
return result;
}
Result: 500 - Internal Server Error. However, If I invoke the API with the same config via Insomnia/Postman, it works.
Also, it's not throwing 401 as the token is valid.
Do I need to set some extra header as I am uploading a txt and JSON file?
PS: I have typed the code here, the code might not be well-formatted.
Please share if anyone has any suggestions. Thank you!
I am trying to create a Bitbucket repository using their REST-API. Everything seems to work except setting the "parent" project, where the repository needs to be created in. On this link a cURL example is provided. In the body, the parameter "scm" is set as either "git" or "hg", both being Strings, the parameter "project" seems to be a json object containing a key-value pair. Everything I tried so far did not work (json object, string, etc.)
Question: How can I create a repository IN a specific project?
My code looks the following:
RestTemplate restTemplate = new RestTemplate();
String url = "https://api.bitbucket.org/2.0/repositories/" + tName + "/" + rName;
HttpHeaders headers = new HttpHeaders();
headers.set("Authorization", "Basic 1234567890qwert");
headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
MultiValueMap<String, String> project = new LinkedMultiValueMap();
project.add("key", "aaaaaaaa"); //the repo should be created in the project aaaaaaaa
MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
postParameters.add("scm", "hg"); //hg or git, does not matter
postParameters.add("project", project); //<-- the api ignores the declared project
HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<MultiValueMap<String, Object>>(body, headers);
ResponseEntity<BitbucketRepository> response = restTemplate.exchange(url, HttpMethod.POST, requestEntity, BitbucketRepository.class);
System.out.println("createRepository: " + response);
return response;
You could use the bitbucket-rest library to do this like so:
BitbucketClient client = BitbucketClient.builder()
.endPoint("http://127.0.0.1:7990")
.credentials("admin:password") // will base64 for you if not already done. Can optionally use token auth as well.
.build();
CreateRepository crepo = CreateRepository.create("my-repo", true);
Repository repo = client.api().repositoryApi().create("my-project", crepo);
I've got a Spring Boot application with some tests. The application's 'happy-path' requires that the user send a request to start a session, then it can make other requests to other services.
I'm trying to test these other services, but I need a session started first. My mindset was as follows:
Hit the session start endpoint
Get the session cookie from that request
Slap that cookie onto future requests made during testing.
To achieve that, I've got this mess:
String s = t.postForEntity(loginUrl, remoteSessionPacket, String.class)
.getHeaders()
.get("Set-Cookie").get(0);
String[] split = s.split(";");
String sessionId = "";
for (String s1 : split) {
if(s1.contains("SESSION"))
{
sessionId = s1;
}
}
HttpHeaders headers = new HttpHeaders();
headers.add("SESSION", sessionId);
HttpEntity<?> httpEntity = new HttpEntity<>(headers);
RemoteDTOPacket= new RemoteDTOPacket();
packet.Token = UUID.randomUUID().toString();
String url = "http://localhost:" + port + "/domain/SomeFunction";
ResponseEntity<ResponsePacket> response = t.postForEntity(url, packet, ResponsePacket.class, httpEntity);
Assert.assertEquals(0, (long) response.getBody().count);
Obviously, this doesn't work and errors are thrown with abandon.
Does anyone know how to accomplish what I'm trying to do?
Any help is greatly appreciated.
Session id is stored in cookie that is stored in "Cookie" header - not in separate request header. Something like this should work:
List<String> coockies = t.postForEntity(loginUrl, remoteSessionPacket, String.class)
.getHeaders()
.get("Set-Cookie");
HttpHeaders requestHeaders = new HttpHeaders();
requestHeaders.put(HttpHeaders.COOKIE, coockies);
HttpEntity<Void> requestEntity = new HttpEntity<>(requestHeaders);
Or you can get exact session id cookie that will be most probably stored under "JSESSIONID" key.