RequestBody of a REST application

2020-03-17 05:33发布

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

2条回答
一夜七次
2楼-- · 2020-03-17 05:48

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.

查看更多
家丑人穷心不美
3楼-- · 2020-03-17 05:49

Another answer to the OP's exact question is to set the consumes content type to "text/plain" and then declare a @RequestBody String input parameter. This will pass the text of the POST data in as the declared String variable (postPayload in the following example).

Of course, this presumes your POST payload is text data (as the OP stated was the case).

Example:

    @RequestMapping(value = "/user/register", method = RequestMethod.POST, consumes = "text/plain")
    public ModelAndView addUser(@RequestBody String postPayload) {    
        // ...    
    }
查看更多
登录 后发表回答