Unable to send POST request in SpringMVC - java

I have created an API using jersey and spring boot. Now when I hit POST request using Postman with following in request body:
{
"name":"something", "email":"something","location":"something","dateOfBirth":"something"
}
It works. Function to save this data is:
#POST
#Path("/addEmployee")
#Produces(MediaType.TEXT_PLAIN)
public String addEmployee(#RequestBody Employee employee) {
service.save(employee);
return "Saved Successfully";
}
Employee model is:
#Entity
#Table(name = "employee")
#XmlRootElement(name = "employee")
#EntityListeners(AuditingEntityListener.class)
public class Employee {
public Employee() {
}
#Id
#Column(nullable = false, name = "id")
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Column(nullable = false, name = "name")
private String name;
#Column(nullable = false, name = "email")
private String email;
#Column(nullable = false, name = "location")
private String location;
#Column(nullable = false, name = "DOB")
private String dateOfBirth;
// getters and setters
This api is called by follwing function at client side:
#RequestMapping(value = "/addEmployee", method = RequestMethod.GET)
public ModelAndView addEmployee(ModelAndView model) {
RestTemplate restTemplate = new RestTemplate();
String url = "http://localhost:8080/api/addEmployee";
EmployeeInfo employee = new EmployeeInfo();
employee.setName("Ashish");
employee.setEmail("anyhing");
employee.setDateOfBirth("mybirthday");
employee.setLocation("home");
ResponseEntity<String> response = restTemplate.postForEntity(url, employee, String.class);
model.setViewName("homePage");
return model;
}
Employee info class is:
public class EmployeeInfo {
private String name;
private String email;
private String location;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
Error I'm getting is :
2018-09-16 15:57:13.706 ERROR 14892 --- [nio-8080-exec-1] 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.HttpClientErrorException: 404 null] with root cause
org.springframework.web.client.HttpClientErrorException: 404 null
at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:86) ~[spring-web-4.3.19.RELEASE.jar:4.3.19.RELEASE]
at org.springframework.web.client.RestTemplate.handleResponse(RestTemplate.java:708) ~[spring-web-4.3.19.RELEASE.jar:4.3.19.RELEASE]
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:661) ~[spring-web-4.3.19.RELEASE.jar:4.3.19.RELEASE]
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:621) ~[spring-web-4.3.19.RELEASE.jar:4.3.19.RELEASE]
at org.springframework.web.client.RestTemplate.postForEntity(RestTemplate.java:415) ~[spring-web-4.3.19.RELEASE.jar:4.3.19.RELEASE]
at com.example.controller.Home.addEmployee(Home.java:82) ~[classes/:na]
and a long list like this.
Form which calls this is:
<form name="myform" method="post" action="addEmployee" >
<input type="submit" value="Save">
</form>
EDIT: On changing client side's method = RequestMethod.GET to RequestMethod.POST, nothing happens, still getting same erro
What I'm doing wrong?

After reviewing your code problem is at client side app where your back end is running on 8090 port while in api you calling is having 8080 for addEmployee.
Change this String url = "http://localhost:8080/api/addEmployee"; to String url = "http://localhost:8090/api/addEmployee"; and you should be good.
#RequestMapping(value = "/addEmployee", method = RequestMethod.GET)
public String addEmployee(ModelAndView model) {
RestTemplate restTemplate = new RestTemplate();
String url = "http://localhost:8090/api/addEmployee";
EmployeeInfo employee = new EmployeeInfo();
employee.setName("Ashish");
employee.setEmail("anyhing");
employee.setDateOfBirth("mybirthday");
employee.setLocation("home");
System.out.println("WE HAVE REACHED HERE");
String response = restTemplate.postForObject(url, employee, String.class);
System.out.println(response);
return "redirect:/home";
}

The 404 means that the requested source does not exist maby because one of these reasons:
There is no controller method to handle the POST request so try to change the which#RequestMapping(value = "/addEmployee", method = RequestMethod.GET) to #RequestMapping(value = "/addEmployee", method = RequestMethod.POST)
try to move this method and make it a service in a restful controller using this annotation #RestController
I see that you are accessing this /api/addEmployee which I think not configured right?

We should be using RequestMethod.POST instead of RequestMethod.GET
#RequestMapping(value = "/addEmployee", method = RequestMethod.POST)
public ModelAndView addEmployee(ModelAndView model) {
RestTemplate restTemplate = new RestTemplate();
String url = "http://localhost:8080/api/addEmployee";
EmployeeInfo employee = new EmployeeInfo();
employee.setName("Ashish");
employee.setEmail("anyhing");
employee.setDateOfBirth("mybirthday");
employee.setLocation("home");
ResponseEntity<String> response = restTemplate.postForEntity(url, employee, String.class);
model.setViewName("homePage");
return model;
}

Related

Java - Initialize member with values from other members

