Search code examples
springspring-mvcresttemplate

400 Bad Request using RestTemplete and postForObject


i'm building two applications using Spring 3.The first one is meant to be rest API and the second is a client.The client must create a reservation. I'm getting 400 Bad Request error,please help.

The class Reservation in the client app:

package ma.ensias.agencecentrale.entities;

import java.io.Serializable;
import java.util.Collection;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.Table;

import org.codehaus.jackson.annotate.JsonIgnore;
import org.codehaus.jackson.annotate.JsonIgnoreProperties;
import org.codehaus.jackson.annotate.JsonProperty;
@JsonIgnoreProperties(ignoreUnknown=true)
@Entity
@Table(name="reservations")
public class Reservation implements Serializable{

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private Long idReservation;
    private String date;
    @ManyToOne
    @JoinColumn(name="id_utilisateur")
    private Utilisateur utilisateur;
    @JsonIgnore
    @ManyToMany(cascade=CascadeType.ALL)  
    @JoinTable(name="passager_reservation", joinColumns=@JoinColumn(name="id_reservation"), inverseJoinColumns=@JoinColumn(name="id_passager")) 
    private Collection<Passager> passagers;
    @JsonIgnore
    @ManyToMany(cascade=CascadeType.ALL)  
    @JoinTable(name="vol_reservation", joinColumns=@JoinColumn(name="id_reservation"), inverseJoinColumns=@JoinColumn(name="id_vol"))
    private Collection<Vol> vols;
    // Contructor without fields 
    public Reservation() {
        super();
    }
    // contructor with date attribute 
    public Reservation(String date) {
        super();
        this.date = date;
    }

    // ----------------------- Getters and setters-------------------------------
    public String getDate() {
        return date;
    }
    public void setDate(String date) {
        this.date = date;
    }
    @JsonProperty(value="client")
    public Utilisateur getUtilisateur() {
        return utilisateur;
    }

    public void setUtilisateur(Utilisateur utilisateur) {
        this.utilisateur = utilisateur;
    }
    public Collection<Vol> getVols() {
        return vols;
    }
    public void setVols(Collection<Vol> vols) {
        this.vols = vols;
    }
    public Long getIdReservation() {
        return idReservation;
    }

}

the rest Client :

//-------------------Create a Reservation--------------------------------------------------------

@RequestMapping("/ajouterReservation")
     private static void ajouterReservation(Reservation reservation) {

            RestTemplate restTemplate = new RestTemplate();
            Reservation addedRes = restTemplate.postForObject(REST_SERVICE_URI,reservation, Reservation.class);


        }

And the class Reservation in provider app:

package ma.ensias.agencevoyage.entities;

import java.io.Serializable;
import java.util.Collection;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.Table;

import org.codehaus.jackson.annotate.JsonIgnore;
import org.codehaus.jackson.annotate.JsonIgnoreProperties;
import org.codehaus.jackson.annotate.JsonProperty;
@JsonIgnoreProperties(ignoreUnknown=true)
@Entity
@Table(name="reservations")
public class Reservation implements Serializable{
    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private Long idReservation;
    private String date;
    @ManyToOne(cascade=CascadeType.ALL)
    @JoinColumn(name="id_client")
    private Client client;
    @JsonIgnore
    @ManyToMany(cascade=CascadeType.ALL)  
    @JoinTable(name="passager_reservation", joinColumns=@JoinColumn(name="id_reservation"), inverseJoinColumns=@JoinColumn(name="id_passager")) 
    private Collection<Passager> passagers;
    @JsonIgnore
    @ManyToMany(cascade=CascadeType.ALL)  
    @JoinTable(name="vol_reservation", joinColumns=@JoinColumn(name="id_reservation"), inverseJoinColumns=@JoinColumn(name="id_vol"))
    private Collection<Vol> vols;
    // Contructor without fields 
    public Reservation() {
        super();
    }
    // contructor with date attribute 
    public Reservation(String date) {
        super();
        this.date = date;
    }

    // ----------------------- Getters and setters-------------------------------
    public String getDate() {
        return date;
    }
    public void setDate(String date) {
        this.date = date;
    }
    public Client getClient() {
        return client;
    }
    public void setClient(Client client) {
        this.client = client;
    }
    public Collection<Passager> getPassagers() {
        return passagers;
    }
    public void setPassagers(Collection<Passager> passagers) {
        this.passagers = passagers;
    }
    public Collection<Vol> getVols() {
        return vols;
    }
    public void setVols(Collection<Vol> vols) {
        this.vols = vols;
    }


}

and the controller is : //-------------------Create a Reservation--------------------------------------------------------

  @RequestMapping(value = "/ajouterReservation", method = RequestMethod.POST, consumes="application/json")
    public ResponseEntity<String> ajouterReservation(@RequestBody Reservation reservation) {
        metier.ajouterReservation(reservation);
        return new ResponseEntity(HttpStatus.CREATED);
    }

I also tested the provider using post man and it is working.

The error i'm getting is below :

GRAVE: Servlet.service() for servlet [appServlet] in context with path [/agencecentrale] threw exception [Request processing failed; nested exception is org.springframework.web.client.HttpClientErrorException: 415 Type de Support Non Supporté] with root cause
org.springframework.web.client.HttpClientErrorException: 415 Type de Support Non Supporté
    at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:88)
    at org.springframework.web.client.RestTemplate.handleResponseError(RestTemplate.java:532)
    at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:488)
    at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:446)
    at org.springframework.web.client.RestTemplate.postForObject(RestTemplate.java:294)
    at ma.ensias.agencecentrale.controllers.ReservationController.ajouterReservation(ReservationController.java:33)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:219)
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132)
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:745)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:686)
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:925)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:856)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:936)
    at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:838)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:650)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:812)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:731)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:218)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:505)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:169)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:958)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:452)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1087)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:637)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:316)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Unknown Source)

Solution

  • Root cause : Problem is with content type set in the provider controller:

    @RequestMapping(value = "/ajouterReservation", method = RequestMethod.POST, consumes="application/json")
        public ResponseEntity<String> ajouterReservation(@RequestBody Reservation reservation)
    

    Solution 1: remove consumes="application/json" in the handler method

    Solution 2 : Set the headers accordingly before making the rest call and make use of exchange method of RestTemplate like below :

         RestTemplate restTemplate = new RestTemplate();
         HttpHeaders headers=new HttpHeaders();
            headers.set("Content-Type", "application/json");
        HttpEntity requestEntity=new HttpEntity(reservation, headers);
    
           Reservation addedRes = restTemplate.exchange(REST_SERVICE_URI, HttpMethod.POST,requestEntity,Reservation.class);