Spring MVC

研究一下spring mvc

 

 

 springMVC是什么?

 

Spring  MVC是一种基于Java的实现了Web MVC设计模式的请求驱动类型的轻量级Web框架,将web层进行职责解耦,基于请求驱动指的就是使用请求-响应模型,Spring MVC简单的说,最主要的作用就是帮我们简化开发。

 

 

springMVC的好处?

 

让我们能非常简单的设计出干净的Web

进行更简洁的Web层的开发;

天生与Spring框架集成(如IoC容器、AOP等);

支持灵活的URL到页面控制器的映射;

非常容易与其他视图技术集成,如VelocityFreeMarker等等,因为模型数据不放在特定的API里,而是放在一个Model

非常灵活的数据验证、格式化和数据绑定机制,能使用任何对象进行数据绑定,不必实现特定框架的API

支持Restful风格。

 

 

 

一个请求是如何被SpringMVC接受,处理,并返回的: 

 

 

 

 

HandlerAdapter

处理器的适配器,用来绑定数据,解析数据,处理返回值等等。

 

如果我们没有指定默认的HandlerAdapter的时候,spring MVC 会采用默认的类RequestMappingHandlerAdapter来充当Adapter角色。 看一下RequestMappingHandlerAdapter类。

 

 

 

 

一、 springMVC 参数解析器 —— ArgumentResolver

 

SpringMVC,对大家印象最深刻的肯定它强大的参数绑定机制,简单的说就是通过SpringMVC,我们可以把前台各种复杂的数据结构组装好,后台直接可以以对象的方式接收并绑定好数据。

 

 

我们来研究一下spring MVC是如何解析参数并且绑定数据,另外,解析器分别支持哪些参数类型。

 

 

有两个参数,customArgumentResolversargumentResolvers,分别是自定义的参数解析器和默认的参数解析器。

 

 

接口的定义,HandlerMethodArgumentResolver

 

 

常见的实现(HandlerMethodArgumentResolver的实现)。

非常多,

 

1>.RequestParamMethodArgumentResolver-->这个解析器能够为参数上加了RequestParam注解的参数提供支持

2>.RequestParamMapMethodArgumentResolver,支持参数上加了RequestParam注解并且是Map类型的参数.

3>.PathVariableMethodArgumentResolver,支持参数上加了PathVariable注解并且不是Map类型的参数,

4>.PathVariableMapMethodArgumentResolver,支持参数上加了PathVariable注解并且参数类型为Map的参数,

5>.RequestResponseBodyMethodProcessor支持参数上加了RequestBody注解的参数,

6>.RequestPartMethodArgumentResolver支持参数上了RequestPart注解的参数,

7>.ServletCookieValueMethodArgumentResolver支持参数上加了CookieValue注解的参数.

8>.ExpressionValueMethodArgumentResolver支持参数上加了Value注解的参数

 

 

 

 

 

 

简单看两个具体的实现

1>.RequestParamMethodArgumentResolver-->这个解析器能够为参数上加了RequestParam注解的参数提供支持               

            1@RequestParam注解的参数

            2)另一种就是简单类型,如IntegerStringDateURI, URL,Locale

            3) MultipartFile类型的文件上传

 

 

2>.RequestResponseBodyMethodProcessor—>支持参数上加了@Request注解的参数

 

 

 

它的代言人(封装和实现)HandlerMethodArgumentResolverComposite

通过方法getArgumentResolver迭代去寻找可用的resolver直到TRUE

 

 

 

初始化。

 

 

 

如何增加ArgumentResolver

 

WebMvcConfigurationSupport

 

WebMvcConfigurerAdapter

 

@Override

    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {

        argumentResolvers.add(resolver);

    }

 

 

 

 

 推荐使用

 

 1PageableHandlerMethodArgumentResolver 

 

 

如何自定义添加ArgumentResolver

 

 

如何实现 

public Object test(Teacher teacher, Student student){

 

}

(1) @RequestBody的办法 2 自已定义一个 HandlerMethodArgumentResolver(怎么定义呢)

 

 

 

二、 springMVC 返回值处理器 —— HandlerMethodReturnValueHandler

 

一个请求中有入参的绑定处理,那么当然也会有响应参数的处理

HandlerMethodReturnValueHandler就是用来处理当含有@RequestMapping的方法调度完成后,后面要进行的事情。 

 

 

有两个参数,customReturnValueHandlersreturnValueHandlers,分别是自定义的返回值处理器和默认的返回值处理器。

 

 

常见的实现。

也非常多

 

1>. ViewNameMethodReturnValueHandler返回值类型是String 或者void类型的

2>. ModelAndViewMethodReturnValueHandler 返回值类型是ModelAndView或其子类

