最近一段时间学习了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的值;

  1. @Controller
  2. @RequestMapping("/appointments")
  3. public class AppointmentsController {
  4.  
  5. private AppointmentBook appointmentBook;
  6.  
  7. @Autowired
  8. public AppointmentsController(AppointmentBook appointmentBook) {
  9. this.appointmentBook = appointmentBook;
  10. }
  11.  
  12. @RequestMapping(method = RequestMethod.GET)
  13. public Map<String, Appointment> get() {
  14. return appointmentBook.getAppointmentsForToday();
  15. }
  16.  
  17. @RequestMapping(value="/{day}", method = RequestMethod.GET)
  18. public Map<String, Appointment> getForDay(@PathVariable @DateTimeFormat(iso=ISO.DATE) Date day, Model model) {
  19. return appointmentBook.getAppointmentsForDay(day);
  20. }
  21.  
  22. @RequestMapping(value="/new", method = RequestMethod.GET)
  23. public AppointmentForm getNewForm() {
  24. return new AppointmentForm();
  25. }
  26.  
  27. @RequestMapping(method = RequestMethod.POST)
  28. public String add(@Valid AppointmentForm appointment, BindingResult result) {
  29. if (result.hasErrors()) {
  30. return "appointments/new";
  31. }
  32. appointmentBook.addAppointment(appointment);
  33. return "redirect:/appointments";
  34. }
  35. }

value的uri值为以下三类:

A) 可以指定为普通的具体值;

B)  可以指定为含有某变量的一类值(URI Template Patterns with Path Variables);

C) 可以指定为含正则表达式的一类值( URI Template Patterns with Regular Expressions);

example B)

  1. @RequestMapping(value="/owners/{ownerId}", method=RequestMethod.GET)
  2. public String findOwner(@PathVariable String ownerId, Model model) {
  3. Owner owner = ownerService.findOwner(ownerId);
  4. model.addAttribute("owner", owner);
  5. return "displayOwner";
  6. }

example C)

  1. @RequestMapping("/spring-web/{symbolicName:[a-z-]+}-{version:\d\.\d\.\d}.{extension:\.[a-z]}")
  2. public void handle(@PathVariable String version, @PathVariable String extension) {
  3. // ...
  4. }
  5. }

2 consumes、produces 示例

cousumes的样例:

  1. @Controller
  2. @RequestMapping(value = "/pets", method = RequestMethod.POST, consumes="application/json")
  3. public void addPet(@RequestBody Pet pet, Model model) {
  4. // implementation omitted
  5. }

方法仅处理request Content-Type为“application/json”类型的请求。

produces的样例:

  1. @Controller
  2. @RequestMapping(value = "/pets/{petId}", method = RequestMethod.GET, produces="application/json")
  3. @ResponseBody
  4. public Pet getPet(@PathVariable String petId, Model model) {
  5. // implementation omitted
  6. }

方法仅处理request请求中Accept头中包含了"application/json"的请求,同时暗示了返回的内容类型为application/json;

3 params、headers 示例

params的样例:

  1. @Controller
  2. @RequestMapping("/owners/{ownerId}")
  3. public class RelativePathUriTemplateController {
  4.  
  5. @RequestMapping(value = "/pets/{petId}", method = RequestMethod.GET, params="myParam=myValue")
  6. public void findPet(@PathVariable String ownerId, @PathVariable String petId, Model model) {
  7. // implementation omitted
  8. }
  9. }

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

headers的样例:

  1. @Controller
  2. @RequestMapping("/owners/{ownerId}")
  3. public class RelativePathUriTemplateController {
  4.  
  5. @RequestMapping(value = "/pets", method = RequestMethod.GET, headers="Referer=http://www.ifeng.com/")
  6. public void findPet(@PathVariable String ownerId, @PathVariable String petId, Model model) {
  7. // implementation omitted
  8. }
  9. }

