Spring Boot Microservices communication using Rest Template - spring

I am trying to implement to Rest Template to talk to another Microservice but it's not working properly, I am new to spring please help me complete this code.
#GetMapping("/name")
public Product name(){//#PathVariable String name){
RestTemplate restTemplate = new RestTemplate();
Product x = restTemplate.getForObject("http://localhost:8081/products", Product.class);
return x;
}
2021-03-18 10:31:34.072 ERROR 56434 --- [nio-8080-exec-2]
o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for
servlet [dispatcherServlet] in context with path [] threw exception
[Request processing failed; nested exception is
org.springframework.web.client.RestClientException: Error while
extracting response for type [class com.java.connect.entity.Product]
and content type [application/json]; nested exception is
org.springframework.http.converter.HttpMessageNotReadableException:
JSON parse error: Cannot deserialize instance of
com.java.connect.entity.Product out of START_ARRAY token; nested
exception is
com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot
deserialize instance of com.java.connect.entity.Product out of
START_ARRAY token
at [Source: (PushbackInputStream); line: 1, column: 1]] with root cause

You don't get a single Product but an array of Products.
So you have to use
ResponsEntity<Product[]> response = restTemplate.getForObject("http://localhost:8081/products", Product[].class);
Product[] products = response.getBody();
But I think this is not what you want and I assume that name would be a query parameter of the rest endpoint. So you have to pass name like this:
#GetMapping("/name")
public Product name(){#PathVariable String name){
RestTemplate restTemplate = new RestTemplate();
Product x = restTemplate.getForObject("http://localhost:8081/products?name=" + name, Product.class);
return x;
}

You need to make below changes to get list of products using RestTemplate.
ResponseEntity<Product[]> response =
restTemplate.getForEntity(
"http://localhost:8080/products/",
Product[].class);
Product [] products = response.getBody();

Related

JSON parserError while creating user in Openfire through spring boot application

