How to perform an http request to another server from spring boot controller - spring

i want to perform a get request on a server hosted on localhost:80 (for example but could be every host) from my spring boot application hosted on localhost:8080.
For example i want to get an image hosted on locahost:80/image.jpg from my spring application. How can i handle this?

You can use RestTemplate for that.
RestTemplate restTemplate = new RestTemplate();
String uri = localhost:80; // or any other uri
HttpHeaders headers = new HttpHeaders();
headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
headers.add("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36");
HttpEntity<String> entity = new HttpEntity<>("parameters", headers);
ResponseEntity<?> result =
restTemplate.exchange(uri, HttpMethod.GET, entity, returnClass);
return result.getBody();
If you want to get images then use following method:
String url = "http://img.championat.com/news/big/l/c/ujejn-runi_1439911080563855663.jpg";
byte[] imageBytes = restTemplate.getForObject(url, byte[].class);
Files.write(Paths.get("image.jpg"), imageBytes);
You will also need to configure ByteArrayHttpMessageConverter in application config:
#Bean
public RestTemplate restTemplate(List<HttpMessageConverter<?>> messageConverters) {
return new RestTemplate(messageConverters);
}
#Bean
public ByteArrayHttpMessageConverter byteArrayHttpMessageConverter() {
return new ByteArrayHttpMessageConverter();
}

If you want to send a request with spring you can do
//first create e restemplate variable
RestTemplate restTemplate=new RestTemplate();
//you can create and edit header
HttpHeaders header= new HttpHeaders();
header.add("Authorization", "*****************");
header.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
header.add("Accept", "application/json");
//you can create and edit body to
MultiValueMap<String, String> body= new LinkedMultiValueMap<String, String>();
body.add("grant_type", "client_credentials");
HttpEntity<MultiValueMap<String, String>> requeteHttp =new HttpEntity<MultiValueMap<String, String>>(body, header);
//After you can create a request
ResponseEntity<Response_class> reponse = restTemplate.postForEntity("your api link", requeteHttp , Response_class.class);
//if you want to send a get request you can edit postForEntity to get
About Response_class
if you know the return type of the request, you can create a class and use it here, otherwise you can use string instead
if your request returns a json like this
{
"token_type":"***",
"access_token":"***",
"expires_in":"***",
}
you can create a Response_class controller(class) and call it like we did above otherwise you can use string instead
public class Response_class{
private String token_type;
private String access_token;
private String expires_in;
public Response_class(String token_type, String access_token, String expires_in) {
this.token_type = token_type;
this.access_token = access_token;
this.expires_in = expires_in;
}
public Response_class() {
}
public String getToken_type() {
return token_type;
}
public void setToken_type(String token_type) {
this.token_type = token_type;
}
public String getAccess_token() {
return access_token;
}
public void setAccess_token(String access_token) {
this.access_token = access_token;
}
public String getExpires_in() {
return expires_in;
}
public void setExpires_in(String expires_in) {
this.expires_in = expires_in;
}
}

You can use WebClient:
byte[] image = WebClient.create("locahost:80/image.jpg")
.get()
.accept(MediaType.IMAGE_JPEG)
.retrieve()
.bodyToMono(byte[].class)
.block();

Related

how to return only HTTP Status code, if we hit one pre-defined endpoint

When I hit
#FeignClient(name = "abc_abc", url = "${abc.host}")
public interface validateClient {
#PostMapping(path = "/api/abc/validate",
consumes = "application/json",
produces = "application/json")
**public <?> validateResponse**(#RequestHeader HttpHeaders htppHeaders, #RequestParam Map<String, Object> params,
#RequestBody String request);
}
in this example API: /api/abc/validate
i just want to return only HTTP status code
what is the return type of validateResponse method ? please some one plz suggest
Try use ResponseEntity without any "body", here an example.
#PostMapping(path = "/api/abc/validate",
consumes = "application/json",
produces = "application/json")
public ResponseEntity validateResponse(#RequestHeader HttpHeaders htppHeaders, #RequestParam Map<String, Object> params,
#RequestBody String request) {
return ResponseEntity.status(HttpStatus.FOUND).build();
}
You can choose from standard HttpStatus enum, or simply insert an integer for your custom needs

Get specific response value from the API in SpringBoot