@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

  1. <span style="font-family:Microsoft YaHei;">/**
  2. * Strategy interface that specifies a converter that can convert from and to HTTP requests and responses.
  3. *
  4. * @author Arjen Poutsma
  5. * @author Juergen Hoeller
  6. * @since 3.0
  7. */
  8. public interface HttpMessageConverter<T> {
  9.  
  10. /**
  11. * Indicates whether the given class can be read by this converter.
  12. * @param clazz the class to test for readability
  13. * @param mediaType the media type to read, can be {@code null} if not specified.
  14. * Typically the value of a {@code Content-Type} header.
  15. * @return {@code true} if readable; {@code false} otherwise
  16. */
  17. boolean canRead(Class<?> clazz, MediaType mediaType);
  18.  
  19. /**
  20. * Indicates whether the given class can be written by this converter.
  21. * @param clazz the class to test for writability
  22. * @param mediaType the media type to write, can be {@code null} if not specified.
  23. * Typically the value of an {@code Accept} header.
  24. * @return {@code true} if writable; {@code false} otherwise
  25. */
  26. boolean canWrite(Class<?> clazz, MediaType mediaType);
  27.  
  28. /**
  29. * Return the list of {@link MediaType} objects supported by this converter.
  30. * @return the list of supported media types
  31. */
  32. List<MediaType> getSupportedMediaTypes();
  33.  
  34. /**
  35. * Read an object of the given type form the given input message, and returns it.
  36. * @param clazz the type of object to return. This type must have previously been passed to the
  37. * {@link #canRead canRead} method of this interface, which must have returned {@code true}.
  38. * @param inputMessage the HTTP input message to read from
  39. * @return the converted object
  40. * @throws IOException in case of I/O errors
  41. * @throws HttpMessageNotReadableException in case of conversion errors
  42. */
  43. T read(Class<? extends T> clazz, HttpInputMessage inputMessage)
  44. throws IOException, HttpMessageNotReadableException;
  45.  
  46. /**
  47. * Write an given object to the given output message.
  48. * @param t the object to write to the output message. The type of this object must have previously been
  49. * passed to the {@link #canWrite canWrite} method of this interface, which must have returned {@code true}.
  50. * @param contentType the content type to use when writing. May be {@code null} to indicate that the
  51. * default content type of the converter must be used. If not {@code null}, this media type must have
  52. * previously been passed to the {@link #canWrite canWrite} method of this interface, which must have
  53. * returned {@code true}.
  54. * @param outputMessage the message to write to
  55. * @throws IOException in case of I/O errors
  56. * @throws HttpMessageNotWritableException in case of conversion errors
  57. */
  58. void write(T t, MediaType contentType, HttpOutputMessage outputMessage)
  59. throws IOException, HttpMessageNotWritableException;
  60.  
  61. }
  62. </span>

该接口定义了四个方法,分别是读取数据时的 canRead(), read() 和 写入数据时的canWrite(), write()方法。

在使用 <mvc:annotation-driven />标签配置时,默认配置了RequestMappingHandlerAdapter(注意是RequestMappingHandlerAdapter不是AnnotationMethodHandlerAdapter,详情查看Spring 3.1 document “16.14 Configuring Spring MVC”章节),并为他配置了一下默认的HttpMessageConverter:

  1. ByteArrayHttpMessageConverter converts byte arrays.
  2.  
  3. StringHttpMessageConverter converts strings.
  4.  
  5. ResourceHttpMessageConverter converts to/from org.springframework.core.io.Resource for all media types.
  6.  
  7. SourceHttpMessageConverter converts to/from a javax.xml.transform.Source.
  8.  
  9. FormHttpMessageConverter converts form data to/from a MultiValueMap<String, String>.
  10.  
  11. Jaxb2RootElementHttpMessageConverter converts Java objects to/from XML added if JAXB2 is present on the classpath.
  12.  
  13. MappingJacksonHttpMessageConverter converts to/from JSON added if Jackson is present on the classpath.
  14.  
  15. AtomFeedHttpMessageConverter converts Atom feeds added if Rome is present on the classpath.
  16.  
  17. 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源代码如下:

  1. private Object readWithMessageConverters(MethodParameter methodParam, HttpInputMessage inputMessage, Class paramType)
  2. throws Exception {
  3.  
  4. MediaType contentType = inputMessage.getHeaders().getContentType();
  5. if (contentType == null) {
  6. StringBuilder builder = new StringBuilder(ClassUtils.getShortName(methodParam.getParameterType()));
  7. String paramName = methodParam.getParameterName();
  8. if (paramName != null) {
  9. builder.append(' ');
  10. builder.append(paramName);
  11. }
  12. throw new HttpMediaTypeNotSupportedException(
  13. "Cannot extract parameter (" + builder.toString() + "): no Content-Type found");
  14. }
  15.  
  16. List<MediaType> allSupportedMediaTypes = new ArrayList<MediaType>();
  17. if (this.messageConverters != null) {
  18. for (HttpMessageConverter<?> messageConverter : this.messageConverters) {
  19. allSupportedMediaTypes.addAll(messageConverter.getSupportedMediaTypes());
  20. if (messageConverter.canRead(paramType, contentType)) {
  21. if (logger.isDebugEnabled()) {
  22. logger.debug("Reading [" + paramType.getName() + "] as \"" + contentType
  23. +"\" using [" + messageConverter + "]");
  24. }
  25. return messageConverter.read(paramType, inputMessage);
  26. }
  27. }
  28. }
  29. throw new HttpMediaTypeNotSupportedException(contentType, allSupportedMediaTypes);
  30. }

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

