spring mvc常用注解的说明
最近一段时间学习了springboot,所以熟悉一下mvc中常用的注解,这样可以方便开发
简介:
@RequestMapping
RequestMapping是一个用来处理请求地址映射的注解,可用于类或方法上。用于类上,表示类中的所有响应请求的方法都是以该地址作为父路径。
RequestMapping注解有六个属性,下面我们把她分成三类进行说明。
1、 value, method;
value: 指定请求的实际地址,指定的地址可以是URI Template 模式(后面将会说明);
method: 指定请求的method类型, GET、POST、PUT、DELETE等;
2、 consumes,produces;
consumes: 指定处理请求的提交内容类型(Content-Type),例如application/json, text/html;
produces: 指定返回的内容类型,仅当request请求头中的(Accept)类型中包含该指定类型才返回;
3、 params,headers;
params: 指定request中必须包含某些参数值是,才让该方法处理。
headers: 指定request中必须包含某些指定的header值,才能让该方法处理请求。
示例:
1、value / method 示例
默认RequestMapping("....str...")即为value的值;
- @Controller
- @RequestMapping("/appointments")
- public class AppointmentsController {
- private AppointmentBook appointmentBook;
- @Autowired
- public AppointmentsController(AppointmentBook appointmentBook) {
- this.appointmentBook = appointmentBook;
- }
- @RequestMapping(method = RequestMethod.GET)
- public Map<String, Appointment> get() {
- return appointmentBook.getAppointmentsForToday();
- }
- @RequestMapping(value="/{day}", method = RequestMethod.GET)
- public Map<String, Appointment> getForDay(@PathVariable @DateTimeFormat(iso=ISO.DATE) Date day, Model model) {
- return appointmentBook.getAppointmentsForDay(day);
- }
- @RequestMapping(value="/new", method = RequestMethod.GET)
- public AppointmentForm getNewForm() {
- return new AppointmentForm();
- }
- @RequestMapping(method = RequestMethod.POST)
- public String add(@Valid AppointmentForm appointment, BindingResult result) {
- if (result.hasErrors()) {
- return "appointments/new";
- }
- appointmentBook.addAppointment(appointment);
- return "redirect:/appointments";
- }
- }
value的uri值为以下三类:
A) 可以指定为普通的具体值;
B) 可以指定为含有某变量的一类值(URI Template Patterns with Path Variables);
C) 可以指定为含正则表达式的一类值( URI Template Patterns with Regular Expressions);
example B)
- @RequestMapping(value="/owners/{ownerId}", method=RequestMethod.GET)
- public String findOwner(@PathVariable String ownerId, Model model) {
- Owner owner = ownerService.findOwner(ownerId);
- model.addAttribute("owner", owner);
- return "displayOwner";
- }
example C)
- @RequestMapping("/spring-web/{symbolicName:[a-z-]+}-{version:\d\.\d\.\d}.{extension:\.[a-z]}")
- public void handle(@PathVariable String version, @PathVariable String extension) {
- // ...
- }
- }
2 consumes、produces 示例
cousumes的样例:
- @Controller
- @RequestMapping(value = "/pets", method = RequestMethod.POST, consumes="application/json")
- public void addPet(@RequestBody Pet pet, Model model) {
- // implementation omitted
- }
方法仅处理request Content-Type为“application/json”类型的请求。
produces的样例:
- @Controller
- @RequestMapping(value = "/pets/{petId}", method = RequestMethod.GET, produces="application/json")
- @ResponseBody
- public Pet getPet(@PathVariable String petId, Model model) {
- // implementation omitted
- }
方法仅处理request请求中Accept头中包含了"application/json"的请求,同时暗示了返回的内容类型为application/json;
3 params、headers 示例
params的样例:

- @Controller
- @RequestMapping("/owners/{ownerId}")
- public class RelativePathUriTemplateController {
- @RequestMapping(value = "/pets/{petId}", method = RequestMethod.GET, params="myParam=myValue")
- public void findPet(@PathVariable String ownerId, @PathVariable String petId, Model model) {
- // implementation omitted
- }
- }

仅处理请求中包含了名为“myParam”,值为“myValue”的请求;
headers的样例:

- @Controller
- @RequestMapping("/owners/{ownerId}")
- public class RelativePathUriTemplateController {
- @RequestMapping(value = "/pets", method = RequestMethod.GET, headers="Referer=http://www.ifeng.com/")
- public void findPet(@PathVariable String ownerId, @PathVariable String petId, Model model) {
- // implementation omitted
- }
- }

