Make PUT call to external website using Rest Template - java

I'm currently trying to make a PUT call to my Gemfire Cache test enviroment
https://gemfire.docs.pivotal.io/95/geode/rest_apps/put_update_data.html
I've tried following a template like so
RestTemplate restTemplate = new RestTemplate();
String url = "http://localhost:8080/spring-rest/data/putdata/{id}/{name}";
Map<String, String> map = new HashMap<String, String>();
map.put("id", "100");
map.put("name", "Ram");
Address address = new Address("Dhananjaypur", "Varanasi","UP");
restTemplate.put(url, address, map);
}
Where in my case would it look something like this?
RestTemplate restTemplate = new RestTemplate();
String url = "gemfire.com/gemfire-api/v1/{region}/{key};
Map<String, String> map = new HashMap<String, String>();
map.put("region", "1");
map.put("key", "testKey");
restTemplate.put(url, "testStringtoPut", map);
}
This template leads into a 404 not found error for me,
can someone provide an insight on a proper method of doing this?

Try doing it this way, it should work
HttpEntity<String> request = new HttpEntity<String>(address.toString());
String url=http://localhost:8080/spring-rest/data/putdata/100/"Ram"
ResponseEntity <String> response= template.exchange(url,HttpMethod.PUT,request,String.class);

Related

RestTemplate POST with query parameter without request body

I am trying a POST method with RestTemplate. I need my request to have only 1 query parameter, without body (e.g. localhost:8080/predictions/init?date=xxxx).
My current code is the following :
String url = "http://localhost:8080/predictions/init";
String dateToGenerate = "xxxx";
MultiValueMap<String, String> headers = new LinkedMultiValueMap<String, String>();
Map map = new HashMap<String, String>();
map.put("Content-Type", "application/json");
headers.setAll(map);
Map req_payload = new HashMap();
req_payload.put("date", dateToGenerate);
HttpEntity<?> request = new HttpEntity<>(req_payload, headers);
restTemplateApi.postForEntity(url, request, String.class);
The side of the REST controller I'm trying to call is the following :
#PostMapping
#ResponseStatus(HttpStatus.OK)
public PredictionGenerated initializeOnePrediction(#RequestParam #NotEmpty String date) {
.............................
.............................
}
I'm currently receiving org.springframework.web.client.HttpClientErrorException: 400 null.
Any ideas?
If you have any many query param then set all in Multiple value Map as below.
MultiValueMap<String, String> param= new
LinkedMultiValueMap<String, String>();
param.put("date", datevalue);
Then create Http header add required content.
HttpHeaders headers = new HttpHeaders()
header.setContentType("application/json");
Create the URL as below.
URI url = UriComponentsBuilder.fromHttpUrl(base url)
.queryParams(param)
.build();
HttpEntity<?> request = new HttpEntity<>(req_payload,
headers);
restTemplateApi.postForEntity(url, request, String.class);

How to add body to a SpringBoot RestTemplate Put request that has headers [duplicate]

Please look at this simple code:
final String url = String.format("%s/api/shop", Global.webserviceUrl);
RestTemplate restTemplate = new RestTemplate();
restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
HttpHeaders headers = new HttpHeaders();
headers.set("X-TP-DeviceID", Global.deviceID);
HttpEntity entity = new HttpEntity(headers);
HttpEntity<Shop[]> response = restTemplate.exchange(url, HttpMethod.GET, entity, Shop[].class);
shops = response.getBody();
As you can see, above code is intended to GET list of shops from server (in json format) and map response to array of Shop objects.
Now I need to PUT new shop, for example as /api/shop/1. Request entity should have exactly the same format as returned one.
Should I add /1 to my url, create new Shop class object, with all fields filled with my values I want to put and then use exchange with HttpMethod.PUT?
Please, clarify it for me, I'm beginner with Spring. Code example would be appreciated.
[edit]
I'm double confused, because I just noticed also method RestTemplate.put(). So, which one should I use? Exchange or put()?
You could try something like :
final String url = String.format("%s/api/shop/{id}", Global.webserviceUrl);
RestTemplate restTemplate = new RestTemplate();
restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
HttpHeaders headers = new HttpHeaders();
headers.set("X-TP-DeviceID", Global.deviceID);
Shop shop= new Shop();
Map<String, String> param = new HashMap<String, String>();
param.put("id","10")
HttpEntity<Shop> requestEntity = new HttpEntity<Shop>(shop, headers);
HttpEntity<Shop[]> response = restTemplate.exchange(url, HttpMethod.PUT, requestEntity, Shop[].class, param);
shops = response.getBody();
the put returns void whereas exchange would get you a response, the best place to check would be documentation https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/client/RestTemplate.html