In my project I have to create a chat box. For that I have to use Open-fire server. I am having the service for creating users in this server.
I am facing the problem when I am trying to access the openfire service from my spring boot application.
I am have created the model for the user also created the service and provided implementation to it.
This is my model class,
public class OpenFireUser {
private String firstname;
private String username;
private String password;
private String email;
<----getters and setters--->
}
This is my service,
public UserCreationResponse createOpenFireUser(String authorization,User createUser) {
OpenFireUser user= new OpenFireUser();
user.setEmail(createUser.getEmail());
user.setFirstname(createUser.getFirstname().toLowerCase());
user.setPassword("Passw0rd");
user.setUsername(createUser.getUsername().toLowerCase());
UserCreationResponse response=new UserCreationResponse();
RestTemplate restTemplate = new RestTemplate();
try{
MultiValueMap<String, String> headers = new LinkedMultiValueMap<String, String>();
headers.add("Authorization", authorization);
headers.add("Content-Type", "application/json");
headers.add("Accept", "application/json");
restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
HttpEntity<OpenFireUser> requestObject = new HttpEntity<OpenFireUser>(user, headers);
ResponseEntity<String> responseEntity=restTemplate.postForEntity(OPENFIRE_REST_ENDPOINT, requestObject,String.class);
int statusCode = responseEntity.getStatusCodeValue();
if(statusCode==201){
response.setResponseCode(statusCode);
return response;
}else{
response.setResponseCode(MessageConstant.ResponseCode.ProcessFail.value());}
return response;
}catch(HttpClientErrorException clientErr){
response.setUserMessage(clientErr.getMessage());
response.setResponseCode(clientErr.getStatusCode().value());
response.setResponseMessage(MessageConstant.CodeMessage.ProcessFail.value());
return response;
}
catch(Exception e)
{
response.setResponseCode(MessageConstant.ResponseCode.ProcessFail.value());
response.setResponseMessage(MessageConstant.CodeMessage.ProcessFail.value());
return response;
}
}
This is controller code for calling service,
#RequestMapping(value = "/createOpenFireUser", method = RequestMethod.POST, consumes = "application/json;charset=UTF-8",produces = "application/json;charset=UTF-8")
public UserCreationResponse createOpenFireUser(#RequestBody User createUser) {
logger.debug("Entering inside createOpenFireUser(#RequestBody OpenFireUser createUser) method");
//logger.debug("Create user request : {}" , createUserRequestEntity);
return userService.createOpenFireUser("authorizationKey",createUser);
}
while sending data from postman I am getting error like,
Failed to read HTTP message: org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Can not deserialize instance of com.exelatech.printshop.model.User out of START_ARRAY token; nested exception is com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of com.exelatech.printshop.model.User out of START_ARRAY token
at [Source: java.io.PushbackInputStream#6c88daca; line: 1, column: 1]
2018-07-20 15:59:13.535 WARN 9988 --- [nio-9090-exec-2] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved exception caused by Handler execution: org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Can not deserialize instance of model.User out of START_ARRAY token; nested exception is com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of model.User out of START_ARRAY token
at [Source: java.io.PushbackInputStream#6c88daca; line: 1, column: 1]
On postman I am getting response like,
"timestamp": 1532082553781,
"status": 400,
"error": "Bad Request",
"exception": "org.springframework.http.converter.HttpMessageNotReadableException",
"message": "JSON parse error: Can not deserialize instance of model.User out of START_ARRAY token; nested exception is com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of model.User out of START_ARRAY token\n at [Source: java.io.PushbackInputStream#6c88daca; line: 1, column: 1]",
Can anyone help me to solve my issue?
Error was in sending object through postman.
Previously I was sending request object like,
[
{
"firstname" : "Jyoti",
"username" : "JyotiNH",
"password":"Passw0rd",
"email" : "jyoti.kanor#exelaonline.com"
}
]
which is object.
But my method receiving parameter as array of strings,
So when I sent request with object like following structure, it successfully created the user.
{
"firstname" : "Jyoti",
"username" : "JyotiNH",
"password":"Passw0rd",
"email" : "jyoti.kanor#exelaonline.com"
}

Random NullPointerExceptions with missing stacktrace in DispatcherServlet

I see random NullPointerException when one of my endpoints is accessed.
I know what an NPE is, but please bear with me, I have many issues here :
problem happens maybe once in every 10000 calls
if I replay the same request a second time it works OK
it looks as if it doesn't get to the code in my controller (no statements are logged)
and, most annoying... I don't have a stacktrace to help me pinpoint the problem.
This is what it is logged :
[p-nio-80-exec-4] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.NullPointerException] with root cause
java.lang.NullPointerException: null
Annnnnd, that's it, nothing more...
The code of the controller is rather straithforward, it looks like this :
#RepositoryRestController
#ResponseBody
public class AnimalImportEndpoint {
#Inject
private animalImportService;
#RequestMapping(value = "/animals/import", method = RequestMethod.POST)
public AnimalImportResult import(#Valid #RequestBody Animal animal) {
return animalImportService.import(animal);
}
#ResponseStatus(value = HttpStatus.BAD_REQUEST, reason = "Illegal arguments")
#ExceptionHandler(IllegalArgumentException.class)
public void illegalArguments() {
}
}
The class is annoted with #RepositoryRestController instead of #RestController because Spring Data Rest also exposes /animals.
Any pointers or advice on how to troubleshoot this ?
Edit : other interesting fact, I use sleuth to trace requests. When I get this NullPointerException, I can see that there is no spanId/traceId in my logs ...
Add this JVM argument to disable stacktrace removal optimization
-XX:-OmitStackTraceInFastThrow

Upgrading to Tomcat 8 breaks MultipartFile upload

I'm using Spring Boot. The method I'm calling in my controller looks like this:
#RequestMapping(value = "/{customerId}/files/{id}/addFile", method = RequestMethod.POST,
produces = "application/json; charset=UTF-8")
#ResponseBody
public Response uploadFile(#PathVariable String customerId, #PathVariable String id,
#RequestParam("uploadedFile") MultipartFile file) throws IOException {
After upgrading to Tomcat 8 I'm getting the following error when calling this method. I set a breakpoint on the first line which is never reached.:
org.springframework.web.util.NestedServletException: Request
processing failed; nested exception is
org.springframework.web.multipart.MultipartException: Could not parse
multipart servlet request; nested exception is java.io.IOException:
org.apache.tomcat.util.http.fileupload.FileUploadException: Stream
closed
Has anyone come across this issue?
Try to add multipart.maxFileSize and multipart.maxRequestSize to your application.properties file. SpringBoot seems to has a default value of 128KB, which broke my upload.

Exception when i send my form Spring MVC

I want to insert a record to database so this is my controller :
#RequestMapping(value="/ajouter_activite",method = RequestMethod.POST)
public String AddActivity(#ModelAttribute Movement movement, ModelMap model,BindingResult result){
AddActivityValidator actvalidator = new AddActivityValidator();
actvalidator.validate(movement, result);
if(!result.hasErrors()){
boolean n;
n=actservice.addMovement(movement);
if(n==true){model.addAttribute("success","true");}
else {model.addAttribute("echec","true");}
return "/FicheService";}
else{return "/FicheService";
}
}
When i send my form i get this exception :
Etat HTTP 500 - Request processing failed; nested exception is org.springframework.web.bind.annotation.support.HandlerMethodInvocationException: Failed to invoke handler method [public java.lang.String gestion.delegation.controller.FicheServiceController.AddActivity(gestion.delegation.domaine.Movement,org.springframework.ui.ModelMap,org.springframework.validation.BindingResult)]; nested exception is java.lang.IllegalStateException: Errors/BindingResult argument declared without preceding model attribute. Check your handler method signature!
Where is the wrong with that ?
Try with
public String AddActivity(#ModelAttribute Movement movement, BindingResult result, ModelMap model)
method signature.
see example 17.1 in http://static.springsource.org/spring/docs/3.2.x/spring-framework-reference/html/mvc.html#mvc-ann-methods for more info.

Boolean return type not working with RestTemplate

I am using Spring 3.0.3 RestTemplate for making RESTfull call to service which is deployed in servicemix ESB. Service method returns boolean value, and am unable to receive this in RestTemplate response.
String query = "?userId="+userId;
RestTemplate rest = new RestTemplate();
Map<String, String> params = new HashMap<String, String>();
boolean status = rest.getForObject(SERVICE_URL+query,boolean.class,params);
And am getting below error
WARN : org.springframework.web.client.RestTemplate - GET request for "http://localhost:818 1/cxf/monitoring/logclear?userId=admin" resulted in 406 (Not Acceptable); invoking error handler org.springframework.web.client.HttpClientErrorException: 406 Not Acceptable at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultR esponseErrorHandler.java:69) at org.springframework.web.client.RestTemplate.handleResponseError(RestTemplate.java:486)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:443)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:409)
at org.springframework.web.client.RestTemplate.getForObject(RestTemplate.java:206)
Any help is greatly appreciated. Thank you!

Resources