Lien : https://docs.spring.io/spring/docs/3.0.0.M4/reference/html/ch15s02.html Spring mvc : dispatches requests to controllers and offers other functionality that facilitates the development of web applications. Spring's __DispatcherServlet__ however, does more than just that. It is completely integrated with the Spring IoC container and as such allows you to use every other feature that Spring has. ===== Enchainement général du traitement d'une requête ===== When sending a request to your application the following happens: - The request arrives at your server. Depending on the __context path__ in the url the server decides to which application the request belongs. - Depending on the url and the __servlet mapping__ in the web.xml file of your application the server knows which servlet should handle the request. - The request is passed to the __servlet filter chain__ which can modify or reject requests - __The servlet takes control over the request. In case of your Spring application the spring Dispatcherservlet receives the request. Now Spring kicks in__ - The request is processed by mvc intercepters preHandle methods - The request is mapped to a controller based on the url. The corresponding __controller__ method will be called. - Your controller is processing the request. Many different responses can be returned in controllers (jsp, pdf, json, redirects, etc.). For now i assume you want to render a simple jsp view. Result of the controller are two things: a model and a view. __The model is a map that contains the data you want to access later in your view__. __The view at this stage is most of the time a simple string containing a view name.__ - Registered springs mvc interceptors can kick in again using the postHandle method (e.g. for modifying the model) - The 'view' result of your controller is resolved to a real View using a ViewResolver. Depending on the ViewResolver the result can be jsp page, a tiles view, a thymeleaf template or many other 'Views'. In your case the ViewResolver resolves a view name (e.g. 'myPage') to a jsp file (e.g. /WEB-INF/jsp/myPage.jsp) - The view is rendered using the model data returned by your controller - The response with the rendered view will be passed to mvc interceptors again (afterCompletion method) - The response leaves the dispatcher servlet. __Here ends spring land__ - The response passes servlet filters again - The response is send back to client ===== WebApplicationContext, WebApplicationContext(s) et ServletContext ===== WebApplicationContext est un ApplicationContext. Elle permet d'accéder aux beans spring créés. ==== ApplicationContext instances in Spring can be scoped ==== * Chaque DispatcherServlet dispose de son propre WebApplicationContext, qui hérite de tous les bean du WebApplicationContext racine de l'application. * On peut redéfinir les bean de l'appContext root dans l'appContext des servlets, via par exemple les fichiers __resources/WEB-INF/[servlet-name]-servlet.xml__ 2 articles très intéressants à ce sujet : * [[https://stackoverflow.com/questions/35258758/getservletconfigclasses-vs-getrootconfigclasses-when-extending-abstractannot ]] * https://stackoverflow.com/questions/44985831/autowire-in-a-java-servlet-using-abstractannotationconfigdispatcherservletiniti * https://stackoverflow.com/questions/32091013/spring-annotation-configuration-replacement-for-web-xml-configuration __Par contre, on n'a qu'1 servletContext par application web (comprendre war).__ ==> on peut faire webApplicationContext.getServletContext() pour le récupérer. webApplicationContext.getServletContext().getContextPath() : est bien le application context path ==== Que contiennent les WebApplicationContext ==== Des bean spring en plus que la servlet va utiliser pour traiter ses requêtes : * Controllers * HandlerMappings : preprocesseurs et postprocesseurs * ViewResolvers : A partir du nom d'une vue, la retrouve et retourne un objet (genre ModelAndView ou View) * LocalResolvers : permet de détecter la langue du client http Particularité/ajout de WebApplicationContext par rapport au ApplicationContext : * ThemeResolver : des thèmes pour par exemple disposer de layout différents * Multipart file resolvers : ca c'est pour des requete POST ou PUT issue de formulaire disposant de pièce jointe * Handler Exception Resolvers : pour mapper des exceptions à des vues en sortie * connait sa servlet est associée (lien vers servletContext) * RequestContextUtils.get(servletRequest) --> permet de retrouver , qui est un des éléments suivants : - le WebApplicationContext dans lequel est traité la requête - le ThemeResolver - le LocalResolver ==== WebApplicationContext par défault pour les DispatcherServlet mais ==== On peut changer la classe de contexte dans les paramètre d'initialisation (dans le web.xml) : avec la balise . Remarque : permet de changer le path du xml définissant les beans spécifiques pour cette servlet : [servlet-name]-servlet.xml ===== Controllers ===== Mettre ça dans l'appContext.xml ModelAndView, ModelMap, Model @Controller @RequestMapping @PathVariable @RequestParam("a_GET_param") @ResponseBody @SessionAttributes et @ModelAttribute : pour une variable dans une session @CookieValue : bound to http header cookie attribute of payload @RequestHeader Exemple : @RequestMapping(value="/owners/{ownerId}/pets/{petId}", method=RequestMethod.GET) ===== Handler Mappings ===== voir doc : Avec les versions de spring >=2.5, les méthodes annotées @RequestMapping sont scannées par le bean DefaultAnnotationHandlerMapping, qui instancié par défaut. Cela dit, on peut redéfinir cette instance. Exemple : On peut aussi instancier d'autre HandlerMapping, comme SimpleUrlHandlerMapping (voir doc), par exemple dans le servlet15-servlet.xml On peut par contre redéfinir ses propriétés : * interceptors : classes qui doivent implémenter HandlerInterceptor : before() : executée avant l'exécution du HandlerMapping after() : executée après l'exécution du HandlerMapping complete() : executée après l'exécution de compète de la requête preHandle(..) : retourne true ou false pour stopper la chaine à venir des HandlerMappings (par exemple ) quand elle retourne false, alors ca signifie que ce HandlerMapping a bien pris en compte et traité la requête donc les autres HandlerMapping ne seront pas exécuté Exemple concret dans la doc : https://docs.spring.io/spring/docs/3.0.0.M4/reference/html/ch15s04.html * defaultHandler : quand aucun autre mapping n'a pu être fait ===== View Resolvers ===== Spring met à disposition pleins de type de view resolver : * JSP * Velocity templates * XSLT views * tymeleaf ==== Fonctionnement ==== Le view resolver est donc appelé par un HanderMapping. Dans tous les cas, un view resolver prend en entrée un ModelAndView, puis tenter de retrouver la fameuse vue. Si il la trouve il la retourne (arrête la chaine de résolution, voir en dessous), sinon il retournera null. Dans le cas des jsp (InternalResourceViewResolver) il cherche la vue à partir d'un RequestDispatcher (en type FORWARD (RequestDispatcher.forward(...)) retourne une InternalView si il la trouve. Hors il en trouve une forcément une, sinon il retourne la une sorte de view "Error". ==== Chaine de viewResolvers dans une DispatcherServlet ==== Il est possible de chainer plusieurs views resolver. __Il faut alors définir un ordre dans lequel il doivent chercher__ Dans tous les cas, si aucune vue n'a été trouvée, alors spring lance une exception. ==== By passer les ViewResolvers ==== return new ModelAndView("forward:/mesPagesJsps/log4jAdmin.jsp"); Ca n'utilisera pas l'InternalResourcesViewResolver, mais ça retournera bien une InternalResourcesView et ça forwardera. ===== Forward, sendRedirect and Include ===== http://programmergate.com/forward-vs-sendredirect-vs-include/ === Forward === Le forward est censé faire une recherche interne d'une resource sans que le navigateur client ne soit au courant. request.getRequestDispatcher("HomeServlet").forward(request, response); === SendRedirect === When calling this method, the server sends back a HTTP status code of 302 (temporary redirect) which causes the web browser to issue a brand new HTTP GET request for the content at the redirected location. response.sendRedirect( "home.jsp?name=Hussein Terek" ); === Include === Permet, au cours du traitement de la requete, d'embarquer une vue ou autre chose dans la réponse, puis de continuer le traitement de la réponse la où on en était. request.getRequestDispatcher("home.jsp").include(request, response); ===== Spring scanning de composant ===== ==== @Component, @Repository, @Service, @Controller ==== https://docs.spring.io/spring/docs/3.0.0.M4/reference/html/ch03s10.html#beans-scanning-filters By default, classes annotated with @Component, @Repository, @Service, @Controller, or a custom annotation that itself is annotated with @Component are the only detected candidate components. ==== Qualification des beans ==== @Qualifier (de spring et de javax) @Genre @Offline ==== Filtrer ==== On peut filtrer pour ne pas créer certains composants Exemple : ==== Scope ==== @Scope(scopeName="") //ConfigurableBeanFactory.SCOPE_PROTOTYPE //ConfigurableBeanFactory.SCOPE_SINGLETON //WebApplicationContext.SCOPE_APPLICATION //WebApplicationContext.SCOPE_REQUEST //WebApplicationContext.SCOPE_SESSION ScopeMetadataResolver