Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

RequestBody of a REST application

Iam bit new to SpringMVC REST concept. Need a help from experts here to understand/ resolve following issue, I have developed a SpringMVC application, following is a part of a controller class code, and it works perfectly ok with the way it is, meaning it works ok with the JSON type object,

@RequestMapping(method = RequestMethod.POST, value = "/user/register")
public ModelAndView addUser( @RequestBody String payload) {

    try{

        ObjectMapper mapper = new ObjectMapper();
        CreateNewUserRequest request = mapper.readValue(payload, CreateNewUserRequest.class);

        UserBusiness userBusiness = UserBusinessImpl.getInstance();
        CreateNewUserResponse response = userBusiness.createNewUser(request);


        return new ModelAndView(ControllerConstant.JASON_VIEW_RESOLVER, "RESPONSE", response);

and this is my rest-servlet.xml looks like

<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" />
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" />

<bean id="jsonViewResolver" class="org.springframework.web.servlet.view.json.MappingJacksonJsonView" />
<bean id="viewResolver" class="org.springframework.web.servlet.view.BeanNameViewResolver" />


<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
    <property name="messageConverters">
        <list>
            <ref bean="jsonConverter" />
        </list>
    </property>
</bean>

<bean id="jsonConverter" class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
        <property name="supportedMediaTypes" value="application/json" />
</bean> 

<bean name="UserController" class="com.tap.mvp.controller.UserController"/>

My problem is how do i make it work for normal POST request, My controller should not accept JSON type object instead it should work for normal HTTP POST variables. How do i get values from the request?What are the modifications should i need to be done for that. I need to get rid of

ObjectMapper mapper = new ObjectMapper();
        CreateNewUserRequest request = mapper.readValue(payload, CreateNewUserRequest.class);

and instead need to add way to create an instance of

CreateNewUserRequest

class, by invoking its constructor. For that i need to get values from request. How do i do that? Can i treat @RequestBody String payload as a map and get the values? or is there a specific way to get values from the request of HTTP POST method? following values will be in the request,

firstName, lastName, email,password

like image 445
bluelabel Avatar asked Jan 10 '12 17:01

bluelabel


1 Answers

You are mixing two concepts here. The REST service in Spring MVC is much more elegant as Spring handles JSON/XML marshalling for you:

@RequestMapping(
      headers = {"content-type=application/json"},
      method = RequestMethod.POST, value = "/user/register")
@ResponseBody
public CreateNewUserResponse addUser( @RequestBody CreateNewUserRequest request) {
        UserBusiness userBusiness = UserBusinessImpl.getInstance();
        return userBusiness.createNewUser(request);
}

Notice the @ResponseBody annotation. You don't need any view resolvers and manual JSON marshalling. And you get XML (via JAXB) for free.

However data sent via form POST is very different. I would suggest creating second mapping handling different media type:

@RequestMapping(
      headers = {"content-type=application/x-www-form-urlencoded"},
      method = RequestMethod.POST, value = "/user/register")
public ModelAndView addUser(@RequestParam("formParam1") String formParam1) {
  //...
}

With this configuration REST calls with Content-type=application/json will be routed to first method and form POST requests to the second one (at least in theory, haven't tried it). Note that there are simpler ways to handle form data in Spring compared to raw @RequestParam annotation, see: Pass a request parameter in Spring MVC 3.

like image 191
Tomasz Nurkiewicz Avatar answered Sep 20 '22 19:09

Tomasz Nurkiewicz