Spring Rest Template calls in java - java

Hi I am trying to call some Soft layer APIs and was able to make simple calls as well as calls which include passing some ids using Spring's RestTemplate in java, but not able to make a similar call in java for below rest URL.
// formatted for readability
https://getInvoices?
objectFilter={
"invoices":{
"createDate":{
"operation":"betweenDate",
"options":[
{
"name":"startDate",
"value":[
"06/01/2016"
]
},
{
"name":"endDate",
"value":[
"06/02/2016"
]
}
]
}
}
}
Can anyone help me out how to do the same in java using springs rest template or even using soft layer rest client.

If you are willing to user Jersey Client API, your code could be like:
String json = "{\"invoices\":{\"createDate\":{\"operation\":\"betweenDate\",\"options\":[{\"name\":\"startDate\",\"value\":[\"06/01/2016\"]},{\"name\":\"endDate\",\"value\":[\"06/02/2016\"]}]}}}";
Client client = ClientBuilder.newClient();
WebTarget target = client.target("https://api.softlayer.com")
.path("rest")
.path("v3")
.path("SoftLayer_Account")
.path("getInvoices")
.queryParam("objectFilter",
URLEncoder.encode(json, StandardCharsets.UTF_8.toString()));
String result = target.request(MediaType.APPLICATION_JSON_TYPE).get(String.class);
With Spring RestTemplate, you would do:
String json = "{\"invoices\":{\"createDate\":{\"operation\":\"betweenDate\",\"options\":[{\"name\":\"startDate\",\"value\":[\"06/01/2016\"]},{\"name\":\"endDate\",\"value\":[\"06/02/2016\"]}]}}}";
RestTemplate restTemplate = new RestTemplate();
URI targetUrl = UriComponentsBuilder
.fromUriString("https://api.softlayer.com")
.path("rest")
.path("v3")
.path("SoftLayer_Account")
.path("getInvoices")
.queryParam("objectFilter",
URLEncoder.encode(json, StandardCharsets.UTF_8.toString()))
.build()
.toUri();
String result = restTemplate.getForObject(targetUrl, String.class);

You can either use RestTemplate
RestTemplate restTemplate = new RestTemplate();
String resourceUrl = "http://localhost:8080/resturl";
ResponseEntity<String> response = restTemplate.getForEntity(resourceUrl+ "/1", String.class);
or you can go with httpclient

Related

Post request to external service with data in Springboot

