Make Rest Client using Spring Rest Template - spring

Here is my spring controller code..
#RequestMapping(value= "/save_item",
method = RequestMethod.POST,produces="application/json")
public #ResponseBody ModelMap saveItem(ModelMap model,
#RequestParam("id") String itemId,
#RequestParam("name") String itemName) {
model.addAttribute("itemId",itemId);
return model;
}
How can i make a rest client using spring rest tempalte?.
I need to send two parameters from my rest client(id,name).
Anyone Please help me.
Thanks.

You can create a RestTemplate object and execute as this
ResponseEntity<List<City>> result = restTemplate.exchange(
new StringBuilder(URL).append(city).toString(),
HttpMethod.GET, null, responseType);
In this project you can find a maven project with spring-boot and sptring-web that uses this restTemplate snippet and jackson for the json response
https://github.com/voliveirajr/dev-test

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.

How do I make spring boot RestTemplate client metrics not create a new tag for query parameters

I've got a spring boot application that is defining a RestTemplate bean as follows:
#Bean
public RestTemplate restTemplate(RestTemplateBuilder builder) {
return builder.build();
}
Also, pulling in spring-boot-starter-actuator and io.micrometer:micrometer-registry-prometheus.
When I use the injected RestTemplate as follows:
#Autowired
private RestTemplate restTemplate;
private String uriTemplate = "http://my.domain.com/bookstore-api/books";
public List<Book> getBooksByAuthor(String author) {
// create URI for "http://my.domain.com/bookstore-api/books?author={authorId}"
UriComponentsBuilder uriComponentsBuilder = UriComponentsBuilder
.fromUriString(uriTemplate)
.queryParam("author", author);
// make the GET
ResponseEntity<Book[]> responseEntity = restTemplate.getForEntity(uriComponentsBuilder.toUriString(),Book[].class);
// rest ommitted for brevity
}
When getBooksByAuthor("Tolkien") is called, we can then hit /metrics/prometheus and see the following:
http_client_requests_seconds_count{clientName="my.domain.com",method="GET",status="200",uri="/bookstore-api/books?author=Tolkien",} 2.0
http_client_requests_seconds_sum{clientName="my.domain.com",method="GET",status="200",uri="/bookstore-api/books?author=Tolkien",} 0.253227898
This would be fine, except that there are lots of authors out there, and eventually I will get the "too many tags" exception.
I would prefer to have the following (similar to how path variables get templated):
http_client_requests_seconds_count{clientName="my.domain.com",method="GET",status="200",uri="/bookstore-api/books?author={author}",} 2.0
http_client_requests_seconds_sum{clientName="my.domain.com",method="GET",status="200",uri="/bookstore-api/books?author={author}",} 0.253227898
Is this possible to achieve by modifying the way I use UriComponentsBuilder? The closest thing I've found is to define my own RestTemplateExchangeTagsProvider, and override the default to do some crazy regex replacement.
Just fixed same issue in SpringBoot 2.4.5 using:
responseEntity = restTemplate.exchange(
config.getDataUrl(),
HttpMethod.GET,
httpEntity,
new ParameterizedTypeReference<String>() {},
rowId);
where getDataUrl resolves to:
https://data-service-dev.apps.cloud.net/api/hbase/getData?rowId={rowId}
metrics:
http_client_requests_seconds_count{clientName="data-service-dev.apps.cloud.net",method="GET",outcome="SUCCESS",status="200",uri="/api/hbase/getData?rowId={rowId}",} 1.0
...
I have had a same problem. Maybe this information will help you.
In my case restTemplate.setUriTemplateHandler(handler) had overwritten annonymous
MetricsClientHttpRequestInterceptor#createUriTemplateHandler.
And the original url templates had not been stored into memory for prometheus.
DefaultUriBuilderFactory builderFactory = new DefaultUriBuilderFactory();
builderFactory.setEncodingMode(DefaultUriBuilderFactory.EncodingMode.NONE);
customizer.customize(restTemplate);
restTemplate.setUriTemplateHandler(handler);
So,
I changed order of the commands:
restTemplate.setUriTemplateHandler(handler);
customizer.customize(restTemplate);
Please check that there are no setting commands for restTemplate after MetricsClientHttpRequestInterceptor.customize(restTemplate).

Spring rest docs for Rest service with JSONObject as #RequestParam

