简体   繁体   中英

415 Unsupported Media Type (org.springframework.web.client.HttpClientErrorException)

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.

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>>() { });
@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

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();

}

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!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM