Spring RestTemplate getForObject getting 404 - java

I'm trying to make a get request to an Api Rest but I'm always getting 404, nevertheless if try copying queryUrl in a browser or postMan it works perfectly.
restTemplate.getForObject(queryUrl, entity ,Integer.class);
I've also tried this:
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.setContentType(MediaType.APPLICATION_JSON);
HttpEntity entity = new HttpEntity(httpHeaders);
log.debug("request headers: " + entity.getHeaders());
ResponseEntity response = restTemplate.exchange(queryUrl,
HttpMethod.GET, entity, String.class);
But nothing changes.
Can anyone help me?

This took me a bit to figure out, so I'll leave a little note here hoping one day it helps someone.
I kept getting a 404 when making a get request with ResTemplate.getForEntity(URL, Type). The URL worked in Chrome, Postman, but not in my code.
It ended up being because I had an unsafe character in my URL, an % to be exact, because my URL had spaces and so instead of space the URL had %20. Postman and Chrome could handle this, but not my code. Once I replaced the unsafe character with an actual space all was well.
Hope it works out for you too.

You were right Barath the usage is correct. The problem was that UriComponentBuilder was including a blank space at the en of the URL.
I've fixed it with a trim.
String queryUrl = UriComponentsBuilder.fromUriString(HOST)
.path(PATH)
.buildAndExpand(param)
.toUriString().trim();

When your url contains "%", then you shoud use restTemplate.getForObject(new URI(url),xx.class), it worked for me.

Related

Gitlab API download file + RestTemplate

Please help with following problem.
When I try to do request to gitlab with Postman or curl everithing works fine, I got answer with the file
curl --header "PRIVATE-TOKEN: xxxxxxxx" "https://gitlabXXXX/api/v4/projects/13/repository/files/src%2Fcom%2Fgre%2Fjenkins%2FConstants.groovy?ref=foo"
But when I try to do the same in code I get error with this message = "404 File not found"
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.set("PRIVATE-TOKEN", "xxxxxxx");
System.out.println(restTemplate.exchange("https://gitlabXXXX/api/v4/projects/13/repository/files/src%2Fcom%2Fgre%2Fjenkins%2FConstants.groovy?ref=foo", HttpMethod.GET, new HttpEntity<>(httpHeaders), String.class).getBody());
Why it does not work? Maybe something in RestTempate change the URL or I do not know...
RestTemplate encodes your URL once again, so your request URL is:
https://gitlabXXXX/api/v4/projects/13/repository/files/src%252Fcom%252Fgre%252Fjenkins%252FConstants.groovy?ref=foo
So your % turns into %25 and this is not what gitlab API is waiting for.
Solution
You can use UriComponentsBuilder.build(true) method to tell your URI is already encoded:
String gitlabUriString = "https://gitlabXXXX/api/v4/projects/13/repository/files/src%2Fcom%2Fgre%2Fjenkins%2FConstants.groovy?ref=foo";
// true in build(true) tells parameters are already encoded
URI gitlabUri = UriComponentsBuilder.fromHttpUrl(gitlabUriString)
.build(true).toUri();
System.out.println(restTemplate.exchange(gitlabUri, HttpMethod.GET, new HttpEntity<>(httpHeaders), String.class).getBody());

setEntity equivalent in OkHttp - Android

I'm migrating from the Apache HTTP legacy client to OkHttp and I'm having some problems finding equivalences between both. A couple of days ago I asked about credentials in this same subject and now I'm stuck again:
In the old implementation I have this:
TimeStampRequestGenerator reqGen = new TimeStampRequestGenerator();
reqGen.setCertReq(true);
MessageDigest digest = MessageDigest.getInstance("SHA256");
digest.update(myData);
TimeStampRequest request = reqGen.generate(TSPAlgorithms.SHA256, digest.digest(), BigInteger.valueOf(100));
byte[] enc_req = request.getEncoded();
myHttpPost.setEntity(new ByteArrayEntity(enc_req));
The most relevant line is the last one (as the others just build the request and, lucky enough, I won't need to change them), which adds the entity to the HttpPost.
Checking this answer it seems the entity of a request is
the majority of an HTTP request or response, consisting of some of the headers and the body, if present. It seems to be the entire request or response without the request or status line
But this definition confuses me as I can't find the equivalence to something with "headers and the body" in OkHttp. What I've tried:
MediaType textPlain = MediaType.parse("text/plain; charset=utf-8");
RequestBody requestBody = RequestBody.create(textPlain, request.getEncoded().toString());
Request myNewRequest = (new Request.Builder()).url(urlString).post(requestBody).build();
But it didn't work (I'm getting a 500 from the server). Does anyone know the correct equivalence?
I finally found the answer: I can use the TimeStampRequest encoded as I did before, without any modification. The change is, as I thought, only for the setEntity.
This is the request using OkHttp:
MediaType textPlain = MediaType.parse("binary");
RequestBody requestBody = RequestBody.create(textPlain, request.getEncoded());
Request myNewRequest = (new Request.Builder()).url(urlString).post(requestBody).build;
As you can see the only change from the previous code I tried is that I use binary as the MediaType, which make sense as we are sending a byte array (previously used ByteArrayEntity from the Apache client).
Hope it helps somebody.