@RequestBody
作用:
i) 该注解用于读取Request请求的body部分数据,使用系统默认配置的HttpMessageConverter进行解析,然后把相应的数据绑定到要返回的对象上;
ii) 再把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指定;
@ResponseBody
作用:
该注解用于将Controller的方法返回的对象,通过适当的HttpMessageConverter转换为指定格式后,写入到Response对象的body数据区。
使用时机:
返回的数据不是html标签的页面,而是其他某种格式的数据时(如json、xml等)使用;
HttpMessageConverter

- <span style="font-family:Microsoft YaHei;">/**
- * Strategy interface that specifies a converter that can convert from and to HTTP requests and responses.
- *
- * @author Arjen Poutsma
- * @author Juergen Hoeller
- * @since 3.0
- */
- public interface HttpMessageConverter<T> {
- /**
- * Indicates whether the given class can be read by this converter.
- * @param clazz the class to test for readability
- * @param mediaType the media type to read, can be {@code null} if not specified.
- * Typically the value of a {@code Content-Type} header.
- * @return {@code true} if readable; {@code false} otherwise
- */
- boolean canRead(Class<?> clazz, MediaType mediaType);
- /**
- * Indicates whether the given class can be written by this converter.
- * @param clazz the class to test for writability
- * @param mediaType the media type to write, can be {@code null} if not specified.
- * Typically the value of an {@code Accept} header.
- * @return {@code true} if writable; {@code false} otherwise
- */
- boolean canWrite(Class<?> clazz, MediaType mediaType);
- /**
- * Return the list of {@link MediaType} objects supported by this converter.
- * @return the list of supported media types
- */
- List<MediaType> getSupportedMediaTypes();
- /**
- * Read an object of the given type form the given input message, and returns it.
- * @param clazz the type of object to return. This type must have previously been passed to the
- * {@link #canRead canRead} method of this interface, which must have returned {@code true}.
- * @param inputMessage the HTTP input message to read from
- * @return the converted object
- * @throws IOException in case of I/O errors
- * @throws HttpMessageNotReadableException in case of conversion errors
- */
- T read(Class<? extends T> clazz, HttpInputMessage inputMessage)
- throws IOException, HttpMessageNotReadableException;
- /**
- * Write an given object to the given output message.
- * @param t the object to write to the output message. The type of this object must have previously been
- * passed to the {@link #canWrite canWrite} method of this interface, which must have returned {@code true}.
- * @param contentType the content type to use when writing. May be {@code null} to indicate that the
- * default content type of the converter must be used. If not {@code null}, this media type must have
- * previously been passed to the {@link #canWrite canWrite} method of this interface, which must have
- * returned {@code true}.
- * @param outputMessage the message to write to
- * @throws IOException in case of I/O errors
- * @throws HttpMessageNotWritableException in case of conversion errors
- */
- void write(T t, MediaType contentType, HttpOutputMessage outputMessage)
- throws IOException, HttpMessageNotWritableException;
- }
- </span>

该接口定义了四个方法,分别是读取数据时的 canRead(), read() 和 写入数据时的canWrite(), write()方法。
在使用 <mvc:annotation-driven />标签配置时,默认配置了RequestMappingHandlerAdapter(注意是
RequestMappingHandlerAdapter
不是AnnotationMethodHandlerAdapter,详情查看Spring 3.1 document “16.14 Configuring Spring MVC”章节),并为他配置了一下默认的HttpMessageConverter:

- ByteArrayHttpMessageConverter converts byte arrays.
- StringHttpMessageConverter converts strings.
- ResourceHttpMessageConverter converts to/from org.springframework.core.io.Resource for all media types.
- SourceHttpMessageConverter converts to/from a javax.xml.transform.Source.
- FormHttpMessageConverter converts form data to/from a MultiValueMap<String, String>.
- Jaxb2RootElementHttpMessageConverter converts Java objects to/from XML — added if JAXB2 is present on the classpath.
- MappingJacksonHttpMessageConverter converts to/from JSON — added if Jackson is present on the classpath.
- AtomFeedHttpMessageConverter converts Atom feeds — added if Rome is present on the classpath.
- RssChannelHttpMessageConverter converts RSS feeds — added if Rome is present on the classpath.

