Getting 400 Bad Request for Spring RestTemplate POST

25,756

Just solved the issue by adding following code in dispatcher servlet configuration file of REST Client:

<bean id="jacksonMessageConverter"
    class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"></bean>
<bean
    class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
    <property name="messageConverters">
        <list>
            <ref bean="jacksonMessageConverter" />
        </list>
    </property>
</bean>

Full code of dispatcher servlet is: web-servlet.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd 
http://www.springframework.org/schema/context 
http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">
<context:component-scan base-package="webcontroller" />
<mvc:annotation-driven />
<bean class = "org.springframework.web.servlet.view.InternalResourceViewResolver">
  <property name = "prefix" value = "/WEB-INF/jsp/" />
  <property name = "suffix" value = ".jsp" />
</bean>

<bean id="jacksonMessageConverter"
    class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"></bean>
<bean
    class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
    <property name="messageConverters">
        <list>
            <ref bean="jacksonMessageConverter" />
        </list>
    </property>
</bean>

</beans>

Also removed some code from REST calling function, below are the changes: REST CLIENT

try {
        RestTemplate restTemplate = new RestTemplate();
        String url = "http://localhost:8181/xyz/updateAdmin";
        JSONArray json = new JSONArray();
        JSONObject obj = new JSONObject();
        obj.put("a_username", "testabcd");
        obj.put("a_id", 1);
        //obj.put("a_password", "N/A");
        json.put(obj);
        HttpHeaders headers = new HttpHeaders();
        headers.add("Accept", MediaType.APPLICATION_JSON.toString());
        headers.add("Content-Type", MediaType.APPLICATION_JSON.toString());
        HttpEntity<String> entity = new HttpEntity<String>(obj.toString(), headers);
        restTemplate.exchange(url, HttpMethod.POST, entity, String.class);


    } catch(Exception ex) {
        ex.printStackTrace();
    }
Share:
25,756
Jignesh M. Khatri
Author by

Jignesh M. Khatri

Updated on August 05, 2020

Comments

  • Jignesh M. Khatri
    Jignesh M. Khatri over 3 years

    I want to consume Spring Rest web-service, using POST method. I don't have access to POJO file at client end (website), so have to use JSON at client end and POJO at web-service. Below is my code:

    REST Controller

    @RequestMapping(value="/updateAdmin", method=RequestMethod.POST, consumes="application/json", headers="Accept=application/json")
    public ResponseEntity<String> updateAdmin(@RequestBody Ss_admin admin) {
        try {
            ss_admin_dao.updateAdmin(admin);
        } catch(Exception ex) {
            ex.printStackTrace();
        }
        return new ResponseEntity<String>(HttpStatus.CREATED);
    }
    

    POJO

    package model;
    
    import java.io.Serializable;
    
    import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
    import com.fasterxml.jackson.annotation.JsonProperty;
    
    @JsonIgnoreProperties(ignoreUnknown = true)
    public class Ss_admin implements Serializable {
    @JsonProperty("a_id")
    private long a_id;
    @JsonProperty("a_username")
    private String a_username;
    @JsonProperty("a_password")
    private String a_password;
    
    public Ss_admin() {}
    public long getA_id() {
        return a_id;
    }
    public void setA_id(long a_id) {
        this.a_id = a_id;
    }
    public String getA_username() {
        return a_username;
    }
    public void setA_username(String a_username) {
        this.a_username = a_username;
    }
    public String getA_password() {
        return a_password;
    }
    public void setA_password(String a_password) {
        this.a_password = a_password;
    }
    }
    

    REST Client

    try {
            RestTemplate restTemplate = new RestTemplate();
            List<HttpMessageConverter<?>> list = new ArrayList<HttpMessageConverter<?>>();
            list.add(new MappingJackson2HttpMessageConverter());
            restTemplate.setMessageConverters(list);
            //restTemplate.setRequestFactory(new HttpComponentsClientHttpRequestFactory(HttpClientBuilder.create().build()));
            String url = "http://localhost:8181/xyz/updateAdmin";
            JSONArray json = new JSONArray();
            JSONObject obj = new JSONObject();
            obj.put("a_username", "testabcd");
            obj.put("a_id", 1);
            obj.put("a_password", "N/A");
            json.put(obj);
            HttpHeaders headers = new HttpHeaders();
            //headers.setContentType(MediaType.APPLICATION_JSON);
            //headers.setAccept(MediaType.APPLICATION_JSON);
            headers.add("Accept", MediaType.APPLICATION_JSON.toString());
            headers.add("Content-Type", MediaType.APPLICATION_JSON.toString());
            //headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
            HttpEntity<String> entity = new HttpEntity<String>(obj.toString(), headers);
            restTemplate.exchange(url, HttpMethod.POST, entity, String.class);
    
            //restTemplate.postForEntity(url, entity, String.class);
        } catch(Exception ex) {
            ex.printStackTrace();
        }
    

    As you can see in the commented, I have tried many options with no success.

    Stack Trace

    Aug 04, 2017 6:58:12 PM org.springframework.web.client.RestTemplate handleResponseError
    WARNING: POST request for "http://localhost:8181/xyz/updateAdmin" resulted in 400 (Bad Request); invoking error handler
    org.springframework.web.client.HttpClientErrorException: 400 Bad Request
    at  org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:91)
    at org.springframework.web.client.RestTemplate.handleResponseError(RestTemplate.java:576)
    at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:532)
    at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:489)
    at org.springframework.web.client.RestTemplate.exchange(RestTemplate.java:431)
    at webcontroller.TestController.update(TestController.java:77)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:214)
    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:748)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:689)
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:83)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:945)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:876)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:931)
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:822)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:687)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:807)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:292)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:212)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:141)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
    at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:616)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:528)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1099)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:670)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1520)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1476)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:745)
    

    EDIT I had tested REST web-service http://localhost:8181/xyz/updateAdmin using Postman, and it is successfully executing, but not working with RestTemplate.

    ISSUE SOLVED See my answer below.