O controlador front-end é a parte mais central de toda a estrutura do MVC. É usado principalmente para interceptar solicitações externas que atendem aos requisitos e distribuem as solicitações a diferentes controladores para processamento. De acordo com os resultados do processamento do controlador, ele gera respostas correspondentes e as envia ao cliente. O controlador front-end pode ser implementado usando o filtro (STRUTS2 usa esse método) ou servlet (Spring MVC Framework).
Como pré-controlador, o DispatcheserServlet é a entrada do servidor da Web e é a classe mais importante do Spring MVC. Durante seu ciclo de vida, o entendimento do servidor da Web pode ser aprofundado.
Ciclo de vida do servlet
Primeiro, lembre -se do ciclo de vida do servlet:
O ciclo de vida do servlet é dividido em três estágios: [Explicação detalhada do ciclo de vida do servlet e do princípio de trabalho]
1. O método init () é chamado init () na fase de inicialização. Depois que o servlet é carregado, o contêiner do servlet cria uma instância do servlet e chama o método init () do servlet para inicialização. O método init () é chamado apenas uma vez durante toda a vida de um servlet.
2. Ligue para o método Service () em resposta ao estágio de solicitação do cliente
3. Método de destruição de chamada () no estágio de rescisão
Fase de inicialização do servlet
Nos momentos seguintes, o contêiner de servlet carrega o servlet:
1. Quando o contêiner do servlet inicia, alguns servlets são carregados automaticamente. Para implementá -lo, você só precisa adicionar o seguinte código entre <Verlet> </servlet> no arquivo web.xml:
<adounon-startup> 1 </farlon-startup>
2. Depois que o contêiner do servlet é iniciado, o cliente envia uma solicitação para o servlet pela primeira vez
3. Depois que o arquivo da classe servlet é atualizado, recarregue o servlet
A estrutura do despachoervlet
Depois de revisar o conhecimento acima, vamos dar uma olhada na estrutura do DispatcheserServlet:
DispatcheserServlet herda da classe abstrata: estrutura de serviço, herda indiretamente httpServlet (herda de serviço da estrutura de HttpServletBean e httpServletBean herda da httpServlet)
Inicialização do servlet
INITSTRAGEM INITSTRATEGRAS DE APPLICAÇÃO DE APPLICAÇÃO) {initmultipartResolver (contexto); // upload de arquivo e análise. Se o tipo de solicitação for multipart, o upload de arquivo e analise através do multipartresolver; initlocaleresolver (contexto); // Localização Parsing initthemeResolver (contexto); // tema analisando inithandlermAppings (contexto); // mapeamento de solicitações ao processador InandleRadapters (contexto); // mapeando vários tipos de processadores inithandleRexceptionResolvers (contexto); // suporta vários tipos de processadores através do HandlerRatapter; // Se uma exceção for encontrada durante a execução, ela será entregue à HandlerexceptionResolver para analisar initRequestToviewNeRetRanslator (contexto); // Analisar diretamente a solicitação para o nome initViewResolvers (contexto); // Resolva o nome da visualização lógica para a visualização específica através do ViewResolver para implementar o initflashmapManager (contexto); // Gerenciador de mapa flash}Como lidar com solicitações:
O método de serviço do servlet lida com solicitações HTTP.
Estrutura de estrutura.java define o serviço e destrua os métodos do servlet, como mostrado abaixo:
/** * Substitua a implementação da classe pai para interceptar as solicitações do patch *. */ @Override Protected Void Service (solicitação httpServletRequest, httpServletResponse resposta) lança servletexception, ioexception {string method = request.getMethod (); if (métod.equalsignorecase (requestmethod.patch.name ())) {processEquest (solicitação, resposta); } else {super.service (solicitação, resposta); }}Sabemos que existem sete tipos de tipos de solicitação HTTP (mais uma opção), que são definidos da seguinte forma:
Public Enum RequestMethod {Get, Head, Post, Put, Patch, Excluir, Opções, Trace} O Serviço () do FrameworkServlet lida com diferentes solicitações. Usamos postagens comuns para ilustrar:
/*** Processe esta solicitação, publicando um evento, independentemente do resultado. * <p> O manuseio real de eventos é executado pelo método de modelo abstrato * {@link #Doservice}. */ Protected Final void ProcessRequest (solicitação httpServletRequest, httpServletResponse resposta) lança servletexception, ioexception {long starttime = system.currenttimemillis (); Arremesso de falhas de arremesso = nulo; LocalEContext anteriorlocalEcontext = localEContextholder.getLocaleContext (); LocalEContext localEContext = BuildLocaleContext (solicitação); RequestAttributes anterioresAttributes = requestContextholder.getRequestAttributes (); ServletRequestattributes requestAttributes = BuildReQuestAttributes (solicitação, resposta, anteriores); WebAsyncManager asyncManager = webAsyncutils.getasyncmanager (request); asyncmanager.RegisterCallableIntercept (estrutura initContextholders (solicitação, localContext, requestAttributes); tente {Doservice (solicitação, resposta); } catch (servleTexception ex) {FailUrecause = Ex; jogar ex; } catch (ioexception ex) {FailUrecause = Ex; jogar ex; } catch (throwable ex) {FailUrecause = Ex; lançar uma nova NestervErvEtexception ("Solicitar o processamento da falha", ex); } finalmente {resetContextholders (request, anteriorlocaleContext, anteriorttributes); if (requestAttributes! = null) {requestAttributes.requestCompleted (); } if (logger.isdebugenabled ()) {if (FailUrecause! = NULL) {this.logger.debug ("não conseguiu concluir a solicitação", Failurecause); } else {if (asyncManager.iscoCurrentHandlingStard ()) {Logger.debug ("Deixando a resposta aberta para processamento simultâneo"); } else {this.logger.debug ("solicitação concluída com êxito"); }}} publishRequestHandleDevent (request, starttime, falherecause); }} O ScrameworkServlet define abstrivelmente o fluxo de processamento e o deixa nas subclasses para implementar o método e conclui o processamento específico de solicitação.
/** * As subclasses devem implementar esse método para fazer o trabalho de manipulação de solicitações, * recebendo um retorno de chamada centralizado para obter, postar, colocar e excluir. * <p> O contrato é essencialmente o mesmo que o para os métodos de dopot} {@code Doget} ou {@code dopost} do httpServlet. * <p> Esta classe intercepta chamadas para garantir que o manuseio de exceções e * a publicação de eventos ocorram. * @param solicitação atual solicitação http * @param Resposta atual HTTP Response * @Throws Exceção em caso de qualquer tipo de falha de processamento * @see javax.servlet.http.httpServlet#doget * @see javax.servlet.htp.httpslet#doPost */ Protected abstrata. Resposta HttpServLetResponse) lança exceção;A implementação específica é a seguinte:
/** * expõe os atributos de solicitação específica do DispatcheserServlet e delega para {@link #Dodispatch} * para a despacho real. */ @Override Protected Doservice de vazio (solicitação httpServletRequest, httpServletResponse resposta) lança exceção {if (logger.isdebugenabled ()) {string retomado = webAsyncutils.getasyncmanager (request) .HascoSCurrentRerentSult ()? "retomado": ""; Logger.debug ("DispatcheserServlet com o nome '" + getServletName () + "'" + retomado + "processamento" + request.getMethod () + "solicitação para [" + getRequesturi (request) + "]"); } // Mantenha um instantâneo dos atributos de solicitação em caso de inclusão, // para poder restaurar os atributos originais após a inclusão. Mapa <string, object> atributessnapshot = null; if (webutils.isincludeReQuest (request)) {atributessnapshot = new hashmap <string, object> (); Enumeração <?> AttNames = request.getAttributenames (); while (attNames.hasMoreElements ()) {string attName = (string) attNames.nextElement (); if (this.cleanUPAfterinclude || attName.Startswith ("org.springframework.web.servlet")) {attribessnapshot.put (attName, request.getAttribute (attName)); }}}} // disponibiliza objetos da estrutura para manipuladores e visualizam objetos. request.setAttribute (web_application_context_attribute, getWebApplicationContext ()); request.setAttribute (loce_resolver_attribute, this.localeresolver); request.setAttribute (tema_resolver_attribute, this.TheMeResolver); request.setAttribute (tema_source_attribute, getThemeSource ()); FlashMap inputFlashMap = this.flashmapManager.retrieveandupdate (solicitação, resposta); if (inputflashmap! = null) {request.setAttribute (input_flash_map_attribute, collection.unmodifiablemap (inputflashmap)); } request.setAttribute (output_flash_map_attribute, new flashMap ()); request.setAttribute (flash_map_manager_attribute, this.flashmapmanager); tente {dodispatch (solicitação, resposta); } finalmente {if (webasyncutils.getasyncmanager (request) .iscoCurrentHandlingStard ()) {return; } // Restaure o instantâneo do atributo original, no caso de uma inclusão. if (attributessNapShot! = null) {restaurEattributesAfterinclude (solicitação, atributessnapshot); }}}O destaque, como implementação do distribuidor de solicitação:
Funções: 1. Distribua a solicitação ao manipulador (obtenha o relacionamento de mapeamento de servlet na ordem da configuração); 2. Consulta o primeiro manipulador que pode ser processado com base nos manipuladores instalados pelo servlet; 3. O manipulador desencadeia o processamento da solicitação
/*** Processe o despacho real para o manipulador. * <p> O manipulador será obtido aplicando as mangas do servlet em ordem. * O HandlerRatapter será obtido consultando o manipulador instalado do servlet * para encontrar o primeiro que suporta a classe Handler. * <p> Todos os métodos HTTP são tratados por esse método. Cabe a Handleratapters ou manipuladores * * decidir quais métodos são aceitáveis. * @param solicitação atual solicitação http * @param Resposta atual HTTP Resposta * @THOWSOWS Exceção no caso de qualquer tipo de falha de processamento */ void protegido Dodispatch (solicitação httpSertRequest, httpServletResponse) lança exceção {httpSertleTequest ProcessEdReQuest = request; HandlerexecutionChain mapedHandler = null; booleano multrotarTeCestarsed = false; WebAsyncManager asyncManager = webAsyncutils.getasyncmanager (request); tente {modelAndView mv = null; Exceção DispatchException = NULL; tente {processedRequest = checkMultipart (request); multipartreCestarsed = (ProcessEdRequest! = solicitação); // Determine o manipulador para a solicitação atual. MappedHandler = Gethandler (ProcessEdRequest); if (mapedHandler == null || mapedhandler.gethandler () == null) {nohandlerfound (processedRequest, resposta); retornar; } // Determine o adaptador de manipulador para a solicitação atual. Handleratapter HA = Gethandleratapter (MappedHandler.gethandler ()); // Processa o cabeçalho último-modificado, se suportado pelo manipulador. String métod = request.getMethod (); boolean isget = "get" .equals (método); if (isGet || "head" .equals (método)) {long lastModified = ha.getLastModified (request, mapedhandler.gethandler ()); if (logger.isdebugenabled ()) {Logger.debug ("Valor Último modificado para [" + getRequesturi (request) + "] é:" + LastModified); } if (new servletwebrequest (solicitação, resposta) .checkNotModified (LastModified) && isGet) {return; }} if (new servletwebrequest (solicitação, resposta) .CheckNotModified (LastModified) && isGet) {return; }} if (! mapedhandler.applyprehrendle (processedRequest, resposta)) {return; } tente {// Na verdade, invoca o manipulador. mv = ha.handle (processenEquest, resposta, mapedhandler.gethandler ()); } finalmente {if (asyncmanager.iscoCurrentHandlingStarted ()) {return; }} ApplyDefaultViewName (request, MV); MAPPEDHANDLER.APPLYPOSTHandle (ProcessEdRequest, Response, MV); } catch (Exceção ex) {DispatchException = Ex; } ProcessDispatchResult (ProcessEdRequest, Response, MappedHandler, MV, DispatchException); } catch (Exceção ex) {triggerfterCompletion (ProcessEdRequest, Response, MappedHandler, Ex); } catch (erro err) {triggerfterCompletionwithError (ProcessEdRequest, Response, MappedHandler, ERR); } finalmente {if (asyncmanager.iscoCurrentHandlingStarted ()) {// em vez de posthandle e pós -concorrência mapedhandler.applyafterconcurrenthandlingstarted (processedRequest, resposta); retornar; } // Limpe os recursos usados por uma solicitação de multipart. if (multipartreCestarsed) {CleanUpMultipart (ProcessEdRequest); }}}destruição de servlet
/*** Feche o WebApplicationContext deste servlet. * @see org.springframework.context.configurableApplicationContext#Close () */ @Override public void Destroy () {getServletContext (). LOG ("Destruindo Spring FrameworkServlet '" + getServletName () + "'"); // Ligue apenas para fechar () no webApplicationContext se gerenciado localmente ... if (this.webApplicationContext Instância do configurableApplicationContext &&! This.webApplicationContextInject) {((configurableApplicationContext) this.webApplication). }}resumo:
Devido às limitações do capítulo, este artigo apresenta apenas o processo de processamento de solicitação e não conduz uma análise aprofundada do código. O próximo artigo começará com os detalhes e analisará a beleza do código da primavera.
O exposto acima é todo o conteúdo deste artigo. Espero que seja útil para o aprendizado de todos e espero que todos apoiem mais o wulin.com.