源代码如下:

  1. private void writeWithMessageConverters(Object returnValue,
  2. HttpInputMessage inputMessage, HttpOutputMessage outputMessage)
  3. throws IOException, HttpMediaTypeNotAcceptableException {
  4. List<MediaType> acceptedMediaTypes = inputMessage.getHeaders().getAccept();
  5. if (acceptedMediaTypes.isEmpty()) {
  6. acceptedMediaTypes = Collections.singletonList(MediaType.ALL);
  7. }
  8. MediaType.sortByQualityValue(acceptedMediaTypes);
  9. Class<?> returnValueType = returnValue.getClass();
  10. List<MediaType> allSupportedMediaTypes = new ArrayList<MediaType>();
  11. if (getMessageConverters() != null) {
  12. for (MediaType acceptedMediaType : acceptedMediaTypes) {
  13. for (HttpMessageConverter messageConverter : getMessageConverters()) {
  14. if (messageConverter.canWrite(returnValueType, acceptedMediaType)) {
  15. messageConverter.write(returnValue, acceptedMediaType, outputMessage);
  16. if (logger.isDebugEnabled()) {
  17. MediaType contentType = outputMessage.getHeaders().getContentType();
  18. if (contentType == null) {
  19. contentType = acceptedMediaType;
  20. }
  21. logger.debug("Written [" + returnValue + "] as \"" + contentType +
  22. "\" using [" + messageConverter + "]");
  23. }
  24. this.responseArgumentUsed = true;
  25. return;
  26. }
  27. }
  28. }
  29. for (HttpMessageConverter messageConverter : messageConverters) {
  30. allSupportedMediaTypes.addAll(messageConverter.getSupportedMediaTypes());
  31. }
  32. }
  33. throw new HttpMediaTypeNotAcceptableException(allSupportedMediaTypes);
  34. }

补充:

  1. MappingJacksonHttpMessageConverter 调用了 objectMapper.writeValue(OutputStream stream, Object)方法,使用@ResponseBody注解返回的对象就传入Object参数内。若返回的对象为已经格式化好的json串时,不使用@RequestBody注解,而应该这样处理:
  1. 1response.setContentType("application/json; charset=UTF-8");
  1. 2response.getWriter().print(jsonStr);
  1. 直接输出到body区,然后的视图为void