Spring restTemplate not working for single quotes in URL. Works with postman

Simple restTemplate exchange used for a GET request.
Header information
HttpHeaders headers = new HttpHeaders();
headers.setAccept(Arrays.asList(MediaType.ALL));
headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
headers.add("Authorization", ************);
URL:
/api/odata/GetAvailableObjects?fromTime=datetime'2018-02-02T12:00:00'&$format=json&toTime=datetime'2018-02-10T12:00:00'
I tried building this URL with either MessageFormat.format or URIBuilder.
The single quotes are the problem. So far I tried double-ing them, escaping them
or leaving them as they are.
I enabled some extra logging with :
logging.level.org.springframework.web.client.RestTemplate=DEBUG
This displays the URL.. if I copy that URL and paste it in POSTMAN, I receive results, from spring I receive 400 Bad request.
I suppose it might be some additional encoding to blame.
Any ideas?
The JWT had way to many scopes, the server API decided to throw a 400 without any message and the server logs were not available..
A flag in application.properties that sets the maximum header size.

Jenkins API : issues with tree filter in java

I am trying to fetch all job names by using below code
HttpGet httpGet = new HttpGet("http://myjenkins/api/json?depth=1&tree=jobs[name,jobs[name]]")
try(CloseableHttpClient httpclient = HttpClients.createDefault()) {
try(CloseableHttpResponse response = httpclient.execute(httpGet)){
int statusCode = response.getStatusLine().getStatusCode();
if (statusCode == 200) {
HttpEntity entity = response.getEntity();
String json = EntityUtils.toString(entity);
System.out.println(json)
}
}
}
The above code is not returning any json response (just an empty array []), but if I remove tree query in the url (http://myjenkins/api/json?depth=1), then I get json response with all jobs.
Why the query with filter is not returning any results ?. Is something wrong with HttpClient or jenkins api.
Can someone help me to resolve this issue.
Thanks
I would suggest just trying out that url in a browser. I tried it against my instance of jenkins, and it worked fine.
Also, the second parameter in the tree query seems unnecessary - even this url returns the job names -
http://myjenkins/api/json?depth=1&tree=jobs[name]
Couple of things ..
1) I tried it my browser and all queries worked well but not through java code. The reason is, in browser am already signed in (git oauth) and all queries are working where as in java am getting empty array since jenkins authorization set to not read jobs for anonymus (Stupid of me not check this before).
2) Once proper permissions are set I still had an issue with URI encoding, then I used URI builder
URI uri = new URIBuilder().setScheme("http").setHost(jenkinsHost)
.setPath("/api/json")
.setParameter("depth", "1").setParameter("tree", "jobs[name,jobs[name]]")
.build()
everything works now.

HTTP Bad Request response to Java POST call

I'm attempting to query a REST api using POST requests in a java application. I think I've set everything correctly, but I keep getting a Bad Request response.
HttpPost request = new HttpPost(requestURI);
request.addHeader("accept", "application/json");
request.addHeader(HttpHeaders.CONTENT_TYPE, "application/json");
HttpEntity entity = new StringEntity(requestBody + new Integer(PatientId).toString() + "}");
request.setEntity(entity);
The requestBody, accompanied by the number and curly brace, are valid JSON, and the requestURI is copy and pasted straight out of the API documentation, so I know I shouldn't be getting a Bad Request due to those.
Am I missing something in the setup?
The Content-Length header is missing. Some servers don't report the correct 4xx error (411 Length Required) and just issue a generic Bad Request error.
It ended up being a random slash that wasn't included in my URI.

Categories

Resources