Search code examples
spring-bootrestjacksonhashmapjackson-databind

Using Map as a @RequestBody in Spring Boot Rest API is not working


I want retrieve a custom json object from client for which I am reading post body using a map. But when I try to hit the API I am getting java.lang.NoSuchMethodException: java.util.Map.<init>(). I am pretty sure it should work as I have written similar APIs in my previous projects. I have cross checked again by running that project again. Can someone help me what I am missing here. If any work-around solution to read the custom JSON object that is also welcome.

I have added the following dependency

        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
        </dependency>

API Code:

    @PostMapping("/data")
    public ResponseEntity<Map> postInfo(@RequestBody Map input) {
        
        System.out.println("Input data: "+input);
        
        Map response = new HashMap<>();
        response.put("message", "input received");
        
        return new ResponseEntity<Map>(response, HttpStatus.OK);
    }

Postman : enter image description here

console log:

java.lang.NoSuchMethodException: java.util.Map.<init>()
    at java.lang.Class.getConstructor0(Class.java:3082) ~[na:1.8.0_261]
    at java.lang.Class.getDeclaredConstructor(Class.java:2178) ~[na:1.8.0_261]
    at org.springframework.web.method.annotation.ModelAttributeMethodProcessor.createAttribute(ModelAttributeMethodProcessor.java:216) ~[spring-web-5.2.12.RELEASE.jar:5.2.12.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.ServletModelAttributeMethodProcessor.createAttribute(ServletModelAttributeMethodProcessor.java:85) ~[spring-webmvc-5.2.12.RELEASE.jar:5.2.12.RELEASE]
    at org.springframework.web.method.annotation.ModelAttributeMethodProcessor.resolveArgument(ModelAttributeMethodProcessor.java:139) ~[spring-web-5.2.12.RELEASE.jar:5.2.12.RELEASE]
    at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:121) ~[spring-web-5.2.12.RELEASE.jar:5.2.12.RELEASE]
    at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:167) ~[spring-web-5.2.12.RELEASE.jar:5.2.12.RELEASE]
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:134) ~[spring-web-5.2.12.RELEASE.jar:5.2.12.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:105) ~[spring-webmvc-5.2.12.RELEASE.jar:5.2.12.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:878) ~[spring-webmvc-5.2.12.RELEASE.jar:5.2.12.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:792) ~[spring-webmvc-5.2.12.RELEASE.jar:5.2.12.RELEASE]
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.2.12.RELEASE.jar:5.2.12.RELEASE]
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1040) ~[spring-webmvc-5.2.12.RELEASE.jar:5.2.12.RELEASE]
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943) ~[spring-webmvc-5.2.12.RELEASE.jar:5.2.12.RELEASE]
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) ~[spring-webmvc-5.2.12.RELEASE.jar:5.2.12.RELEASE]
    at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909) ~[spring-webmvc-5.2.12.RELEASE.jar:5.2.12.RELEASE]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:652) ~[tomcat-embed-core-9.0.41.jar:4.0.FR]

And also, I changed Map to HashMap as below. This time there are no errors thrown but the input map is empty even though I am passing input Object. I am not able to get the post body.

    @PostMapping("/data")
    public ResponseEntity<Map> postInfo(@RequestBody HashMap input) {
        
        System.out.println("Input data: "+input);
        
        Map response = new HashMap<>();
        response.put("message", "input received");
        
        return new ResponseEntity<Map>(response, HttpStatus.OK);
    }

Postman : enter image description here

console log:

Input data: {}

Solution

  • This may sound silly, but you can check if the RequestBody is actually being imported. It should look like this:

    import org.springframework.web.bind.annotation.RequestBody;
    

    I was facing the same issue and adding this import did the trick.