spring mvc常用注解的说明的更多相关文章

  1. Spring MVC学习总结(2)——Spring MVC常用注解说明

        使用Spring MVC的注解及其用法和其它相关知识来实现控制器功能. 02     之前在使用Struts2实现MVC的注解时,是借助struts2-convention这个插件,如今我们使 ...

  2. spring mvc常用注解总结

    1.@RequestMapping@RequestMappingRequestMapping是一个用来处理请求地址映射的注解(将请求映射到对应的控制器方法中),可用于类或方法上.用于类上,表示类中的所 ...

  3. Spring入门(十三):Spring MVC常用注解讲解

    在使用Spring MVC开发Web应用程序时,控制器Controller的开发非常重要,虽然说视图(JSP或者是Thymeleaf)也很重要,因为它才是直接呈现给用户的,不过由于现在前端越来越重要, ...

  4. Spring MVC常用注解

    cp by http://www.cnblogs.com/leskang/p/5445698.html 1.@Controller 在SpringMVC 中,控制器Controller 负责处理由Di ...

  5. spring mvc常用注解标签

    @Controller 在SpringMVC 中,控制器Controller 负责处理由DispatcherServlet 分发的请求,它把用户请求的数据经过业务处理层处理之后封装成一个Model , ...

  6. spring mvc 常用注解

    1.@requestMapping注解,绑定指定的url,requestmapping注解的属性值有value和method. requestmaping可以作用在类上或者方法上 如:@Request ...

  7. Spring MVC常用注解@PathVariable、@RequestHeader、@CookieValue、@RequestParam、@RequestBody、@SessionAttributes、@ModelAttribute

    简介: handler method参数绑定常用的注解,我们根据他们处理的Request的不同内容部分分为四类:(主要讲解常用类型) A.处理requet uri部分(这里指uri template中 ...

  8. Spring MVC 常用注解 和session界面渲染取值

    @RequestParams name 修饰当前形参的属性 value 和name属性一样 也是修饰当前属性 defaultValue 给属性设置一个默认值 默认属性 required 必备属性 1. ...

  9. J2EE进阶(十三)Spring MVC常用的那些注解

    Spring MVC常用的那些注解 前言 Spring从2.5版本开始在编程中引入注解,用户可以使用@RequestMapping, @RequestParam,@ModelAttribute等等这样 ...

随机推荐

  1. JVM(四)内存回收(二)

    在上一节中"JVM(三)内存回收(一)"我讲到了垃圾回收的几种算法,算是解决了之前提到的3个问题中的最后一个. 关于内存回收,还应该了解常用的内存回收器(GC Collector) ...

  2. Android 之http编程

    HTTP-GET和HTTP-POST定义: 都是使用HTTP的标准协议动词,用于编码和传送变量名/变量值对参数,并且使用相关的请求语义. 每个HTTP-GET和HTTP-POST都由一系列HTTP请求 ...

  3. linux文件权限解析(摘)

    用户组 在linux中的每个用户必须属于一个组,不能独立于组外.在linux中每个文件有所有者.所在组.其它组的概念 - 所有者 - 所在组 - 其它组 - 改变用户所在的组 所有者 一般为文件的创建 ...

  4. MVC(3DOnLine)开发过程的一些难点以及知识点

    1.当修改数据然后保存时,会提示有一行受影响无法保存   @Html.HiddenFor(model => model.UserID)  最好将主键隐藏  也就是不去修改它 原因:修改了主键 然 ...

  5. vue学习第一篇 hello world

    计划近期开始学习vue.js.先敲一个hello wolrd作为开始. <!DOCTYPE html> <html lang="en"> <head& ...

  6. "svn: E155010: 提交失败"问题解决

    习惯于通过命令行操作svn,今天如往常一样提交代码: AnnytekiMacBook-Air:weiyibao Anny$ svn ci -m "code" 居然报错,如下: sv ...

  7. 关于JetBrains CLion 激活 (CLion License Activation)的解决办法,带hosts详细修改

    CLion版本号:JetBrains CLion 2017.2.1 第一行选择Activite,第二行Activate license with:选择Activation code. 这个时候里面的代 ...

  8. Java数据结构和算法总结-冒泡排序、选择排序、插入排序算法分析

    前言:排序在算法中的地位自然不必多说,在许多工作中都用到了排序,就像学生成绩统计名次.商城商品销量排名.新闻的搜索热度排名等等.也正因为排序的应用范围如此之广,引起了许多人深入研究它的兴趣,直至今天, ...

  9. python堆栈实现

    百度百科定义: 堆栈是一个在计算机科学中经常使用的抽象数据类型.堆栈中的物体具有一个特性: 最后一个放入堆栈中的物体总是被最先拿出来, 这个特性通常称为后进先出(LIFO)队列. 堆栈中定义了一些操作 ...

  10. VB.NET生成重复窗体

    Public Class Form1 Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click ...