translating http to RestTemplate - spring

I have this elasticsearch query that works just fine when I plug it in to a browser:
http://my.server:9200/customer/customer/_search?q=age:[0+TO+1]&pretty
I'd really like to use it with Spring's RestTemplate:
String a = "http://my.server:9200/customer/customer/_search?q=age:[\"0\"+TO+\"1\"]";
String s = restTemplate.getForObject(a, String.class);
JSONObject j = new JSONObject(s);
and then access the keys/values via the JSONObject api.
Problem is, I'm getting the error:
org.springframework.web.client.HttpClientErrorException: 400 Bad Request
from:
String s = restTemplate.getForObject(a, String.class);
What am I missing?

Is ES throwing the 400 ?
you might want to try that :
String url = "http://my.server:9200/customer/customer/_search?q={q}
Map params = new LinkedHashMap();
params.put("q", "age:[0 TO 1]");
restTemplate.getForObject(url, String.class, params)

Related

REST API call from spring boot not working

I am trying to fetch live data from NSE options trading. Below code is not working and the request made is stuck without any response.
Any workaround on this?
public void getLiveBankNiftyData() {
String RESOURCE_PATH = "https://www.nseindia.com/api/option-chain-indices?symbol=BANKNIFTY";
ResponseEntity<Object[]> responseEntity = restTemplate.getForEntity(RESOURCE_PATH, Object[].class);
Object[] objects = responseEntity.getBody();
}
i tried this
// request url
String url = "https://www.nseindia.com/api/option-chain-indices?symbol=BANKNIFTY";
// create an instance of RestTemplate
RestTemplate restTemplate = new RestTemplate();
// make an HTTP GET request
String json = restTemplate.getForObject(url, String.class);
// print json
System.out.println(json);
I found a way out. Instead of using RestTemplate I used WebClient and this solved the issue.

Why im getting Exception- Not enough variables available to expand in Spring Rest URI call?

im working on a rest API call related to Payments. But i encountered with an exception. I know this comes due to setting parameters to the rest uri.
String uri = "https://test-gateway.mastercard.com/api/rest/version/52/merchant/{merchantId}/order/{orderId}/transaction/{transactionId}";
LinkedMultiValueMap<String, String> uriVars = new LinkedMultiValueMap<>();
uriVars.add("merchantId", _paymentInstrument.getAcquirerMid());
uriVars.add("orderId", _paymentInstrument.getOrderId().toString());
uriVars.add("transactionId", _paymentInstrument.getTargetTransactionId().toString());
String uri = UriComponentsBuilder.fromHttpUrl(url)
.queryParams(uriVars).build().toUriString();
VoidRequest voidRequest =
createVoidRequest(_paymentInstrument.getTargetTransactionId());
HttpEntity<VoidRequest> requestEntity = new HttpEntity<>(voidRequest, headers);
ResponseEntity<TransactionResponse> responseEntity = restTemplate.exchange(uri, HttpMethod.PUT, requestEntity, TransactionResponse.class);
Exception im getting is Using RestTemplate in Spring. Exception- Not enough variables available to expand "merchantId".

Spring get all queries params as a string

I have an API gateway that handles all GET requests and forwards them to the correct url like so
#RequestMapping(value = "**", method = RequestMethod.GET)
public #ResponseBody ResponseEntity<String> doGet(HttpServletRequest req) {
String uriString = (String) req.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE);
String targetHost = uriString.split("/")[0];
URI uri = UriComponentsBuilder.fromUriString(targetHost)
.path(uriString)
.build().normalize().encode().toUri();
try {
ClientHttpRequest request = requestFactory.createRequest(uri, HttpMethod.GET);
request.getHeaders().add(HttpHeaders.ACCEPT, "application/json");
ClientHttpResponse response = request.execute();
HttpStatus status = response.getStatusCode();
String json = readBodyAsString(response);
return new ResponseEntity<>(json, status);
} catch (IOException ioe) {
StringBuilder sb = new StringBuilder();
sb.append("{\"message\": \"").append(ioe.getMessage()).append("\"}");
return new ResponseEntity<>(sb.toString(), HttpStatus.INTERNAL_SERVER_ERROR);
}
}
This works really well for all get requests that have any number of paths.
Problem is the
HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE
Only grabs the paths of a given URL and not the Query Params
So if this controller gets a request with /api/path/path/path it works but if it gets /api/path/path/path?query=1?search=2 for example it will only grab /api/path/path/path and then the subsequent request will fail since it required query params.
How can I get the entire path of the wild card match to include any queryParams that might be here
Thanks
Really simple just needed to use req.getQueryString() to get all the query params as a string.
Also important to note that I needed to pass the query as a .query() on the UriComponentsBuilder so that it gets encoded properly.
URI uri = UriComponentsBuilder.fromUriString(targetHost)
.path(uriString)
.query(queryParams)
.build().normalize().encode().toUri();

