• 周六. 10 月 12th, 2024

5G编程聚合网

5G时代下一个聚合的编程学习网

热门标签

Interaction between dispatcher servlet and controller in spring MVC

King Wang

1 月 3, 2022

1. MVC framework

 Insert picture description here

1.1 FrontController: DispatcherServlet

FrontController Namely Spring Provided DispatcherServlet , and No Spring Provided @Controller,xml The configuration file needs to specify Tomcat Load this… First at startup Servlet Mapping path write /, Forward all requests

 <servlet>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--tomcat When it starts , Load this... First Servlet-->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>

DispatcherServlet It’s essentially a HttpServlet

 Insert picture description here

track HttpServlet.service() Method call chain
  • FrameworkServlet Inherited from the parent class HttpServlet.service,Spring The expansion realization of processRequest

    FrameworkServlet.processRequest,==Spring Will block all types of requests , Include HttpServlet There is no definition in ,== Keep tracking processRequest The implementation of the

     @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) {
    
    HttpMethod httpMethod = HttpMethod.resolve(request.getMethod());
    if (httpMethod == HttpMethod.PATCH || httpMethod == null) {
    
    processRequest(request, response);
    }
    else {
    
    super.service(request, response);
    }
    }
    
  • FrameworkServlet.processRequest Combined doService Logic

     protected final void processRequest(HttpServletRequest request, HttpServletResponse response) {
    
    try {
    
    doService(request, response);
    }
    // Leave it for later research 
    publishRequestHandledEvent(request, response, startTime, failureCause);
    }
    }
    
  • FrameworkServlet Abstract method of doService Is left to subclasses Must be realized , That is to say DispatcherServlet.doService()

    protected abstract void doService(HttpServletRequest request, HttpServletResponse response);
    
     /**
    * DispatcherServlet.doService()
    *
    */
    @Override
    protected void doService(HttpServletRequest request, HttpServletResponse response) {
    
    // Omit data preparation 
    try {
    
    doDispatch(request, response);
    }
    }
    
track FrameworkServlet.doPost() / doGet() …
  • FrameworkServlet.doGet/doPost/.. Use… Without exception processRequest The implementation of the , That is to say DispatcherServlet.doService

 Insert picture description here

To explore the FrameworkServlet.service() Template method implementation
  • super.service()

    Using the template design pattern ,Spring Compatible with PATCH The implementation of the , Give the rest to HttpServlet The template of service()

     @Override
    protected void service(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
    
    HttpMethod httpMethod = HttpMethod.resolve(request.getMethod());
    if (httpMethod == HttpMethod.PATCH || httpMethod == null) {
    
    processRequest(request, response);
    }
    else {
    
    super.service(request, response);
    }
    }
    
  • HttpServlet.service() Templates , No concrete implementation . because FrameworkServlet.doGet/doPost.. It’s all covered

    HttpServlet The implementation of the , One Get The request went through DispatcherServlet after , There are the following processes

    FrameworkServlet.service() -> super.service() -> FrameworkServlet.doGet()

    -> FrameworkServlet.processRequest() -> DispatcherServlet.doService

    -> DispatcherServlet.doDispatch()

     /**
    * super.service() Always call to HttpServlet Template method
    *
    */
    protected void service(HttpServletRequest req, HttpServletResponse resp) {
    
    String method = req.getMethod();
    if (method.equals(METHOD_GET)) {
    
    doGet(req, resp);
    } else if (method.equals(METHOD_HEAD)) {
    
    long lastModified = getLastModified(req);
    maybeSetLastModified(resp, lastModified);
    doHead(req, resp);
    } else if (method.equals(METHOD_POST)) {
    
    doPost(req, resp);
    } else if (method.equals(METHOD_PUT)) {
    
    doPut(req, resp);
    } else if (method.equals(METHOD_DELETE)) {
    
    doDelete(req, resp);
    } else if (method.equals(METHOD_OPTIONS)) {
    
    doOptions(req,resp);
    } else if (method.equals(METHOD_TRACE)) {
    
    doTrace(req,resp);
    }
    }
    

Summary

DispatcherServlet As MVC Front end controller in Architecture , It’s also the core controller , adopt HttpServlet.service() The template mode puts the request Forward to Spring ,DispatcherServlet.doService() Subsequent analysis ,

About DispatcherServlet Other parents of , The role of online collection :

  1. HttpServletBean, yes FrameworkServlet Parent class of

    Mainly do some initialization work , take web.xml The parameters configured in are set to Servlet in . such as servlet Child of the tag init-param Parameters configured in the tag .

  2. FrameworkServlet

    take Servlet And Spring Container context . In fact, initialization FrameworkServlet Properties of webApplicationContext, This property represents SpringMVC Context , It has a parent context ServletContext, Both web.xml Configured in ContextLoaderListener Listener initialized container context .

  3. DispatcherServlet ( It will be mentioned later )

    Initialize the implementation classes of each function . Like exception handling 、 The view 、 Request mapping processing, etc .
     Insert picture description here

2. MVC Interaction process

 Insert picture description here

2.1 Controller: DispatcherServlet.doService()

track DispatcherServlet.doDispatch()

doService() The internal call is doDispatch()

 protected void doDispatch(HttpServletRequest request, HttpServletResponse response) {

HttpServletRequest processedRequest = request;
// Determine handler for the current request.( track )
HandlerExecutionChain mappedHandler = getHandler(processedRequest)
// Determine handler adapter for the current request.( track )
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
// Actually invoke the handler.( track )
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
applyDefaultViewName(processedRequest, mv);
mappedHandler.applyPostHandle(processedRequest, response, mv);
}
track DispatcherServlet.getHandler()
 protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {

for (HandlerMapping hm : this.handlerMappings) {

HandlerExecutionChain handler = hm.getHandler(request);
if (handler != null) {

return handler;
}
}
return null;
}

Handler It’s based on HandlerMapping Acquired , Corresponding Controller Of @RequestMapping

track DispatcherServlet. getHandlerAdapter()
 protected HandlerAdapter getHandlerAdapter(Object handler) throws ServletException {

for (HandlerAdapter ha : this.handlerAdapters) {

if (ha.supports(handler)) {

return ha;
}
}
}
track HandlerAdapter.handle()
ModelAndView handle(HttpServletRequest request, HttpServletResponse response,
Object handler) throws Exception;

stay DispatcherServlet Find ModelAndView The return value of

track HandlerAdapter Implementation class SimpleControllerHandlerAdapter
 public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {

return ((Controller) handler).handleRequest(request, response);
}
track Controller Realization
public interface Controller {

@Nullable
ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception;
}

Final eureka Controller return MV Code for , It also confirms DispatcherServlet.doDispatcher Will eventually return to Controller Made up of ModelAndView

2.2 Model And View

Different view parsers decide how to handle parsing View name , therefore SpringMVC You need to configure the view parser

public interface ViewResolver {

@Nullable
View resolveViewName(String viewName, Locale locale) throws Exception;
}

3. summary

DispatcherServlet Will be looking for HandlerMapping and HandlerMapping , When you parse a view, you use ViewResolver

If manual integration SSM,SpringMVC You need to manually inject these three bean. It is worth mentioning that ,XML Configure if annotation support is enabled ,HandlerMapping and HandlerMapping It also loads . See the figure below for details

 Insert picture description here

发表回复