3.6、@RequestParam 和 @RequestBody

431 查看

  这一部分实例见项目的 mvc 分支下的 ParamAndBodyController.java


① 使用@RequestParam绑定请求参数到方法参数

  使用@RequestParam注解绑定请求参数到你的控制器方法中的参数。下面的代码段展示了这种用法:

    /**
     * 使用 @RequestParam 时,请求参数名要和 @RequestParam 的值一样,而不是和方法参数名一样
     */
    @GetMapping("/find/pet")
    public String findPet(@RequestParam("petId") int pid, ModelMap model) 
    {

        System.out.println("--> petId : " + pid);
        
        /**
         * 将被放到响应中,发送到客户端
         */
        model.addAttribute("test", "Hello World");
        
        return "/examples/targets/test4";
    }

  默认情况下,使用这个注解的参数是必须的,但是你可以通过设置@RequestParamrequired属性为false来指定参数是可选的(如: @RequestParam(path="id", required=false))。

  如果目标方法的类型参数不是String类型的,将自动应用类型转换。见 “方法参数和类型转换”一节.

  当一个@RequestParam注解用在一个Map<String, String>或者MultiValueMap<String, String>类型的参数上是,这个map将包含所有请求参数

② 使用@RequestBody注解映射请求体

  方法参数注解@RequestBody指定一个方法参数应该被绑定到 HTTP 请求体的值。例如:

    /**
     * 带有 @RequestBody 注解的参数,直接可以得到请求体
     */
    @PutMapping("/handle")
    public void handle(@RequestBody String body, Writer writer) throws IOException 
    {
        System.out.println("--> body : " + body);
        
        /**
         * 将被放到响应中,发送到客户端
         */
        writer.write("{ pet :" + body + " }");
    }

  通过使用一个HttpMessageConverter,你能够把请求体转换为方法参数。HttpMessageConverter负责把 HTTP 请求消息转换为一个对象,也把一个对象转换为 HTTP 请求体。RequestMappingHandlerAdapter支持@RequestBody注解使用下面的默认的HttpMessageConverters:

  • ByteArrayHttpMessageConverter转换字节数组

  • StringHttpMessageConverter转换字符串

  • FormHttpMessageConverter在表单数据和MultiValueMap<String, String>对象之间转换.

  • SourceHttpMessageConverter在请求体和javax.xml.transform.Source之间转换.

  更多关于这些转换器的信息,见消息转换器。也要注意,如果使用MVC命名空间或者MVCJava配置,一个更大范围的消息转换器被默认注册。更多信息见18.16.1节“使用MVC Java配置或者MVC XML命名空间”

  如果你打算读写XML,你会需要配置一个带有指定Marshaller和Unmarshaller(在包org.springframework.oxm中)实现的MarshallingHttpMessageConverter。虽然下面的例子展示了怎让直接在你的配置中做,但是如果你的应用程序通过 MVC 命名空间或者 MVC Java 配置,你要参考18.16.1节“使用 MVC Java 配置或者 MVC XML 命名空间”

<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
    <property name="messageConverters">
        <util:list id="beanList">
            <ref bean="stringHttpMessageConverter"/>
            <ref bean="marshallingHttpMessageConverter"/>
        </util:list>
    </property>
</bean>

<bean id="stringHttpMessageConverter" 
      class="org.springframework.http.converter.StringHttpMessageConverter"/>

<bean id="marshallingHttpMessageConverter" 
      class="org.springframework.http.converter.xml.MarshallingHttpMessageConverter">
    <property name="marshaller" ref="castorMarshaller"/>
    <property name="unmarshaller" ref="castorMarshaller"/>
</bean>

<bean id="castorMarshaller" class="org.springframework.oxm.castor.CastorMarshaller"/>

  一个@RequestBody方法参数可以带有注解@Valid,此时它会被配置好的Validator实例校验。当使用 MVC 命名空间或者 MVC Java 配置时,一个 JSR-303 校验器会自动配置进来,如果类路径中有一个可用的 JSR-303 实现的话。

  就像@ModelAttribute参数一样,一个 Errors 参数可以用于检查错误。如果没有声明这样的参数,一个 MethodArgumentNotValidException 异常将会抛出。这个异常会在 DefaultHandlerExceptionResolver 中处理,并返回一个400错误到客户端。