ByteArrayHttpMessageConverter: 负责读取二进制格式的数据和写出二进制格式的数据;
StringHttpMessageConverter: 负责读取字符串格式的数据和写出二进制格式的数据;
ResourceHttpMessageConverter:负责读取资源文件和写出资源文件数据;
FormHttpMessageConverter: 负责读取form提交的数据(能读取的数据格式为 application/x-www-form-urlencoded,不能读取multipart/form-data格式数据);负责写入application/x-www-from-urlencoded和multipart/form-data格式的数据;
MappingJacksonHttpMessageConverter: 负责读取和写入json格式的数据;
SouceHttpMessageConverter: 负责读取和写入 xml 中javax.xml.transform.Source定义的数据;
Jaxb2RootElementHttpMessageConverter: 负责读取和写入xml 标签格式的数据;
AtomFeedHttpMessageConverter: 负责读取和写入Atom格式的数据;
RssChannelHttpMessageConverter: 负责读取和写入RSS格式的数据;
当使用@RequestBody和@ResponseBody注解时,
RequestMappingHandlerAdapter
就使用它们来进行读取或者写入相应格式的数据。
HttpMessageConverter匹配过程:
@RequestBody注解时: 根据Request对象header部分的Content-Type类型,逐一匹配合适的HttpMessageConverter来读取数据;
spring 3.1源代码如下:

- private Object readWithMessageConverters(MethodParameter methodParam, HttpInputMessage inputMessage, Class paramType)
- throws Exception {
- MediaType contentType = inputMessage.getHeaders().getContentType();
- if (contentType == null) {
- StringBuilder builder = new StringBuilder(ClassUtils.getShortName(methodParam.getParameterType()));
- String paramName = methodParam.getParameterName();
- if (paramName != null) {
- builder.append(' ');
- builder.append(paramName);
- }
- throw new HttpMediaTypeNotSupportedException(
- "Cannot extract parameter (" + builder.toString() + "): no Content-Type found");
- }
- List<MediaType> allSupportedMediaTypes = new ArrayList<MediaType>();
- if (this.messageConverters != null) {
- for (HttpMessageConverter<?> messageConverter : this.messageConverters) {
- allSupportedMediaTypes.addAll(messageConverter.getSupportedMediaTypes());
- if (messageConverter.canRead(paramType, contentType)) {
- if (logger.isDebugEnabled()) {
- logger.debug("Reading [" + paramType.getName() + "] as \"" + contentType
- +"\" using [" + messageConverter + "]");
- }
- return messageConverter.read(paramType, inputMessage);
- }
- }
- }
- throw new HttpMediaTypeNotSupportedException(contentType, allSupportedMediaTypes);
- }

@ResponseBody注解时: 根据Request对象header部分的Accept属性(逗号分隔),逐一按accept中的类型,去遍历找到能处理的HttpMessageConverter;
源代码如下:

- private void writeWithMessageConverters(Object returnValue,
- HttpInputMessage inputMessage, HttpOutputMessage outputMessage)
- throws IOException, HttpMediaTypeNotAcceptableException {
- List<MediaType> acceptedMediaTypes = inputMessage.getHeaders().getAccept();
- if (acceptedMediaTypes.isEmpty()) {
- acceptedMediaTypes = Collections.singletonList(MediaType.ALL);
- }
- MediaType.sortByQualityValue(acceptedMediaTypes);
- Class<?> returnValueType = returnValue.getClass();
- List<MediaType> allSupportedMediaTypes = new ArrayList<MediaType>();
- if (getMessageConverters() != null) {
- for (MediaType acceptedMediaType : acceptedMediaTypes) {
- for (HttpMessageConverter messageConverter : getMessageConverters()) {
- if (messageConverter.canWrite(returnValueType, acceptedMediaType)) {
- messageConverter.write(returnValue, acceptedMediaType, outputMessage);
- if (logger.isDebugEnabled()) {
- MediaType contentType = outputMessage.getHeaders().getContentType();
- if (contentType == null) {
- contentType = acceptedMediaType;
- }
- logger.debug("Written [" + returnValue + "] as \"" + contentType +
- "\" using [" + messageConverter + "]");
- }
- this.responseArgumentUsed = true;
- return;
- }
- }
- }
- for (HttpMessageConverter messageConverter : messageConverters) {
- allSupportedMediaTypes.addAll(messageConverter.getSupportedMediaTypes());
- }
- }
- throw new HttpMediaTypeNotAcceptableException(allSupportedMediaTypes);
- }