I need to send post request to external service with data. How can I achieve that in Springboot.
For example - need to connect and send a request to endpoint a 10.20.30.111:30 with some data. Then that data will be tested and send back test result as response.
I am new to java and did some research but did not get any success.
You can check HttpClient
URI uri = URI.create("10.20.30.111:30/endpoint");
HttpRequest req = HttpRequest.newBuilder().uri(uri).build();
HttpResponse<String> response = httpClient.send(req,HttpResponse.BodyHandlers.ofString());
String body = response.body();
If the response is json, you can convert the String response body to a custom object using JSONB.
Jsonb jsonb = JsonBuilder.create();
MyDataClass myDataObject = jsonb.fromJson(body, MyDataClass.class);
Check the Feign Client:
https://cloud.spring.io/spring-cloud-netflix/multi/multi_spring-cloud-feign.html
Your POST request will be implemented by an Interface like:
#FeignClient("stores")
public interface StoreClient {
#RequestMapping(method = RequestMethod.POST, value = "/stores/{storeId}", consumes = "application/json")
Store update(#PathVariable("storeId") Long storeId, Store store);
}

Sending request body in GET method not working

Im currently in a task in which i have to send a GET request with a body. Im a aware this isn't a good practice and that i should send the json through query params.
But I'm bound to do it like this.
So let's continue. I use RestTemplate with exchange but due to SimpleClientHttpRequestFactory implementation i cannot send a body with a GET method.
RestTemplate template = new RestTemplate(new CustomClientHttpRequestFactory());
httpHeaders.setContentType(APPLICATION_JSON);
httpHeaders.set("token", token.getToken());
httpHeaders.set("companyId", companyId);
URI uri = new URI(getInspectionsUrl);
HttpEntity<InspectionsInputDTO> entity = new HttpEntity<InspectionsInputDTO>(inputDTO, httpHeaders);
response = template.exchange(uri, GET, entity, InspectionsResponseDTO.class);
After some research i found the following code:
class CustomClientHttpRequestFactory extends SimpleClientHttpRequestFactory {
#Override
protected void prepareConnection(HttpURLConnection connection, String httpMethod) throws IOException {
super.prepareConnection(connection, httpMethod);
if ("GET".equals(httpMethod)) {
connection.setDoOutput(true);
}
}
}
// RestTemplate initialization
RestTemplate template = new RestTemplate(new CustomClientHttpRequestFactory());
This tries to override SimpleClientHttpRequestFactory httpMethod allowance but id does not work. The question is, how can i send a Request BODY in GET request with RestTemplate. Maybe there is another way to override SimpleClientHttpRequestFactory. Im new in this strange world of spring, sorry if im saying something wrong (:

GET/POST Requst to REST API using Spring Boot

I have a REST Service an external server like https://api.myrestservice.com and I have a Spring Boot Application running locally on http://localhost:8080. Now I want to make GET or POST request to the REST API address i.e https://api.myrestservice.com/users to get all users, using my locally running Spring Boot App i.e through http://localhost:8080/users. I am not getting how to redirect local app request to external server request.
I hope I got your question right. You are trying get your local app to get data from app running on your server.
You can use the below sample code in your spring boot application.
private void getUsers() {
final String uri = "https://api.myrestservice.com/users";
RestTemplate restTemplate = new RestTemplate();
Users result = restTemplate.getForObject(uri, Users.class);
System.out.println(result);
}
Then your getUsers can be invoked by getUsers Controller in your spring boot app.
I am adding the reference if you want to look at more examples -
https://howtodoinjava.com/spring-restful/spring-restful-client-resttemplate-example/
Making post Api call from your code to another server:
suppose you have a server https://searchEmployee... which returns you list of employees belonging to a particular city or belonging to a particular organization:
request body:
{
"city" : "Ranchi",
"organisation" : "Bank Of America"
}
json response: [{"name": "Vikash"},{"name":"kumar" },{}...etc]
Then to make a post api call you can use RestTemplate in java like this:
public void makeApiCall(){
final String uri = "https://searchEmployee...";
RestTemplate restTemplate = new RestTemplate();
String reqBody = "{"city": "Ranchi"}";
String result = restTemplate.postForObject(uri, reqBody, String.class);
// convert your result into json
try {
jsonResponse = new JSONObject(result);
} catch (JSONException e) {
e.printStackTrace();
}
//extract a value "name" from your json data:
try{
String value = jsonResponse.getString("name");
}catch(JSONException e) {
e.printStackTrace();
}
}
/********************************************************************/
if you have more than one request body parameters to set do it like this:
String reqBody = "{\"quantity\":100,\"name\":\"product1\",\"ifBoolean\":false}";
false is a boolean value here in your request body and 100 is an integer.
NOTE
if you are having problem in setting request body copy it directly from postman request body and paste it inside double quote.
There are many ways to do it. Like Apache HTTP Components and other. Sample
String type = "application/x-www-form-urlencoded" Or Set your desire content type;
String encodedData = URLEncoder.encode( rawData, "UTF-8" );
URL u = new URL("your remote url");
HttpURLConnection conn = (HttpURLConnection) u.openConnection();
conn.setDoOutput(true);
conn.setRequestMethod("POST");
conn.setRequestProperty( "Content-Type", type );
conn.setRequestProperty( "Content-Length",
String.valueOf(encodedData.length()));
OutputStream os = conn.getOutputStream();
os.write(encodedData.getBytes());
There are a couple of thing going on here, Like URLEncoding is really mattered when came to security.
Note: Source of above code:here.
This is very Simple By using Java Clients you can Use RestTemplate or UniRest
That one running on Remote is simply Producer and the one which is in local is Consumer So you can exchange method of Resttemplate or get method of Unirest
Example Code is here.
#RequestMapping(value = "/testclient")
public String testclient()
{
HttpHeaders headers = new HttpHeaders();
headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
HttpEntity<String> entity = new HttpEntity<String>(headers);
return restTemplate.exchange("https://www.mocky.io/v2/5185415ba171ea3a00704eed", HttpMethod.GET, entity, String.class).getBody();
}
For Unirest code is like this
HttpResponse<JsonNode> jsonResponse = null;
try {
jsonResponse = Unirest.get("https://www.mocky.io/v2/5185415ba171ea3a00704eed")
.header("accept", "application/json").queryString("apiKey", "123").asJson();
} catch (UnirestException e) { // TODO Auto-generated catch block
e.printStackTrace();
}
return jsonResponse.getBody().toString();

Calling remote method in spring with parameters

I have a class annoted with Service Annotation on server 1 .
#Service
public class MainHandler implements AbstractHandler {
#Autowired
private ServiceLocal defaultService;
#Override
public boolean execute(HttpServletRequest request, HttpServletResponse response) throws MsisdnServiceException {
System.out.println("The default Request" + request);
}
}
I want to call this method from other remote server after passing the request and get the response from this , what is the way to do in spring .
Invoking methods remotely would be using a technology called RMI, which you can google easily.
However, since you want to use HttpServletRequest and HttpServletResponse, you probably should write an Http Controller using Spring MVC. For that you can also google and very easily find excellent tutorials and guides.
You can use spring's RestTemplate to make communication with the servers.
First you need to create a controller on server 1 backend to get data from server 2:
#RestController
public class MyController {
#RequestMapping(value = "/endpoint", method = RequestMethod.POST)
String execute(#RequestBody MyClass object) {
System.out.println("Your data" + object);
}
}
On server 2 backend create a method that make a REST call to server 1's endpoint with RestTemplate:
void request() {
String url = "http://localhost:8080/endpoint";
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.set("Content-Type", "application/json");
JSONObject json = new JSONObject();
json.put("name", "yourName");
json.put("email", "name#gmail.com");
HttpEntity < String > httpEntity = new HttpEntity < String > (json.toString(), httpHeaders);
RestTemplate restTemplate = new RestTemplate();
String response = restTemplate.postForObject(url, httpEntity, String.class);
}

How to send JSON data in request body suing apache CXF webclient?

I am using apache cxf webclient to consume a service written in .NET
sample JSON to be sent in request body to a web service
{
"Conditions":
[
{
"Field":"TextBody",
"Comparer":"ContainsAny",
"Values":["stocks","retire"],
"Proximity":0
},
{
"Field":"SentAt",
"Comparer":"LessThan",
"Values":["1331769600"],
"Proximity":0
},
],
"Operator":"And",
"ExpireResultIn":3600
}
Is there any way if I want to submit data from both form and in Json body in one request ?
webclient API apache CXF -
web client API doc
WebClient client = WebClient.create("http://mylocalhost.com:8989/CXFTest/cxfws/rest/restservice/json");
client.type(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON);
After this which method and how to use ?
client.form(...form object )
client.post(...JSON string )
They have not shared Object of "Conditions" in JSON which I can annotate and pass to post method of client
I got answer here
Need to set JSON provider in my case it was jackson
List<Object> providers = new ArrayList<Object>();
providers.add( new JacksonJaxbJsonProvider() );
WebClient client = WebClient.create("http://localhost:8080/poc_restapi_cxf/api",
providers);
client = client.accept("application/json")
.type("application/json")
.path("/order")
.query("id", "1");
Order order = client.get(Order.class);
System.out.println("Order:" + order.getCustomerName());
There is a way to do this using annotations and suited my purpose:
#Post
#Path("mypath/json/whatever")
#Consumes({MediaType.APPLICATION_JSON_VALUE})
public Response postClient(#Context HttpHeaders headers, String input) {
//Here the String input will be equal to the supplied json.
//...
}

Categories

Resources