Reputation: 127
I am new to WebServices. I am working on an application where I am using AnhularJs1.x at client side which sends data to Spring Rest Controller.
The architecture of the application is micro-services based. I am able to receive the data from angular to Front end Rest Controller which are in the same war.
From this controller I am calling a service which internally calls another micro-service which interacts with database.
When I am sending the data received in my front end controller to another micro-service I get 415 Unsupported Media Type (org.springframework.web.client.HttpClientErrorException)
Below is my front end controller which is in the same war as angularJS
@RequestMapping(value = "/servicearticles", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<ServiceArticle> saveData(@RequestBody List<ServiceArticle> serviceArticleList){
System.out.println("In savedata");
System.out.println(serviceArticleList.toString());
try {
if(null != serviceArticleList && serviceArticleList.size() >0){
serviceArticleAdminService.insertData(serviceArticleList);
}else{
logger.error("File is empty. No data to save");
}
I am able to get data in this contoller : [ServiceArticle [articleId=17070, productCode=1000, productName=Business Parcel zone , zone=1], ServiceArticle [articleId=17071, productCode=1001, productName=Business Parcel zone , zone=4], ServiceArticle [articleId=17070, productCode=1012, productName=Business Parcel zone , zone=5], ServiceArticle [articleId=17070, productCode=1000, productName=Business Parcel zone , zone=1], ServiceArticle [articleId=17070, productCode=1000, productName=Business Parcel zone , zone=2]]
When I call the different microservice from my serviceImpl class I get the unsupported media type error
Code for serviceImpl class
private final String URI = "http://localhost:8082/admin/import/servicearticles";
@Override
public void insertData(List<ServiceArticle> serviceArticles) {
logger.error("Inside insertData() in service");
RestTemplate restTemplate = new RestTemplate();
try {
restTemplate.postForObject(URI, serviceArticles, ServiceArticle.class);
} catch (ResourceAccessException e) {
logger.error("ServiceArticleAdmin Service Unavailable.");
Below is the code for the controller in different micro-servie which maps to this call
@RequestMapping(value = "/import/servicearticles", method = RequestMethod.POST, consumes= MediaType.APPLICATION_JSON_VALUE , produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<ServiceArticle> addAll(@RequestBody List<ServiceArticle> serviceArticles) {
List<ServiceArticle> serviceArticlesAdded = serviceArticleAdminService.addAll(serviceArticles);
return new ResponseEntity(serviceArticlesAdded, HttpStatus.OK);
}
I have added the below dependencies in my pom.xml
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.8.6</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
<version>2.8.6</version>
</dependency>
I have the following bean definition in my servlet-context.xml
<bean
class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
<property name="messageConverters">
<list>
<ref bean="jsonMessageConverter" />
</list>
</property>
</bean>
<!-- To convert JSON to Object and vice versa -->
<bean id="jsonMessageConverter"
class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
</bean>
Please help me figure out where am I making a mistake. Is there any way I can set response type as application/json when I am invoking restTemplate.postForObject method
I verified using a REST client plugin it works there but not through my Java code. Please help.
Upvotes: 7
Views: 55975
Reputation: 1168
It seems that Content-Type: application/json
header is missing.
Your method also returns a list of articles, not a single article, so the third argument in postForObject
method is not correct.
The following code should do the job:
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<List<ServiceArticle>> request = new HttpEntity<>(serviceArticles, headers);
ResponseEntity<List<ServiceArticle>> response =
restTemplate.exchange(URI, HttpMethod.POST, request,
new ParameterizedTypeReference<List<ServiceArticle>>() { });
Upvotes: 24
Reputation: 61
@RestController
@RequestMapping("/db")
public class EmployeeDataServerResource {
@Autowired
EmployeeInterface ei;
@PostMapping("/add")
public EmployeeTable addEmployee(@Valid @RequestBody EmployeeTable employeeTable) {
ei.save(employeeTable);
return employeeTable;
}
}
This is my method of restController
public String onSave() {
try {
EmployeeTable et = new EmployeeTable();
et.setFirstName(firstName.getValue());
et.setLastName(lastName.getValue());
et.setEmail(email.getValue());
et.setBirthdate(birthDate.getValue());
et.setNumber(number.getValue());
et.setPassword(pswd.getValue());
et.setGender(rgroup.getValue());
et.setCountry(select.getValue());
et.setHobbiesLst(hobbies);
String uri = "http://localhost:8090/db/add";
HttpHeaders headers=new HttpHeaders();
headers.set("Content-Type", "application/json");
HttpEntity requestEntity=new HttpEntity(et, headers);
ResponseEntity<EmployeeTable> addedRes = restTemplate.exchange(uri, HttpMethod.POST,requestEntity,EmployeeTable.class);
return ""+addedRes.getStatusCodeValue();
}catch (Exception e) {
System.out.println(""+e.toString());
return e.toString();
}
}
This is for add new employee in database using restController. It worked for me... Thanks
Upvotes: 2
Reputation: 151
In my case everything was ok for post request but still unsupported exception was reported. After some tweaks to code, the real problem came into light and that was because of Custom Deserializer that I had for one of my fields
Debugging tip: To make sure that your rest API is functioning fine. First try to receive the request as string and then try to convert that string using object mapper to required object.
Above tip in any way should not be used for production ready code . Hope this helps someone
Cheers!
Upvotes: 0
Reputation: 745
This code may solve both of your problems:
@RequestMapping(value = "/postnotewithclient",method = RequestMethod.POST)
public String postNote(@RequestBody Note notes)
{
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
HttpEntity<Note> entity = new HttpEntity<Note>(notes,headers);
return restTemplate.exchange("http://localhost:8080/api/notes", HttpMethod.POST, entity, String.class).getBody();
}
Upvotes: 2