I am calling one post call and getting the response like below :
Now I want to get the value of the access token and do some logic. How to get the value from the response? Can anyone please help.
Service code of the API.
public String getToken(User user) throws JsonMappingException, JsonProcessingException {
ObjectMapper mapper = new ObjectMapper();
System.out.println(clientId+clientPass);
String plainCreds = clientId+":"+clientPass;
byte[] plainCredsBytes = plainCreds.getBytes();
byte[] base64CredsBytes = Base64.getEncoder().encode(plainCredsBytes);
String base64Creds = new String(base64CredsBytes);
HttpHeaders headers = new HttpHeaders();
headers.add("Authorization", "Basic " + base64Creds);
HttpEntity<String> request=new HttpEntity<String>(headers);
String uri = url+ user.getUser_id()
+ "&password=" + user.getPassword();
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<String> result = restTemplate.exchange(uri, HttpMethod.POST, request, String.class) ;
JsonNode newNode = mapper.readTree(result.getBody());
ObjectNode node = ((ObjectNode) newNode).put("Authentication", "Successful");
return mapper.writerWithDefaultPrettyPrinter().writeValueAsString(node);
}
I was able to figure it out.
I used
node.get("access_token")
And it worked!
You can write DTO for response:
public class ResponseSample {
#JsonProperty("access_token")
String accessToken;
....
}
(or deserialize to Map)
and instead calling ResponseEntity<String> result = restTemplate.exchange(...) you can call
ResponseEntity<ResponseSample> result = restTemplate.exchange(..., ResponseSample.class)

JSON to CSV API with Spring RestTemplate