I have a REST Webservice, I get my data from a JSON request:
#POST
#Path("load")
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_JSON)
#RequestMapping(value="load", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON, consumes = MediaType.APPLICATION_JSON)
public #ResponseBody
Respuesta loadData(#RequestBody Persons person) {
//code
em.persist(person);
}
This is my Person class:
#Entity
#Table(name = "myparenttable", schema = "myschema", catalog = "mydb")
public class Parent {
private Integer id_parent;
private String name;
private String last_name;
private String username;
//getters and setters
public Parent(){}
}
I want to generate the username member with parts of the name and last_name members; for simplicity, lets say I need the username be = name + last_name; the username member is not specified in the json request, is there a way to load a member with values of other members in the object initialization? in this case, automatic initialization with #RequestMapping and #RequestBody

passing another object into current rest service does not throw an exception

this my is rest request that is compatible for another service :
{
"fromDate": 1562773101000,
"toDate": 1563118701000,
"turnOverType": 4,
"fromAmount": 1,
"toAmount": 10000000,
"voucherDescription": null,
"articleDescription": null,
"referenceNumbers": [],
"offset": 3,
"pageSize": 20,
"iban": "BLAHBLAHBLAHBLAH"
}
and this is corresponding model that not match request :
#XmlAccessorType(XmlAccessType.FIELD)
#XmlRootElement(name = "TransferRequestInquiryFilter")
public class TransferRequestInquiryFilter implements Serializable {
#XmlElement(name = "sourceIbans")
private List<String> sourceIbans;
#XmlElement(name = "transferType")
private TransferType transferType;
#XmlElement(name = "fromTransferDate")
private Timestamp fromTransferDate;
#XmlElement(name = "toTransferDate")
private Timestamp toTransferDate;
#XmlElement(name = "fromRegistrationDate")
private Timestamp fromRegistrationDate;
#XmlElement(name = "toRegistrationDate")
private Timestamp toRegistrationDate;
#XmlElement(name = "trackingNumbers")
private List<String> trackingNumbers;
#XmlElement(name = "referenceNumbers")
private List<String> referenceNumbers;
#XmlElement(name = "transactionIds")
private List<String> transactionIds;
#XmlElement(name = "status")
private TransactionStatus status;
#XmlElement(name = "fromAmount")
private Long fromAmount;
#XmlElement(name = "toAmount")
private Long toAmount;
#XmlElement(name = "destinationIbans")
private List<String> destinationIbans;
and this is my controller ..
#RequestMapping(value = "/inquiry", method = RequestMethod.POST)
public #ResponseBody
ResponseEntity<List<ExtendedTransferRequest>> transferInquiry(#RequestBody #Valid TransferRequestInquiryFilter transferRequestInquiryFilter
, BindingResult bindingResult) {
// when validation not works return bad request
List<ErrorObject> errorObjects = requestInquiryValidator.validate(transferRequestInquiryFilter);
if (errorObjects.size() > 0) {
// just throw bad request and not detail of them
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
}
List<ExtendedTransferRequest> extendedTransferRequestList = new ArrayList<>();
ExtendedTransferRequest extendedTransferRequest = new ExtendedTransferRequest();
List<SettlementTransaction> settlementTransactionList = settlementSearch.findSettlement(transferRequestInquiryFilter);
extendedTransferRequestList = TransferInquiryResponseMapper.INSTANCE.SettlementTransactionInquiryResponse(setlementTransactionList);
return new ResponseEntity<>(extendedTransferRequestList, HttpStatus.OK);
}
just fromAmount and toAmount fills. but i want to get an exception for this situation and throw a bad request for client. how can i do that? If I get name conflict or type conflict between rest request and model , I need to handle it and riase a bad request for client. i am using spring mvc 5 and jackson-core and jackson-databind 2.9.4
Using validation-api, annotate proper validation for fields and #validated before controller method and using #valid before RequestBody object would throw proper validation exception.

No suitable HttpMessageConverter found for response type and content type [application/json;charset=UTF-8] exception occurs

Im trying to hit Spring REST endpoint in my other module of the application. So im trying to use the REST Template to get a list of users as below :
The API request using REST Template :
public List<LeadUser> getUsersBySignUpType(String type, String id) {
String adminApiUrl = adminApiBaseUrl+"/crm/v1/users/?type="+type+"&id="+id;
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.setContentType(org.springframework.http.MediaType.APPLICATION_JSON);
HttpEntity entity = new HttpEntity(headers);
ResponseEntity<LeadUserList> response = restTemplate.exchange(
adminApiUrl, HttpMethod.GET, entity, LeadUserList.class);
return response.getBody().getUsersList();
}
LeadUserList class :
public class LeadUserList {
private List<LeadUser> usersList;
public List<LeadUser> getUsersList() {
return usersList;
}
}
LeadUser model class :
public class LeadUser {
#JsonProperty("id")
private String id;
#JsonProperty("email")
private String email;
#JsonProperty("name")
private String name;
#JsonProperty("businessName")
private String businessName;
#JsonProperty("phone")
private String phone;
#JsonProperty("address")
private String address;
#JsonProperty("createdTime")
#DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME)
private Date createdTime;
#JsonProperty("updatedTime")
#DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME)
private Date updatedTime;
#JsonProperty("bookletSignups")
private BookletSignUp bookletSignUp;
#JsonProperty("eventSignups")
private EventSignUp eventSignUp;
#JsonProperty("infoSignups")
private InfoSignUp infoSignUp;
#JsonProperty("webinarSignups")
private WebinarSignUp webinarSignUp;
public LeadUser() {
}
}
The API endpoint controller class :
#Controller
#Component
#RequestMapping(path = "/crm/v1")
public class UserController {
#Autowired
UserService userService;
#RequestMapping(value = "/users", method = GET,produces = "application/json")
#ResponseBody
public ResponseEntity<List<User>> getPartnersByDate(#RequestParam("type") String type,
#RequestParam("id") String id) throws ParseException {
List<User> usersList = userService.getUsersByType(type);
return new ResponseEntity<List<User>>(usersList, HttpStatus.OK);
}
}
Although the return type is JSON from the API endpoint im getting the above exception. What have I done wrong here?
The exception :
Could not extract response: no suitable HttpMessageConverter found for response type [class admin.client.domain.LeadUserList] and content type [application/json]
Try additional settings as follows,
httpHeaders.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
httpHeaders.setContentType(MediaType.APPLICATION_JSON);
Also fix your exchange call,
ResponseEntity<List<LeadUser>> response = restTemplate.exchange(
adminApiUrl, HttpMethod.GET, entity, new ParameterizedTypeReference<List<LeadUser>>(){});

Spring mvc validate a primitive with #RequestBody doesn't work

I'm trying to validate an email that I receive from the post request body but it's doesn't work !
#RequestMapping(value = "myservice/emails", method = RequestMethod.POST)
public String requestFoo(#RequestBody #Email String email) {
return email;
}
When I send a request with a string that doesn't respect the email regex the function is executed and I receive a 200 status code.
Even do I add the #Valid annotation the result is always the same.
#RequestMapping(value = "myservice/emails", method = RequestMethod.POST)
public String testValidation(#Valid #RequestBody #Email String email) {
return email;
}
Start with Spring 3.2 #RequestBody method argument may be followed by Errors object, hence allowing handling of validation errors in the same #RequestMapping :
#RequestMapping(value = "myservice/emails", method = RequestMethod.POST)
public ResponseEntity<String> testValidation(#Valid #RequestBody #Email String email, Errors errors) {
if (errors.hasErrors()) {
return ResponseEntity.badRequest().body(ValidationErrorBuilder.fromBindingErrors(errors));
}
return email;
}
And create a custom validator :
public class ValidationErrorBuilder {
public static ValidationError fromBindingErrors(Errors errors) {
ValidationError error = new ValidationError("Validation failed. " + errors.getErrorCount() + " error(s)");
for (ObjectError objectError : errors.getAllErrors()) {
error.addValidationError(objectError.getDefaultMessage());
}
return error;
}
}

Error org.springframework.web.HttpMediaTypeNotSupportedException

i have a problem with rest and method post on my controler i have this 2 class the first is user in my class user i have my class with the getters and setter and a default contructor because for the finally I would like use Hibernate .:
#Entity
#Table(name="Utilisateur") // mapping with hibernate (but not using in this situation)
public class User {
#Id
private long id;
#Column(name="nom")
private String nom;
#Column(name="prenom")
private String prenom;
#Column(name="admin")
private boolean admin;
#Column(name="actif")
private boolean actif;
#Column(name="logins")
private String logins;
#Column(name="email")
private String email;
#Column(name="naissance")
private String naissance;
#Column(name="pwd")
private String pwd;
#Column(name="compte")
private String compte;
public User(){
}
/*
with getter and setter.
*/
}
and my class controler (User controller) : is using for make the api principally post api .
#RestController
public class UserController {
#RequestMapping(
value="/api/greetings/post",
method = RequestMethod.POST,
consumes = MediaType.APPLICATION_JSON_VALUE,
produces=MediaType.APPLICATION_JSON_VALUE
)
#ResponseBody
public ResponseEntity<User> getByEmail(#RequestBody User user){
if(user==null){
return new ResponseEntity<User>(HttpStatus.INTERNAL_SERVER_ERROR);
}
return new ResponseEntity<User>(user, HttpStatus.OK);
}
and i get this erreur I am using postman for make the query and in parameter of my query I send this Json query :
{"id":"3","nom":"Gille","prenom":"Laurent","admin":"1","actif":"0","logins":"gilaur","email":""toto#hotmail.com,"naissance":"1990/09/09","pwd":"gal","compte":"autre"}
And i get this error :
{"timestamp":1457906727481,"status":415,"error":"Unsupported Media Type","exception":"org.springframework.web.HttpMediaTypeNotSupportedException","message":"Content type 'text/plain;charset=UTF-8' not supported","path":"/api/greetings/post/"}
Thank you
you are change headers content-type application/json in Postman because you try set text/plain

Categories