RestTemplate gives 400 Bad Request Error on a Get Request

When I try to make a get request with Spring's RestTemplate, it gives 400 BAD Request. I can call the same url from javascript successfully with the headers below :
But the code below does not work. What might be the cause?
public Entity getEntityByUri(String uri) {
String req = "http://live.dbpedia.org/sparql?query=DESCRIBE%20%3Chttp://dbpedia.org/resource/Concept_learning%3E&format=application%2Fjson-ld";
HttpHeaders headers = new HttpHeaders();
headers.setAccept(Arrays.asList(MediaType.ALL));
HttpEntity<String> httpEntity = new HttpEntity<String>(headers);
new RestTemplate().exchange(req, HttpMethod.GET, httpEntity, Map.class);
Entity entity = new Entity();
return entity;
}
Your url is already encoded. Popular browsers such as Chrome are capable of understanding and responding appropriately. However, it's not the same case with RestTemplate.
I had to decode your uri here and the decoded uri is DESCRIBE <http://dbpedia.org/resource/Concept_learning>
Having checked the browser console, I got to know you have two query strings passed in the url, they are query and format holding values DESCRIBE <http://dbpedia.org/resource/Concept_learning> and application/json-ld respectively.
I assume Entity class is the pojo class of json response.
Have created Entity as from your json response:
public class Entity {
private String value;
private String type;
// getters and setters omitted for brevity
}
Finally in your getEntityByUri method have got the instance of UriComponentsBuilder which handles uri encoding and query params.
To sum up, your getEntityByUri looks below.
public HttpEntity<Entity> getEntityByUri() {
String req = "http://live.dbpedia.org/sparql";
UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(req)
.queryParam("query",
"DESCRIBE <http://dbpedia.org/resource/Concept_learning>")
.queryParam("format", "application/json-ld");
HttpHeaders headers = new HttpHeaders();
headers.setAccept(Arrays.asList(MediaType.ALL));
HttpEntity<String> httpEntity = new HttpEntity<String>(headers);
return new RestTemplate().exchange(builder.build().encode().toUri(), HttpMethod.GET, httpEntity, Entity.class);
}
The above method didn't throw HTTP400 as the required query params have been passed in builder object.
Hope this helps and good luck!
Anyone getting same error make sure your URL is decoded means no percent symbols in url (if space in param values).
This worked for me
try {
requestURL = URLDecoder.decode("http://api.com?p=1&groups=3212&affected-since=2019-06-06T14%3A11%3A14.880&detail=full&after-id=43536", "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
Maybe
headers.setAccept(Arrays.asList(MediaType.ALL));
generates a malformed "Accept" header field? (FWIW, why do you send it at all???)

RestTemplate POST request urlformencoded gives 400 (Bad Request)

I have the following request :
String url = "url to oauth_token";
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
RestTemplate restTemplate = new RestTemplate();
String body = "grant_type=authorization_code&client_id=123&client_secret=123&"
+ "redirect_uri=https://axyz.com&code=123";
HttpEntity<Object> entity = new HttpEntity<>(body, headers);
Object token = restTemplate.exchange(url, HttpMethod.POST, entity, Object.class);
This seems to return 400 (Bad Request). I have also tried its alternatives where body is a MultiValueMap but this is what makes the most sense to me. Is there something wrong with the way I am trying the request?
The values of the POST fields should be URL encoded (you can use URLEncoder.encode(value, "UTF-8") for each value while concatenating the body string). That's why you get 400 error.
You'd better use a more convenient way to create a POST form entity with keys and values, which will URL encode your values automatically:
List<NameValuePair> formparams = new ArrayList<NameValuePair>();
formparams.add(new BasicNameValuePair("param1", "value1"));
formparams.add(new BasicNameValuePair("redirect_uri", "https://axyz.com"));
...
UrlEncodedFormEntity entity = new UrlEncodedFormEntity(formparams, Consts.UTF_8);

Resources