补充:
- MappingJacksonHttpMessageConverter 调用了 objectMapper.writeValue(OutputStream stream, Object)方法,使用@ResponseBody注解返回的对象就传入Object参数内。若返回的对象为已经格式化好的json串时,不使用@RequestBody注解,而应该这样处理:
- 1、response.setContentType("application/json; charset=UTF-8");
- 2、response.getWriter().print(jsonStr);
- 直接输出到body区,然后的视图为void。
spring mvc常用注解的说明的更多相关文章
- Spring MVC学习总结(2)——Spring MVC常用注解说明
使用Spring MVC的注解及其用法和其它相关知识来实现控制器功能. 02 之前在使用Struts2实现MVC的注解时,是借助struts2-convention这个插件,如今我们使 ...
- spring mvc常用注解总结
1.@RequestMapping@RequestMappingRequestMapping是一个用来处理请求地址映射的注解(将请求映射到对应的控制器方法中),可用于类或方法上.用于类上,表示类中的所 ...
- Spring入门(十三):Spring MVC常用注解讲解
在使用Spring MVC开发Web应用程序时,控制器Controller的开发非常重要,虽然说视图(JSP或者是Thymeleaf)也很重要,因为它才是直接呈现给用户的,不过由于现在前端越来越重要, ...
- Spring MVC常用注解
cp by http://www.cnblogs.com/leskang/p/5445698.html 1.@Controller 在SpringMVC 中,控制器Controller 负责处理由Di ...
- spring mvc常用注解标签
@Controller 在SpringMVC 中,控制器Controller 负责处理由DispatcherServlet 分发的请求,它把用户请求的数据经过业务处理层处理之后封装成一个Model , ...
- spring mvc 常用注解
1.@requestMapping注解,绑定指定的url,requestmapping注解的属性值有value和method. requestmaping可以作用在类上或者方法上 如:@Request ...
- Spring MVC常用注解@PathVariable、@RequestHeader、@CookieValue、@RequestParam、@RequestBody、@SessionAttributes、@ModelAttribute
简介: handler method参数绑定常用的注解,我们根据他们处理的Request的不同内容部分分为四类:(主要讲解常用类型) A.处理requet uri部分(这里指uri template中 ...
- Spring MVC 常用注解 和session界面渲染取值
@RequestParams name 修饰当前形参的属性 value 和name属性一样 也是修饰当前属性 defaultValue 给属性设置一个默认值 默认属性 required 必备属性 1. ...
- J2EE进阶(十三)Spring MVC常用的那些注解
Spring MVC常用的那些注解 前言 Spring从2.5版本开始在编程中引入注解,用户可以使用@RequestMapping, @RequestParam,@ModelAttribute等等这样 ...
随机推荐
- JVM(四)内存回收(二)
在上一节中"JVM(三)内存回收(一)"我讲到了垃圾回收的几种算法,算是解决了之前提到的3个问题中的最后一个. 关于内存回收,还应该了解常用的内存回收器(GC Collector) ...
- Android 之http编程
HTTP-GET和HTTP-POST定义: 都是使用HTTP的标准协议动词,用于编码和传送变量名/变量值对参数,并且使用相关的请求语义. 每个HTTP-GET和HTTP-POST都由一系列HTTP请求 ...
- linux文件权限解析(摘)
用户组 在linux中的每个用户必须属于一个组,不能独立于组外.在linux中每个文件有所有者.所在组.其它组的概念 - 所有者 - 所在组 - 其它组 - 改变用户所在的组 所有者 一般为文件的创建 ...
- MVC(3DOnLine)开发过程的一些难点以及知识点
1.当修改数据然后保存时,会提示有一行受影响无法保存 @Html.HiddenFor(model => model.UserID) 最好将主键隐藏 也就是不去修改它 原因:修改了主键 然 ...
- vue学习第一篇 hello world
计划近期开始学习vue.js.先敲一个hello wolrd作为开始. <!DOCTYPE html> <html lang="en"> <head& ...
- "svn: E155010: 提交失败"问题解决
习惯于通过命令行操作svn,今天如往常一样提交代码: AnnytekiMacBook-Air:weiyibao Anny$ svn ci -m "code" 居然报错,如下: sv ...
- 关于JetBrains CLion 激活 (CLion License Activation)的解决办法,带hosts详细修改
CLion版本号:JetBrains CLion 2017.2.1 第一行选择Activite,第二行Activate license with:选择Activation code. 这个时候里面的代 ...
- Java数据结构和算法总结-冒泡排序、选择排序、插入排序算法分析
前言:排序在算法中的地位自然不必多说,在许多工作中都用到了排序,就像学生成绩统计名次.商城商品销量排名.新闻的搜索热度排名等等.也正因为排序的应用范围如此之广,引起了许多人深入研究它的兴趣,直至今天, ...
- python堆栈实现
百度百科定义: 堆栈是一个在计算机科学中经常使用的抽象数据类型.堆栈中的物体具有一个特性: 最后一个放入堆栈中的物体总是被最先拿出来, 这个特性通常称为后进先出(LIFO)队列. 堆栈中定义了一些操作 ...
- VB.NET生成重复窗体
Public Class Form1 Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click ...