I want to hit a JSON to CSV API after grabbing a JSON from my own API. The JSON to CSV API requires email and JSON passed in a POST request. Now I am able to store JSON locally but, how do I pass in both the email and JSON in the request and how do I handle the CSV from the response?
Controller
#PostMapping("/generateExcel")
public String getEmployeeCsv(#RequestBody String email) {
HttpHeaders headers = new HttpHeaders();
headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
HttpEntity<String> entity = new HttpEntity<String>(headers);
String json = restTemplate.exchange("http://localhost:8080/SwaggerTest/employees", HttpMethod.GET, entity, String.class).getBody();
entity = new HttpEntity<String>(json, email, headers);
return restTemplate.exchange("https://json-csv.com/api/getcsv", HttpMethod.POST, entity, String.class).getBody();
}
Update:
I created a EmployeeCsvParams class with email and json String fields as suggested by #Adrien but I still need to handle the CSV from the response.
#PostMapping("/generateExcel")
public String getEmployeeCsv(#RequestBody String email) {
HttpHeaders headers = new HttpHeaders();
EmployeeCsvParams params = new EmployeeCsvParams();
headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
HttpEntity<String> entity = new HttpEntity<String>(headers);
String json = restTemplate.exchange("http://localhost:8080/SwaggerTest/employees", HttpMethod.GET, entity, String.class).getBody();
params.setEmail(email);
params.setJson(json);
HttpEntity<EmployeeCsvParams> entity2 = new HttpEntity<EmployeeCsvParams>(params, headers);
return restTemplate.exchange("https://json-csv.com/api/getcsv", HttpMethod.POST, entity2, String.class).getBody();
}
From spring docs #RequestBody "You can use the #RequestBody annotation to have the request body read and deserialized into an Object through an HttpMessageConverter. ..."
So i assume you can create the object bellow and use it as argument in your endpoint.
public class EmployeeCsvParams {
/* Fields */
private String email;
private String json;
/* Getters and Setters */
public String getEmail() { return this.email; }
public void setEmail(String email) { this.email = email; }
public String getJson() { return this.json; }
public void setJson(String json) { this.json = json; }
}
#PostMapping("/generateExcel")
public String getEmployeeCsv(#RequestBody EmployeeCsvParams employeeCsvParams)
{
/* ... */
}

Spring Service and RestTemplate Client always Unexpected end of file from server

My POJO:
public class Product {
String name;
int price;
public Product(){
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
}
My Controller:
#RestController
#RequestMapping("/rest")
public class RstController {
#RequestMapping(value = "/getProductPost2", method=RequestMethod.POST, produces = {"application/json"})
public Product getProductPost2(#RequestBody Product p){
System.out.println(p.getName());
return p;
}
My Client, using JUnit(I've tried all the lines commented, the same error everytime):
public class RestTemplatePostTest {
#Test
public void testee(){
String url = "http://localhost:8443/ShoppingCartSpringMVCSpringDataHibernate/rest/getProductPost2";
Product p = new Product();
p.setName("produs");
p.setPrice(22);
String json = "{\"name\":\"pen\",\"price\":10}";
HttpEntity<Product> request = new HttpEntity<Product>(p);
RestTemplate rt = new RestTemplate();
rt.postForObject(url, json, String.class);
//rt.postForObject(url, p, String.class);
//rt.exchange(url, HttpMethod.POST, request, Product.class);
//rt.exchange(url, HttpMethod.POST, request, String.class);
//assertEquals("produs",p2.getName());
}
}
When I'm using POSTMAN, it works.
I haven't found any other option on the internet and it's been 2 days since I'm trying to do this . Any opinion or tutorial is more than welcomed.
Edit1: Also, a simple GET also doesn't work,but it works in browser or in POSTMAN.
#RequestMapping(value = "/getProductGet", method=RequestMethod.GET)
public String getProductGet{
return "hello World!!";
}
#Test
public void testGet(){
String url = "http://localhost:8443/ShoppingCartSpringMVCSpringDataHibernate/rest/getProductGet";
RestTemplate rt = new RestTemplate();
ResponseEntity<String> response= rt.getForEntity(url, String.class);
}
When in debug mode, it stops in my breakpoint when called by browser or POSTMAN, but it doesn't get there when using rest template.
Perhaps something to do with the fact that I'm using Spring security?
I think the problem is that your request has a wrong data type which server can not parse and thus can not reply.
Since you are sending a POST request with JSON Content-Type, your Product must be JSON-encoded.
To do that, you need to add a json converter so modify your code to some thing like this:
RestTemplate rt= new RestTemplate();
rt.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
Product recievedProduct = rt.postForObject(url, p, Product.class);
Don't forget to add the jackson dependency.

Spring RestTemplate Handling Multiple Responses

I'm consuming a restful service, What I observed is based on the request I see multiple responses for the same end point.
For Ex : I request a GET call with the some parameters for a PDF document.
if the response is good and the content type is application/pdf its giving a pdf document.
if the document is not available, the content type is application/xml and the response is giving the error code, error description.
Any input is much appreciated !
Thanks,
Sudheer.
You can use the ResponseEntity class of Spring, you can set the class to return the object what you want. You can change the content type, and everything you want.
here there is an example of file
#RequestMapping(value = URIConstansts.GET_FILE, produces = { "application/json" }, method = RequestMethod.GET)
public #ResponseBody ResponseEntity getFile(#RequestParam(value="fileName", required=false) String fileName,HttpServletRequest request) throws IOException{
ResponseEntity respEntity = null;
byte[] reportBytes = null;
File result=new File("/home/arpit/Documents/PCAP/dummyPath/"+fileName);
if(result.exists()){
InputStream inputStream = new FileInputStream("/home/arpit/Documents/PCAP/dummyPath/"+fileName);
String type=result.toURL().openConnection().guessContentTypeFromName(fileName);
byte[]out=org.apache.commons.io.IOUtils.toByteArray(inputStream);
HttpHeaders responseHeaders = new HttpHeaders();
responseHeaders.add("content-disposition", "attachment; filename=" + fileName);
responseHeaders.add("Content-Type",type);
respEntity = new ResponseEntity(out, responseHeaders,HttpStatus.OK);
}else{
respEntity = new ResponseEntity ("File Not Found", HttpStatus.OK);
}
return respEntity;
}
Here there is an example of Json
#ResponseBody ResponseEntity<? extends AbstractResponse> createUser(#RequestBody String requestBody) {
if(!valid(requestBody) {
ErrorResponse errResponse = new ErrorResponse();
//populate with error information
return new ResponseEntity<ErrorResponse> (errResponse, HTTPStatus.BAD_REQUEST);
}
createUser();
CreateUserSuccessResponse successResponse = new CreateUserSuccessResponse();
// populate with more info
return new ResponseEntity<CreateUserSuccessResponse> (successResponse, HTTPSatus.OK);
}

Resources