Outils pour utilisateurs

Outils du site


techniques:j2ee_spring_mvc

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:

  1. The request arrives at your server. Depending on the context path in the url the server decides to which application the request belongs.
  2. 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.
  3. The request is passed to the servlet filter chain which can modify or reject requests
  4. The servlet takes control over the request. In case of your Spring application the spring Dispatcherservlet receives the request. Now Spring kicks in
  5. The request is processed by mvc intercepters preHandle methods
  6. The request is mapped to a controller based on the url. The corresponding controller method will be called.
    1. 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.
    2. Registered springs mvc interceptors can kick in again using the postHandle method (e.g. for modifying the model)
    3. 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)
    4. The view is rendered using the model data returned by your controller
    5. The response with the rendered view will be passed to mvc interceptors again (afterCompletion method)
    6. The response leaves the dispatcher servlet. Here ends spring land
    7. The response passes servlet filters again
    8. 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 :

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<XXX>(servletRequest) –> permet de retrouver <XXX>, qui est un des éléments suivants :
  1. le WebApplicationContext dans lequel est traité la requête
  2. le ThemeResolver
  3. 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 <contextClass>.

Remarque : <contextConfigLocation> 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 <context:component-scan base-package=“packageToControllers”/>

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 :

<sxh xml>

 <beans>
   <bean id="handlerMapping" class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
     <property name="interceptors">
       <bean class="example.MyInterceptor"/>
     </property>
   </bean>

</sxh> <beans>

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

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 :

 <beans ...>
 
   <context:component-scan base-package="org.example">
      <context:include-filter type="regex" expression=".*Stub.*Repository"/>
      <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Repository"/>
   </context:component-scan>
 
 </beans>

Scope

      @Scope(scopeName="")
      //ConfigurableBeanFactory.SCOPE_PROTOTYPE
      //ConfigurableBeanFactory.SCOPE_SINGLETON
      //WebApplicationContext.SCOPE_APPLICATION
      //WebApplicationContext.SCOPE_REQUEST
      //WebApplicationContext.SCOPE_SESSION
      
      ScopeMetadataResolver
      
techniques/j2ee_spring_mvc.txt · Dernière modification: 2018/02/11 09:19 (modification externe)