3>. ModelMethodProcessor 返回值类型是Model或其子类

4>. ViewMethodReturnValueHandler 返回值类型是View或其子类

5>. ModelAttributeMethodProcessor 返回值有@ModelAttribute注解

6>. MapMethodProcessor 返回值是Map

 

 

简单看两个具体的实现

1>.ViewNameMethodReturnValueHandler 支持处理返回值是voidString

2>.RequestResponseBodyMethodProcessor 支持处理返回值被@ResponseBody注解的

 

 

接口的定义 HandlerMethodReturnValueHandler 封装实现是HandlerMethodReturnValueHandlerComposite

 

原理和参数解析器一样, 调用方法 selectHandler ,有所不同,多实现了AsyncHandlerMethodReturnValueHandler,支持处理一些异步的返回值,比如promise

 

 

初始化。

 

如何添加

 

如何实现自定义的 HandlerMethodReturnValueHandler

 

比如要实现返回类型是的某个Tidlong改成String

  @RequestMapping(value = "/test3")

    public Object test3(){

        Trade trade = new Trade();

        trade.setUserId(11878123L);

        trade.setTid(91234444L);

        trade.setSellerNick("q奇园");

        return trade;

    }

 

 

其中mavContainer.setRequestHandled(true);

 

标志着此次请求是否是由handler自己控制的,true表示本方法会响应请求。

使用自己的实现后,需要去除controller方法上的@ResponseBody注解,因为我们不再需要使用默认的处理器。

 

 

三、springMVC 消息转换器 —— HttpMessageConverter

 

Http请求和响应报文本质上都是一串字符串,当请求报文被Java读取之后,它会被封装成为一个ServletInputStream的输入流,供我们读取报文。响应报文则是通过一个ServletOutputStream的输出流,来输出响应报文。我们从流中,只能读取到原始的字符串报文,同样,我们往输出流中,也只能写原始的字符。但是我们在Java中, 所有东西都是以对象来做处理的。

             我们不可能手动的把字符串转成对象,简单的说,从字符串到java所认识的对象这一处理过程,就是由HttpMessageConverter来完成的。

 

 

HttpInputMessage类就是http请求报文的抽象。

HttpOutputMessage类就是SpringMVC内部对一次Http响应报文的抽象

 

再来看看消息转换器的抽象 HttpMessageConverter

 

 

 

常见的实现

 

StringHttpMessageConverter 可以从请求中读和写 String data

FormHttpMessageConverter:可以从、中读和写 form data

ByteArrayMessageConverter:可以从请求中读和写 byte arrays

MarshallingHttpMessageConverterXML的转换需要使用Spring Marshaller Unmarshaller.

MappingJacksonHttpMessageConverterJSON的转换.

 

 

 

举个例子,具体实现

StringHttpMessageConverter

 

@RequestMapping(value="/string", method=RequestMethod.POST)

@ResponseBody

public String readString(@RequestBody String string) {

    return "Read string '" + string + "'";

}

SpringMVC进入readString方法前,会根据@RequestBody注解选择适当的HttpMessageConverter实现类来将请求参数解析到string变量中,具体来说是使用了StringHttpMessageConverter类,它的canRead()方法返回true,然后它的read()方法会从请求中读出请求参数,绑定到readString()方法的string变量中。

 

SpringMVC执行readString方法后,由于返回值标识了@ResponseBodySpringMVC将使用StringHttpMessageConverterwrite()方法,将结果作为String值写入响应报文,当然,此时canWrite()方法返回true

 

 

 

 

 

 

 

推荐使用

MappingJackson2HttpMessageConverter

 

一般加上对Java8时间的解析支持。

 

如何添加messageConvert

 

 

 

 

 

 

 

 

 

四、请求值和返回值增强 ——RequestBodyAdviceResponseBodyAdvice

 

ResponseBodyAdvicespring4.1的新特性,其作用是在响应体写出之前做一些处理;比如,修改返回值、对返回值统一加密等。

 

 

接口的定义

 

 

 

看下AbstractMessageConverterMethodProcessor

我们一般在方法writeWithMessageConverters之前调用


从这个可以看出,我们可以在使用这些HandlerMethodReturnValueHandler的时候,我们能对返回值返回之前做统一处理。

 

 

初始化

 

initControllerAdviceCache();

 

 

添加ResponseBodyAdvice

 

首先一个实现类,实现RequestBodyAdvice,然后在类上加上注解@ControllerAdvice,比如有些请求的参数需要做加密处理,可以在此将json串解密处理,再处理。

 

 

 

 

 

 

 

 

 

 

原文地址:https://www.cnblogs.com/wazqy/p/6907261.html