Spring Android - POST Request - URL Encoded Params from Class Object

I am trying to send some key-value pairs in Android Spring POST Request.It works correctly , if I am using a
MultiValueMap<String, String> map= new LinkedMultiValueMap<String, String>();
for that. Is there any way to avoid MultiValueMap & directly send the Class Object as Request.
One solution found is using Reflection , like the following
for (Field field:objAuth.getClass().getDeclaredFields()){
field.setAccessible(true);
map.add(field.getName(),field.get(objAuth)+"");
}
Code Snippet
RestTemplate restTemplate = new RestTemplate(true);
restTemplate.getMessageConverters().add(new FormHttpMessageConverter());
restTemplate.getMessageConverters().add(new MappingJacksonHttpMessageConverter());
restTemplate.getMessageConverters().add(new StringHttpMessageConverter());
HttpHeaders requestHeaders = new HttpHeaders();
requestHeaders.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
MultiValueMap<String, String> map= new LinkedMultiValueMap<String, String>();
Authenticate objAuth = new Authenticate();
objAuth.setUserId("1");
objAuth.setType("Type");
objAuth.setoAuthToken("00112233");
objAuth.setResponseCode("9689");
objAuth.setResponseMessage("Last Message");
/**
* Using Reflection
*/
for (Field field:objAuth.getClass().getDeclaredFields()){
field.setAccessible(true);
map.add(field.getName(),field.get(objAuth)+"");
}
HttpEntity<?> requestEntity = new HttpEntity<Object>(map , requestHeaders);
String response = restTemplate.postForObject("http://posttestserver.com/post.php",requestEntity, String.class);
When posting a media type of APPLICATION_FORM_URLENCODED with FormHttpMessageConverter, you must use a MultiValueMap, as seen here. Alternatively, if you want to post JSON, Jackson is used internally to convert any object class to JSON output. Spring uses message converters to determine how to read/write objects, and which types are compatible with which media types.

RestTemplate: How to send URL and query parameters together

