{"id":7212,"date":"2021-05-19T23:01:39","date_gmt":"2021-05-20T03:01:39","guid":{"rendered":"https:\/\/springframework.guru\/?p=7212"},"modified":"2021-09-06T10:43:05","modified_gmt":"2021-09-06T14:43:05","slug":"requestbody-annotation","status":"publish","type":"post","link":"https:\/\/springframework.guru\/requestbody-annotation\/","title":{"rendered":"The @RequestBody Annotation"},"content":{"rendered":"<p>Spring Web applications and services need to process client requests sent over HTTP. When the HTTP clients send data with the request, the data is in the request body. On the application side, you need a mechanism to deserialize data sent in the request body to domain objects. This is done using the <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">@RequestBody <\/code>annotation.<\/p>\n<p>In this post, I will explain how to use the <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">@RequestBody <\/code> annotation.<\/p>\n<h2>Deserializing RequestBody to Domain Object using <code class=\"\u201cEnlighterJSRAW\u201d\" data-enlighter-language=\"\u201cjava\u201d\" data-enlighter-theme=\"\u201cgit\u201d\" data-enlighter-linenumbers=\"\u201cfalse\u201d\">@RequestBody <\/code>annotation<\/h2>\n<p>The <code class=\"\u201cEnlighterJSRAW\u201d\" data-enlighter-language=\"\u201cjava\u201d\" data-enlighter-theme=\"\u201cgit\u201d\" data-enlighter-linenumbers=\"\u201cfalse\u201d\">@RequestBody <\/code> annotation is applicable to handler methods of Spring controllers. This annotation indicates that Spring should deserialize a request body into an object. This object is passed as a handler method parameter.<\/p>\n<p>Under the hood, the actual deserialization is done by one of the many implementations of <a href=\"https:\/\/docs.spring.io\/spring-framework\/docs\/current\/javadoc-api\/org\/springframework\/messaging\/converter\/MessageConverter.html\" target=\"_blank\" rel=\"noopener\">MessageConverter<\/a>.<\/p>\n<p>To understand how this works, let\u2019s create a simple domain class to represent user credentials.<\/p>\n<p>The code of the <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">User<\/code> domain class is this.<\/p>\n<h3>User.java<\/h3>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\">package gur.springframework.model;\r\n\r\npublic class User {\r\nprivate String userName;\r\nprivate String password;\r\n\r\n    public User() {\r\n    }\r\n\r\n    public User(String userName, String password) {\r\n        this.userName = userName;\r\n        this.password = password;\r\n    }\r\n   \/\/Getter and Setter\r\n\r\n    public void setUserName(String userName) {\r\n        this.userName = userName;\r\n    }\r\n\r\n    public void setPassword(String password) {\r\n        this.password = password;\r\n    }\r\n\r\n    public String getUserName() {\r\n        return userName;\r\n    }\r\n\r\n    public String getPassword() {\r\n        return password;\r\n    }\r\n}\r\n<\/pre>\n<p>The code of the controller is this.<\/p>\n<p><strong>DemoController.java<\/strong><\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\">package gur.springframework.controller;\r\n\r\nimport gur.springframework.model.User;\r\nimport org.springframework.http.HttpStatus;\r\nimport org.springframework.web.bind.annotation.*;\r\n\r\n@RequestMapping(\"api\/v1\")\r\n@RestController\r\npublic class DemoController {\r\n\r\n    @PostMapping(\"users\")\r\n    @ResponseStatus(HttpStatus.CREATED)\r\n    public User registerUserCredential(@RequestBody User user){\r\n        System.out.println(\"User ID: \"+user.getUserName());\r\n        System.out.println(\"User ID: \"+user.getPassword());\r\n        return user;\r\n    }\r\n}\r\n<\/pre>\n<p>In the preceding controller class, the <code class=\"\u201cEnlighterJSRAW\u201d\" data-enlighter-language=\"\u201cjava\u201d\" data-enlighter-theme=\"\u201cgit\u201d\" data-enlighter-linenumbers=\"\u201cfalse\u201d\">@RequestBody <\/code> annotation is specified on the <code class=\"\u201cEnlighterJSRAW\u201d\" data-enlighter-language=\"\u201cjava\u201d\" data-enlighter-theme=\"\u201cgit\u201d\" data-enlighter-linenumbers=\"\u201cfalse\u201d\">registerUserCredential()<\/code> method. This annotation informs Spring to deserialize an incoming request body to the User domain object. The <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">System.out.println<\/code> statements prints to console the user name and password of the deserialised <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">User<\/code> object.<\/p>\n<p>You can send a POST request to invoke the <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">registerUserCredential()<\/code> handler with the following URL:<\/p>\n<p><code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">http:\/\/localhost:8080\/api\/v1\/users<\/code><\/p>\n<p>This figure shows a POST request sent from Postman.<\/p>\n<p><a href=\"http:\/\/springframework.guru\/wp-content\/uploads\/2021\/05\/Post_request_with_request_body.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-7216\" src=\"http:\/\/springframework.guru\/wp-content\/uploads\/2021\/05\/Post_request_with_request_body.png\" alt=\"Post request with request body\" width=\"942\" height=\"590\" srcset=\"https:\/\/springframework.guru\/wp-content\/uploads\/2021\/05\/Post_request_with_request_body.png 942w, https:\/\/springframework.guru\/wp-content\/uploads\/2021\/05\/Post_request_with_request_body-300x188.png 300w, https:\/\/springframework.guru\/wp-content\/uploads\/2021\/05\/Post_request_with_request_body-768x481.png 768w, https:\/\/springframework.guru\/wp-content\/uploads\/2021\/05\/Post_request_with_request_body-848x531.png 848w, https:\/\/springframework.guru\/wp-content\/uploads\/2021\/05\/Post_request_with_request_body-410x257.png 410w\" sizes=\"(max-width: 942px) 100vw, 942px\" \/><\/a><\/p>\n<p>After sending the request, examine the console log. This figure shows the fields of the deserialized <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">User<\/code> object.<\/p>\n<p><a href=\"http:\/\/springframework.guru\/wp-content\/uploads\/2021\/05\/fields-of_deserialized_domain_object.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-large wp-image-7217\" src=\"http:\/\/springframework.guru\/wp-content\/uploads\/2021\/05\/fields-of_deserialized_domain_object-1024x207.png\" alt=\"Fields of Deserialized Domain Object\" width=\"1024\" height=\"207\" srcset=\"https:\/\/springframework.guru\/wp-content\/uploads\/2021\/05\/fields-of_deserialized_domain_object-1024x207.png 1024w, https:\/\/springframework.guru\/wp-content\/uploads\/2021\/05\/fields-of_deserialized_domain_object-300x61.png 300w, https:\/\/springframework.guru\/wp-content\/uploads\/2021\/05\/fields-of_deserialized_domain_object-768x155.png 768w, https:\/\/springframework.guru\/wp-content\/uploads\/2021\/05\/fields-of_deserialized_domain_object-848x172.png 848w, https:\/\/springframework.guru\/wp-content\/uploads\/2021\/05\/fields-of_deserialized_domain_object-410x83.png 410w, https:\/\/springframework.guru\/wp-content\/uploads\/2021\/05\/fields-of_deserialized_domain_object.png 1325w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/a><\/p>\n<p>The automated unit test code of the controller class is this.<\/p>\n<p><strong>DemoControllerTest.java<\/strong><\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\">package gur.springframework.controller;\r\n\r\n\r\nimport com.fasterxml.jackson.databind.ObjectMapper;\r\nimport gur.springframework.model.User;\r\nimport org.junit.jupiter.api.BeforeEach;\r\nimport org.junit.jupiter.api.Test;\r\nimport org.junit.jupiter.api.extension.ExtendWith;\r\nimport org.mockito.junit.jupiter.MockitoExtension;\r\nimport org.springframework.beans.factory.annotation.Autowired;\r\nimport org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;\r\nimport org.springframework.boot.test.context.SpringBootTest;\r\nimport org.springframework.http.MediaType;\r\nimport org.springframework.test.web.servlet.MockMvc;\r\nimport org.springframework.test.web.servlet.MvcResult;\r\nimport org.springframework.test.web.servlet.setup.MockMvcBuilders;\r\nimport static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;\r\nimport static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;\r\n\r\n@ExtendWith(MockitoExtension.class)\r\nclass DemoControllerTest {\r\n\r\n  private  MockMvc mockMvc;\r\n  private User user;\r\n\r\n    @BeforeEach\r\n    void setUp() {\r\n        user = new User(\"John\",\"pass1234\");\r\n\r\n         mockMvc = MockMvcBuilders\r\n                .standaloneSetup(DemoController.class)\r\n                .build();\r\n    }\r\n\r\n@Test\r\n    void registerUserCredential()throws Exception {\r\n\r\n    MvcResult result =    mockMvc.perform(post(\"\/api\/v1\/users\")\r\n            .contentType(MediaType.APPLICATION_JSON_VALUE)\r\n            .content(asJsonString(user)))\r\n            .andExpect(status().isCreated())\r\n            .andReturn();\r\n    String content = result.getResponse().getContentAsString();\r\n    System.out.println(content);\r\n\r\n}\r\n    public static String asJsonString(final Object obj) {\r\n        try {\r\n            return new ObjectMapper().writeValueAsString(obj);\r\n        } catch (Exception e) {\r\n            throw new RuntimeException(e);\r\n        }\r\n    }\r\n}\r\n<\/pre>\n<h2>Deserializing RequestBody to Map using <code class=\"\u201cEnlighterJSRAW\u201d\" data-enlighter-language=\"\u201cjava\u201d\" data-enlighter-theme=\"\u201cgit\u201d\" data-enlighter-linenumbers=\"\u201cfalse\u201d\">@RequestBody <\/code>annotation<\/h2>\n<p>You can also use the <code class=\"\u201cEnlighterJSRAW\u201d\" data-enlighter-language=\"\u201cjava\u201d\" data-enlighter-theme=\"\u201cgit\u201d\" data-enlighter-linenumbers=\"\u201cfalse\u201d\">@RequestBody <\/code> annotation to deserialize a request body to a Java <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">Map<\/code>.<\/p>\n<p>As a programmer, you don\u2019t need to do anything special. You only need to pass a <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">Map<\/code> parameter to the handler method. It is <code class=\"\u201cEnlighterJSRAW\u201d\" data-enlighter-language=\"\u201cjava\u201d\" data-enlighter-theme=\"\u201cgit\u201d\" data-enlighter-linenumbers=\"\u201cfalse\u201d\">@RequestBody <\/code> along with <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">HttpMessageConverter<\/code> who will deserialize the JSON in the request body to the <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">Map<\/code>.<\/p>\n<p>The code is this.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\">@PostMapping(\"\/map\/users\")\r\n@ResponseStatus(HttpStatus.CREATED)\r\npublic Map&lt;String, String&gt; registerUserCredentialThroughMap(@RequestBody Map&lt;String, String&gt; userMap){\r\n    System.out.println(\"User ID: \"+userMap.get(\"userName\"));\r\n    System.out.println(\"User ID: \"+userMap.get(\"password\"));\r\n    return userMap;\r\n}\r\n<\/pre>\n<p>Once you run the application, access it using this URL from Postman.<\/p>\n<p><code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">http:\/\/localhost:8080\/api\/v1\/map\/users<\/code><\/p>\n<p>As a result, you can see the deserialized map values on the console as shown in this figure.<\/p>\n<p><a href=\"http:\/\/springframework.guru\/wp-content\/uploads\/2021\/05\/fields-of_deserialized_map.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-7218\" src=\"http:\/\/springframework.guru\/wp-content\/uploads\/2021\/05\/fields-of_deserialized_map.png\" alt=\"Fields of Deserialized Map\" width=\"978\" height=\"271\" srcset=\"https:\/\/springframework.guru\/wp-content\/uploads\/2021\/05\/fields-of_deserialized_map.png 978w, https:\/\/springframework.guru\/wp-content\/uploads\/2021\/05\/fields-of_deserialized_map-300x83.png 300w, https:\/\/springframework.guru\/wp-content\/uploads\/2021\/05\/fields-of_deserialized_map-768x213.png 768w, https:\/\/springframework.guru\/wp-content\/uploads\/2021\/05\/fields-of_deserialized_map-848x235.png 848w, https:\/\/springframework.guru\/wp-content\/uploads\/2021\/05\/fields-of_deserialized_map-410x114.png 410w\" sizes=\"(max-width: 978px) 100vw, 978px\" \/><\/a><\/p>\n<p>The <code class=\"\u201cEnlighterJSRAW\u201d\" data-enlighter-language=\"\u201cjava\u201d\" data-enlighter-theme=\"\u201cgit\u201d\" data-enlighter-linenumbers=\"\u201cfalse\u201d\">@RequestBody <\/code> annotation comes with the <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">required<\/code> attribute that defaults to <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">true<\/code>.\u00a0 Above all, this enforces that a request always contains body content. If not so, an exception is thrown. You can switch this to <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">false<\/code> if you prefer null to be passed when the body content is null.<\/p>\n<p>The code to do so is this.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\">@PostMapping(\"users\")\r\n    @ResponseStatus(HttpStatus.CREATED)\r\n    public User registerUserCredential(@RequestBody User user, required=\u201dfalse\u201d)\r\n<\/pre>\n<p>The <code class=\"\u201cEnlighterJSRAW\u201d\" data-enlighter-language=\"\u201cjava\u201d\" data-enlighter-theme=\"\u201cgit\u201d\" data-enlighter-linenumbers=\"\u201cfalse\u201d\">@RequestBody <\/code> annotation is also commonly used with the <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">@Valid<\/code> annotation. Both together perform validation of request data. You can read more about it in my post- <a href=\"https:\/\/springframework.guru\/bean-validation-in-spring-boot\/\" target=\"_blank\" rel=\"noopener\">Bean Validation in Spring Boot<\/a><\/p>\n<p>You can find the source code of this post on <a href=\"https:\/\/github.com\/spring-framework-guru\/sfg-blog-posts\/tree\/master\/java-bean-validation\" target=\"_blank\" rel=\"noopener\">Github<\/a>.<\/p>\n<p>For in-depth knowledge of the Spring Framework and Spring Boot, you can check my Udemy Best Seller Course <a href=\"https:\/\/www.udemy.com\/course\/spring-framework-5-beginner-to-guru\/?referralCode=6D9ECD1F93988FEE5CE9\" target=\"_blank\" rel=\"noopener\">Spring Framework 5: Beginner to Guru<\/a><\/p>\n<p><a href=\"https:\/\/www.udemy.com\/course\/spring-framework-5-beginner-to-guru\/?referralCode=6D9ECD1F93988FEE5CE9\" target=\"_blank\" rel=\"noopener\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-4656 size-full\" src=\"http:\/\/springframework.guru\/wp-content\/uploads\/2017\/07\/Spring-5ver02bweb.jpg\" alt=\"Spring Framework 5\" width=\"560\" height=\"315\" srcset=\"https:\/\/springframework.guru\/wp-content\/uploads\/2017\/07\/Spring-5ver02bweb.jpg 560w, https:\/\/springframework.guru\/wp-content\/uploads\/2017\/07\/Spring-5ver02bweb-300x169.jpg 300w, https:\/\/springframework.guru\/wp-content\/uploads\/2017\/07\/Spring-5ver02bweb-410x231.jpg 410w\" sizes=\"(max-width: 560px) 100vw, 560px\" \/><\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Spring Web applications and services need to process client requests sent over HTTP. When the HTTP clients send data with the request, the data is in the request body. On the application side, you need a mechanism to deserialize data sent in the request body to domain objects. This is done using the @RequestBody annotation. [&hellip;]<a href=\"https:\/\/springframework.guru\/requestbody-annotation\/\" class=\"df-link-excerpt\">Continue reading<\/a><\/p>\n","protected":false},"author":111,"featured_media":4590,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_lmt_disableupdate":"","_lmt_disable":"","_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"_uf_show_specific_survey":0,"_uf_disable_surveys":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","enabled":false},"version":2}},"categories":[21,104,182,34,354],"tags":[358,359],"class_list":["post-7212","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-spring","category-spring-boot","category-spring-framework-5","category-spring-mvc","category-spring-rest","tag-requestbody","tag-request-body-annotation"],"jetpack_publicize_connections":[],"aioseo_notices":[],"modified_by":"jt","jetpack_sharing_enabled":true,"jetpack_featured_media_url":"https:\/\/springframework.guru\/wp-content\/uploads\/2015\/03\/Banner560x292_06aweb.jpg","jetpack_shortlink":"https:\/\/wp.me\/p5BZrZ-1Sk","_links":{"self":[{"href":"https:\/\/springframework.guru\/wp-json\/wp\/v2\/posts\/7212"}],"collection":[{"href":"https:\/\/springframework.guru\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/springframework.guru\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/springframework.guru\/wp-json\/wp\/v2\/users\/111"}],"replies":[{"embeddable":true,"href":"https:\/\/springframework.guru\/wp-json\/wp\/v2\/comments?post=7212"}],"version-history":[{"count":11,"href":"https:\/\/springframework.guru\/wp-json\/wp\/v2\/posts\/7212\/revisions"}],"predecessor-version":[{"id":8153,"href":"https:\/\/springframework.guru\/wp-json\/wp\/v2\/posts\/7212\/revisions\/8153"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/springframework.guru\/wp-json\/wp\/v2\/media\/4590"}],"wp:attachment":[{"href":"https:\/\/springframework.guru\/wp-json\/wp\/v2\/media?parent=7212"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/springframework.guru\/wp-json\/wp\/v2\/categories?post=7212"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/springframework.guru\/wp-json\/wp\/v2\/tags?post=7212"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}