I am trying to do write Spring rest docs for the rest service which accepts JSONObject as #RequestParam.
ex:
URL - http://localhost:9090/report?request={cdomain:automation,date:20190920}
Also I need to publish description for cdomain and date for understanding.
I am able to generate the rest docs for #PathVariable with below code:
URL - http://localhost:9090/report/11
this.mockMvc.perform(RestDocumentationRequestBuilders.get("/report/{id}",1))
.andExpect(status().isOk())
.andExpect(content().contentType("application/json;charset=UTF-8"))
.andDo(document("fin-report/balance-sheet",
pathParameters(parameterWithName("id")
.description("Identifier of the person to be obtained.")),
responseFields()...
Please let me know how to do documentation for JSONObject as #RequestParam, like below code and URL:
Code - #RequestMapping(method = RequestMethod.GET, produces = "application/json", path = "report)
public String getReport(#RequestParam(value="request") JSONObject jobjparam) {...}
URL - http://localhost:9090/report?request={cdomain:automation,date:20190920}

spring deferred result response in weblogic

I have implemented DeferredResult in spring MVC. It returns the right response in Tomcat8 but when I deployed into weblogic 12.1.3 gives me 404 error. I tried to debug to find out what is going on then at some point handler is looking for view in web-inf directory. I am confused here.
Could you please help me to understand?
I am using Spring
Java 7
Spring 4.2.0.RELEASE
Spring OAuth2
Weblogic 12.1.3
#RequestMapping(value = "/file/{id}")
#ResponseBody
public DeferredResult<ResponseEntity<Resource>> file(#PathVariable String id) {
DeferredResult<ResponseEntity<Resource>> result = new DeferredResult<>();
try {
final ImageObject image = null;
final Resource fileResource = new FileSystemResource(image.getImagePath().replace("E:", "C:"));
final HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
headers.setContentLength(fileResource.contentLength());
result.setResult(new ResponseEntity<>(fileResource, headers, HttpStatus.OK));
} catch (Exception e) {
}
return result;
}
Thanks in advance.
In my case Spring wrongly concatenated a #RequestMapping path of #RestController and #RequestMapping path of a method. #RequestMapping path of #RestController was duplicated in a resulting URI in Spring logs.
The only workaround I've found is to create #RestControllers for each required DeferredResult method without specifying a #RequestMapping path in the methods.
WebLogic 12.2.1.3.0, Spring 4.3.23.

How to send Multipart form data and upload PDF with RestTemplate Spring Boot

Good day Pals,
In my microservice and spring-boot app, I have a frontend employee microservice which consumes another microservice with file upload endpoint.
The calling service is based on spring rest controller and I am trying to consume a File-Upload endpoint using RestTemplate in a Spring Boot application. In a nutshell, trying to upload a PDF file.
I have explored the following SO post, but its not working for me:
jackson disable fail_on_empty_beans
I am testing this in postman and getting the following error:
org.springframework.http.converter.HttpMessageNotWritableException: Could not write content: No serializer found for class java.io.FileDescriptor and no properties discovered to create BeanSerializer.
Any help will be appreciated pleasee ....
Below are the main components -
Rest Controller ############
#RestController 
#RequestMapping(path = “/employee”) 
public class EmployeeController {
private EmployeeService empService;
#RequestMapping(value =“/emp/load”, method = RequestMethod.POST)
public
#ResponseBody
ResponseEntity<byte[]> handleFileUpload(
 #RequestParam("file") MultipartFile file, #RequestParam String a, #RequestParam String b, #RequestParam String c, #RequestParam String d, #RequestParam String e) throws Exception {
return empService.handleFileUpload(file, a, b, c, d, e);
}
}
The service Implementation
#Service
public class EmployeeServiceImpl implements EmployeeService{
 
 #Value(“${emp.base.url}")
private String EMP_BASE_URI;
public ResponseEntity<byte[]>handleFileUpload(MultipartFile file, String a, String b, String c, String d, String e) {
final String uri = EMP_BASE_URI + "/upload";
RestTemplate restTemplate = getMappedRestTemplate();
MultiValueMap<String, Object> params = new LinkedMultiValueMap<String, Object>();
params.add("file", file);
params.add(“a”, a);

params.add(“b”, b);
params.add(“c”, c);

params.add(“d”, d);
params.add(“e”, e);
HttpHeaders headers = new HttpHeaders();
headers.set("Content-Type", "multipart/form-data");
ResponseEntity<byte[]> response = restTemplate.exchange(uri, HttpMethod.POST, new HttpEntity<>(params, headers), byte[].class);
return new ResponseEntity<>(response.getBody(), response.getStatusCode());
} 
 
 
 
private RestTemplate getMappedRestTemplate(){
RestTemplate restTemplate = new RestTemplate();
ObjectMapper newObjectMapper = new ObjectMapper();

 newObjectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS,false);

newObjectMapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);
MappingJackson2HttpMessageConverter mappingJacksonHttpMessageConverter=new MappingJackson2HttpMessageConverter();
FormHttpMessageConverter formConvertor = new FormHttpMessageConverter();

restTemplate.getMessageConverters().add(formConvertor);
restTemplate.getMessageConverters().add(mappingJacksonHttpMessageConverter);
restTemplate.getMessageConverters().add(new StringHttpMessageConverter());

return restTemplate;
}
}
I am getting the following error:
Failed to write HTTP message: org.springframework.http.converter.HttpMessageNotWritableException: Could not write content: No serializer found for class java.io.FileDescriptor and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) ) (through reference chain: org.springframework.web.multipart.support.StandardMultipartFile["inputStream"]->java.io.FileInputStream["fd"]); nested exception is com.fasterxml.jackson.databind.JsonMappingException: No serializer found for class java.io.FileDescriptor and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) ) (through reference chain: org.springframework.web.multipart.support.StandardMultipartFile["inputStream"]->java.io.FileInputStream["fd"])
Please, any help with be appreciated.
I have been stuck on this all day.
I have gone for sending the params (including the pdf file as a byte stream i.e. byte[]) as json in the request body using the following method signature:
#RequestMapping(value = "/upload", method = RequestMethod.POST)
#ResponseStatus(HttpStatus.CREATED)
public #ResponseBody Long handleFileUpload(#Valid #RequestBody Invoice uploadedInvoice){
...
}

Resources