I am trying to pass path param and query params in a URL but I am getting a weird error. Below is the code.
String url = "http://test.com/Services/rest/{id}/Identifier"
Map<String, String> params = new HashMap<String, String>();
params.put("id", "1234");
UriComponentsBuilder builder = UriComponentsBuilder.fromUriString(url)
.queryParam("name", "myName");
String uriBuilder = builder.build().encode().toUriString();
restTemplate.exchange(uriBuilder , HttpMethod.PUT, requestEntity,
class_p, params);
and my url is becoming http://test.com/Services/rest/%7Bid%7D/Identifier?name=myName
What should I do to make it work? I am expecting http://test.com/Services/rest/{id}/Identifier?name=myName so that params will add id to the url.
I would use buildAndExpand from UriComponentsBuilder to pass all types of URI parameters.
For example:
String url = "http://test.com/solarSystem/planets/{planet}/moons/{moon}";
// URI (URL) parameters
Map<String, String> urlParams = new HashMap<>();
urlParams.put("planet", "Mars");
urlParams.put("moon", "Phobos");
// Query parameters
UriComponentsBuilder builder = UriComponentsBuilder.fromUriString(url)
// Add query parameter
.queryParam("firstName", "Mark")
.queryParam("lastName", "Watney");
System.out.println(builder.buildAndExpand(urlParams).toUri());
/**
* Console output:
* http://test.com/solarSystem/planets/Mars/moons/Phobos?firstName=Mark&lastName=Watney
*/
restTemplate.exchange(builder.buildAndExpand(urlParams).toUri() , HttpMethod.PUT,
requestEntity, class_p);
/**
* Log entry:
* org.springframework.web.client.RestTemplate Created PUT request for "http://test.com/solarSystem/planets/Mars/moons/Phobos?firstName=Mark&lastName=Watney"
*/
An issue with the answer from Michal Foksa is that it adds the query parameters first, and then expands the path variables. If query parameter contains parenthesis, e.g. {foobar}, this will cause an exception.
The safe way is to expand the path variables first, and then add the query parameters:
String url = "http://test.com/Services/rest/{id}/Identifier";
Map<String, String> params = new HashMap<String, String>();
params.put("id", "1234");
URI uri = UriComponentsBuilder.fromUriString(url)
.buildAndExpand(params)
.toUri();
uri = UriComponentsBuilder
.fromUri(uri)
.queryParam("name", "myName")
.build()
.toUri();
restTemplate.exchange(uri , HttpMethod.PUT, requestEntity, class_p);
One-liner using TestRestTemplate.exchange function with parameters map.
restTemplate.exchange("/someUrl?id={id}", HttpMethod.GET, reqEntity, respType, ["id": id])
The params map initialized like this is a groovy initializer*
String url = "http://test.com/Services/rest/{id}/Identifier";
Map<String, String> params = new HashMap<String, String>();
params.put("id", "1234");
URI uri = UriComponentsBuilder.fromUriString(url)
.buildAndExpand(params)
.toUri();
uri = UriComponentsBuilder
.fromUri(uri)
.queryParam("name", "myName")
.build()
.toUri();
restTemplate.exchange(uri , HttpMethod.PUT, requestEntity, class_p);
The safe way is to expand the path variables first, and then add the query parameters:
For me this resulted in duplicated encoding, e.g. a space was decoded to %2520 (space -> %20 -> %25).
I solved it by:
String url = "http://test.com/Services/rest/{id}/Identifier";
Map<String, String> params = new HashMap<String, String>();
params.put("id", "1234");
UriComponentsBuilder uriComponentsBuilder = UriComponentsBuilder.fromUriString(url);
uriComponentsBuilder.uriVariables(params);
Uri uri = uriComponentsBuilder.queryParam("name", "myName");
.build()
.toUri();
restTemplate.exchange(uri , HttpMethod.PUT, requestEntity, class_p);
Essentially I am using uriComponentsBuilder.uriVariables(params); to add path parameters. The documentation says:
... In contrast to UriComponents.expand(Map) or buildAndExpand(Map), this method is useful when you need to supply URI variables without building the UriComponents instance just yet, or perhaps pre-expand some shared default values such as host and port. ...
Source: https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/util/UriComponentsBuilder.html#uriVariables-java.util.Map-
Since version 5.3 you can use this API to do this.
RequestEntity.post(urlString, urlParam1, urlParam2).headers(...).body(requestBody);
public static RequestEntity.BodyBuilder post(String uriTemplate,
Object... uriVariables)
Create an HTTP POST builder with the given string base uri template.
At the docs:
https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/http/RequestEntity.html#post-java.net.URI-
Or
template.exchange(..., uriVariables)
One simple way to do that is:
String url = "http://test.com/Services/rest/{id}/Identifier"
UriComponents uriComponents = UriComponentsBuilder.fromUriString(url).build();
uriComponents = uriComponents.expand(Collections.singletonMap("id", "1234"));
and then adds the query params.
Below is the working code, I had to pass two values in the respective placeholders while making the query parameter.
String queryParam = "Key=Project_{ProdjectCode}_IN_{AccountCode}"
Map<String, String> queryParamMap = new HashMap<>();
queryParamMap.put("ProjectCode","Project1");
queryParamMap.put("AccountCode","Account1");
UriComponents builder = UriComponentsBuilder.fromHttpUrl("http://myservice.com/accountsDetails").query(queryParam).buildAndExpand(queryParamMap);
restTemplate.exchange(builder.toUriString(), HttpMethod.GET,httpEntity,MyResponse.class);
Above code will make a GET call to url
http://myservice.com/accountsDetails?Key=Project_Project1_IN_Account1

how to pass queries to a url in rest template without uri

I am trying to make a GET call to a url and I need to pass in queries to get the response i want.
I am using spring framework and using Rest template to make the calls.
I know i can manually do this way:
Uritemplate(url+name={name}...
but this is a pain. I need a easier way and the hash map will be generated dynamically
So how do i pass in a map to a url without using uri encoder?
String url = "example.com/search
Map<String, String> params = new HashMap<String, String>();
params.put("name", "john");
params.put("location", "africa");
public static ResponseEntity<String> callGetService(String url, Map<String, String> param) {
RestTemplate rest = new RestTemplate();
rest.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
HttpEntity<?> reqentity = new HttpEntity<Object>(headers);
ResponseEntity<String> resp = rest.exchange(url, HttpMethod.GET, reqentity, String.class);
System.out.println(resp);
return resp;
}
So url will end up like this example.com/search?name=john&location=africa
response: {name:john doe, love: football} --- tons of json data
You can use UriComponentsBuilder and UriComponents which facilitate making URIs
String url = "http://example.com/search";
MultiValueMap<String, String> params = new LinkedMultiValueMap<String, String>();
params.add("name", "john");
params.add("location", "africa");
UriComponents uriComponents = UriComponentsBuilder.fromHttpUrl(url).queryParams(params).build();
System.out.println(uriComponents.toUri());
prints
http://example.com/search?name=john&location=africa
There are other options if you need to use URI variables for path segments.
Note that if you are sending an HTTP request, you need an valid URL. The HTTP URL schema is explained in the HTTP specification, here.
The UriComponentsBuilder provides methods to build all parts of the URL.

Categories