你真的懂@ResponseBody和@RequestBody吗?
简介
Response、Request是指的HTTP协议的请求和响应。我们知道一个请求有请求头,请求行、请求体三部分组成。响应也是如此,分为响应头,响应行和响应体三部分。Body在这里指的就是“体”。@ResponseBody和@RequestBody都是SpringMVC的一个注解。我们先从@ResponseBody开始说起。
@ResponseBody
其一般加在web层的方法上,作用是将加入此注解的方法返回的对象序列化,放在本次响应的响应体中传递给前端。它可以将数据序列化为JSON、XML返回,不过我们一般用的都是JSON类型,用作AJAX调用。
仅使用@RequestMapping注解时,我们可以通过return一个字符串用来跳转页面。但是加入了@ResponseBody以后返回的字符串也会被解析为json格式的数据,无法进行跳转。
@RestController
SpringMVC提供了一个神奇的注解@RestController,我们可以先看一下它的源码。
/*
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.web.bind.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.core.annotation.AliasFor;
import org.springframework.stereotype.Controller;
/**
* A convenience annotation that is itself annotated with
* {@link Controller @Controller} and {@link ResponseBody @ResponseBody}.
* <p>
* Types that carry this annotation are treated as controllers where
* {@link RequestMapping @RequestMapping} methods assume
* {@link ResponseBody @ResponseBody} semantics by default.
*
* <p><b>NOTE:</b> {@code @RestController} is processed if an appropriate
* {@code HandlerMapping}-{@code HandlerAdapter} pair is configured such as the
* {@code RequestMappingHandlerMapping}-{@code RequestMappingHandlerAdapter}
* pair which are the default in the MVC Java config and the MVC namespace.
*
* @author Rossen Stoyanchev
* @author Sam Brannen
* @since 4.0
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Controller
@ResponseBody
public @interface RestController {
/**
* The value may indicate a suggestion for a logical component name,
* to be turned into a Spring bean in case of an autodetected component.
* @return the suggested component name, if any (or empty String otherwise)
* @since 4.0.1
*/
@AliasFor(annotation = Controller.class)
String value() default "";
}
我们可以看到,其包含了@Controller、@ResponseBody等几个注解,我们知道@Controller是加在web层的类上的,@RestController同样也是加在web层的类上,其作用就是为该类中的所有方法都默认加上@ResponseBody,就不用每个方法都单独加了,这也是对RESTful风格的实现。
@RequestBody
@RequestBody与@ResponseBody相反,是将请求体中的数据拿出,使用适合的 HttpMessageConverter 将请求体写入某个对象。
作用:
1) 该注解用于读取Request请求的body部分数据,使用系统默认配置的HttpMessageConverter进行解析,然后把相应的数据绑定
到要返回的对象上;
2) 再把HttpMessageConverter返回的对象数据绑定到 controller中方法的参数上。
使用时机:
A) GET、POST方式提时, 根据request header Content-Type的值来判断:
application/x-www-form-urlencoded, 可选(即非必须,因为这种情况的数据@RequestParam, @ModelAttribute
也可以处理,当然@RequestBody也能处理);
multipart/form-data, 不能处理(即使用@RequestBody不能处理这种格式的数据);
其他格式, 必须(其他格式包括application/json, application/xml等。这些格式的数据,必须使用@RequestBody来处理);
B) PUT方式提交时, 根据request header Content-Type的值来判断:
application/x-www-form-urlencoded, 必须;multipart/form-data, 不能处理;其他格式, 必须;
说明:request的body部分的数据编码格式由header部分的Content-Type指定;
例如:
@RequestMapping(value = "user/login")
@ResponseBody
// 将ajax(datas)发出的请求写入 User 对象中
public User login(@RequestBody User user) {
// 这样就不会再被解析为跳转路径,而是直接将user对象写入 HTTP 响应正文中
return user;
}
可以通俗的理解为@RequestBody是解析请求中的json或者xml,放入后台用于接收的POJO参数中。但是其不支持一些特定类型的内容。
参考博客:CSDN链接