开发者

SpringMVC的处理器适配器-HandlerAdapter的用法及说明

开发者 https://www.devze.com 2023-12-28 10:25 出处:网络 作者: huangyaa729
目录SpringMVC处理器适配器HandlerAdapter用法HandlerAdapter目前最常见的主要为浅谈HandlerAdapter总结SpringMVC处理器适配器HandlerAdapter用法
目录
  • SpringMVC处理器适配器HandlerAdapter用法
    • HandlerAdapter目前最常见的主要为
  • 浅谈HandlerAdapter
    • 总结

      SpringMVC处理器适配器HandlerAdapter用法

      如题:

      今天看spring源码解析这本书时,看到了这个地方,对于不同HandlerAdapter的使用场景有的困惑,主要还是没见过,因为大多数面向的Controller类型的HandlerAdapter;

      HandlerAdapter目前最常见的主要为

      1、SimpleContrjsollerHandlerAdapter、HttpRequestHandlerAdapter 、AnnotationMethodHandlerAdapter (已过时),这三个是默认的;如果没有指明新的适配器时,会从这三个中间选择;

      2、SimpleServletHandlerAdapter目前很少用到,也不是默认的适配器;

      3、RequestMappingHandlerAdapter这个应该是目前springMVC主要采用的,针对方法级的映射匹配处理。

      由HandlerAdapter的实现类可知:映射匹配的处理器handler包括三个类型Controller、HttpRequestHandler、Servlet,但后两个的应用场景与使用方式我却没有见到过,经过一番查找,特做一个总结以供以后参考:

      1、SimpleControllerHandlerAdapter主要是针对实现Controller接口的handler进行适配,配置方式在书中可见;

      2、SimpleServletHandlerAdapter主要是针对实现Servlet接口的handler进行适配,配置方式跟普通的Controller类似,如下所示:

      spring配置文件中bean的配置如下:

      /** 采用BeanNameUrlHandlerMapping类进行路径映射匹配**/
      <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping" />
       <bean name="/demo.do" class="com.demo.DemoServlet"/>  

      对应的Bean实现类为

      public class DemoServlet extends HttpServlet{  
      .......
      }

      3、HttpRequestHandlerAdapter 主要是针对实现HttpRequestHandler接口的handler进行适配;

      HTTP请求处理器适配器仅仅支持对HTTP请求处理器的适配。它简单的将HTTP请求对象和响应对象传递给HTTP请求处理器的实现,它并不需要返回值。它主要应用在基于HTTP的远程调用的实现上。

      配置应该与上述相同,从SpringMvc自带的实现类来说,主要用于转发或者静态资源的加载,对应的实现类为DefaultServletHttpRequestHandler和ResourceHttpRequestHandler

      浅谈HandlerAdapter

      HandlerAdapter顾名思义就是一个适配器,(肯定也采用了适配器模式这里不做过多的解释),那么它的主要作用是什么呢?

      HandlerMapping存储了所有都请求映射,请求过来找到相应的请求映射后,返回给我们一个Handler

      看这里的代码:

      @Nullable
      protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
          if (this.handlerMappings != null) {
              Iterator var2 = this.handlerMappings.iterator();
      
              while(var2.hasNext()) {
                  HandlerMapping mapping = (HandlerMapping)var2.next();
                  HandlerExecutionChain handler = mapping.getHandler(request);
                  if (handler != null) {
                      return handler;
                  }
              }
          }
      
          return null;
      }

      这里是DispacherServlet的核心控制方法。

      protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
              HttpServletRequest processedRequest = request;
              HandlerExecutionChain mappedHandler = null;
              boolean multipartRequestParsed = false;
              WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
       
              try {
                  try {
                      ModelAndView mv = null;
                      Object dispatchException = null;
       
                      try {
                          processedRequest = this.checkMultipart(request);
                          multipartRequestParsed = processedRequest != request;
                          mappedHandler = this.getHandler(processedRequest);
                          if (mappedHandler == null) {
                              this.noHandlerFound(processedRequest, response);
                              return;
                          }
       
                          HandlerAdapter ha = this.getHandlerAdapter(mappedHandler.getHandler());
                          String method = request.getMethod();
                          boolean isGet = HttpMethod.GET.matches(method);
                          if (isGet || HttpMethod.HEAD.matches(method)) {
                              long lastModified = ha.getLastModified(request, mappedHandler.getHandler());
                              if ((new ServletWebRequest(request, response)).checkNotModified(lastModified) &am编程p;& isGet) {
                                  return;
                              }
                          }
       
                          if (!mappedHandler.applyPreHandle(processedRequest, response)) {
                              return;
                          }
       
                          mv = ha.handle(processedRequeandroidst, response, mappedHandler.getHandler());
                          if (asyncManager.isConcurrentHandlingStarted()) {
                              return;
                          }
       
                          this.applyDefaultViewName(processedRequest, mv);
                          mappedHandler.applyPostHandle(processedRequest, response, mv);
                      } catch (Exception var20) {
                          dispatchException = var20;
                      } catch (Throwable var21) {
                          dispatchException = new NestedServletException("Handler dispatch failed", var21);
                      }
       
                      this.processDispatchResult(processedRequest, response, mappedHandler, mv, (Exception)dispatchException);
                  } catch (Exception var22) {
                      this.triggerAfterCompletion(processedRequest, response, mappedHandler, var22);
                  } catch (Throwable var23) {
                      this.triggerAfterCompletion(processedRequest, response, mappedHandler, new NestedServletException("Handler processing failed", var23));
                  }
       
              } finally {
                  if (asyncManager.isConcurrentHandlingStarted()) {
                      if (mappedHandler != null) {
                          mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);
                      }
                  } else if (multipartRequestParsed) {
                      this.cleanupMultipart(processedRequest);
              python    }
       
              }
          }

      我们拿到Handler之后呢?

      接着代码往下走我们可以看到这样一行代码

      HandlerAdapter ha = this.getHandlerAdapter(mappedHandler.getHandler());

      这一步就是讲我们的Handler进行一个HandlerAdapter的适配解析,我们继续代码跟进

      public interface HandlerAdapter {
          //如果当前支持当前handler就执行handler方法
          boolean supports(Object handler);
       
          @Nullable
          ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception;
       
          /** @deprecated */
          @Deprecated
          long getLastModified(HttpServletRequest request, Object handler);
      }

      我们知道它采用的适配器模式

      protected HandlerAdapter getHandlerAdapter(Object handler) throws ServletException {
          if (this.handlerAdapters != null) {
              Iterator var2 = this.handlerAdapters.iterator();
      
              while(var2.hasNext()) {
                  HandlerAdapter adapter = (HandlerAdapter)var2.next();
                  if (adapter.supports(handler)) {
                      return adapter;
                  }
              }
          }
      
          throw new ServletException("No adapter for handler [" + handler + "]: The DispatcherServlet configuration needs to include a HandlerAdapter that supports this handler");
      }

      DispacherServlet中这个方法,就是一个迭代器,给handler找一个适配器,那这一步到底是要做什么呢?

      SpringMVC的处理器适配器-HandlerAdapter的用法及说明

      在HandlerAdapter中有四个实现类,分别处理不同Handler我们看一下我们最常用的HttpRequestHandlerAdapter

      public boolean supports(Object handler) {
          return handler instanceof HttpRequestHandler;
      }

      里面就是去判断了,当前handler是不是HttpRequestHandler类型,其实在我们确认号类型的时候,handler经过RequestMappingHandlerMapping​,返回的就已经是这个类型的了。

      找到适配器之后啊,就是开始参数解析了

      String method = request.getMethod();
      boolean isGet = HttpMethod.GET.matches(method);
      if (isGet || HttpMethod.HEAD.matches(method)) {
          long lastModified = ha.getLastModified(request, mappedHandler.getHandler());
          if ((new ServletWebRequest(request, response)).checkNotModified(lastModified) && isGet) {
              return;
          }
      }

      核心在这python里,利用的HandlerAdapter,也就是刚才找到的适配器,和目标方法传进去,执行目标方法。​

      执行完上面代码,就是判断了一下是不是get请求,HEAD这个不是由我们 去处理的。

      mv = ha.handle(processedRequest, response, mappedHandler.getHandler());

      上面这行代码去执行的目标方法。

      到这里基本是完成了HandlerAdapter的一个准备工作,找到适配的HandlerAdapter之后,还要进行相应的参数解析啊。

      总结

      以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程客栈(www.devze.com)。

      0

      精彩评论

      暂无评论...
      验证码 换一张
      取 消

      关注公众号