Maison  >  Article  >  Java  >  Apprentissage et construction approfondis Spring+SpringMVC+MyBatis (17) - Intercepteur SpringMVC

Apprentissage et construction approfondis Spring+SpringMVC+MyBatis (17) - Intercepteur SpringMVC

PHP中文网
PHP中文网original
2017-07-03 17:30:261404parcourir

Veuillez indiquer la source lors de la réimpression :

Comme mentionné précédemment : Spring+SpringMVC+MyBatis apprentissage et construction approfondis (16) - Développement d'annotations SpringMVC (avancé)

1.Définition de l'intercepteur

L'intercepteur de processeur de Spring Web MVC est similaire au filtre du développement de servlets, qui est utilisé pour pré-traiter et post-traiter le processeur.

Définissez un intercepteur et implémentez l'interface HandlerInterceptor. Trois méthodes sont proposées dans l'interface.

<span style="color: #0000ff">package</span><span style="color: #000000"> joanna.yan.ssm.interceptor;

</span><span style="color: #0000ff">import</span><span style="color: #000000"> javax.servlet.http.HttpServletRequest;
</span><span style="color: #0000ff">import</span><span style="color: #000000"> javax.servlet.http.HttpServletResponse;
</span><span style="color: #0000ff">import</span><span style="color: #000000"> org.springframework.web.servlet.HandlerInterceptor;
</span><span style="color: #0000ff">import</span><span style="color: #000000"> org.springframework.web.servlet.ModelAndView;

</span><span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> HandlerInterceptor1 <span style="color: #0000ff">implements</span><span style="color: #000000"> HandlerInterceptor{

    </span><span style="color: #008000">//</span><span style="color: #008000">执行Handler完成执行此方法
    </span><span style="color: #008000">//</span><span style="color: #008000">应用场景:统一异常处理,统一日志处理</span>
<span style="color: #000000">    @Override
    </span><span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span><span style="color: #000000"> afterCompletion(HttpServletRequest request,
            HttpServletResponse response, Object handler, Exception ex)
            </span><span style="color: #0000ff">throws</span><span style="color: #000000"> Exception {
        System.out.println(</span>"HandlerInterceptor1......afterCompletion"<span style="color: #000000">);
    }

    </span><span style="color: #008000">//</span><span style="color: #008000">进入Handler方法之后,返回modelAndView之前执行
    </span><span style="color: #008000">//</span><span style="color: #008000">应用场景从modelAndView出发:将公用的模型数据(比如菜单导航)在这里传到视图,也可以在这里同意指定视图</span>
<span style="color: #000000">    @Override
    </span><span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span><span style="color: #000000"> postHandle(HttpServletRequest request, HttpServletResponse response,
            Object handler, ModelAndView modelAndView) </span><span style="color: #0000ff">throws</span><span style="color: #000000"> Exception {
        System.out.println(</span>"HandlerInterceptor1......postHandle"<span style="color: #000000">);
    }

    </span><span style="color: #008000">//</span><span style="color: #008000">进入Handler方法之前执行
    </span><span style="color: #008000">//</span><span style="color: #008000">用于身份认证、身份授权
    </span><span style="color: #008000">//</span><span style="color: #008000">比如身份认证,如果认证不通过表示当前用户没有登录,需要此方法拦截不再向下执行。</span>
<span style="color: #000000">    @Override
    </span><span style="color: #0000ff">public</span> <span style="color: #0000ff">boolean</span><span style="color: #000000"> preHandle(HttpServletRequest request, HttpServletResponse response,
            Object handler) </span><span style="color: #0000ff">throws</span><span style="color: #000000"> Exception {
        System.out.println(</span>"HandlerInterceptor1......preHandle"<span style="color: #000000">);
        </span><span style="color: #008000">//</span><span style="color: #008000">return false表示拦截,不向下执行
        </span><span style="color: #008000">//</span><span style="color: #008000">return true表示放行</span>
        <span style="color: #0000ff">return</span> <span style="color: #0000ff">true</span><span style="color: #000000">;
    }

}</span>

2. Configuration de l'intercepteur

Il y a une grande chaîne d'intercepteur dans les entretoises. C'est une chose courante. Vous pouvez l'ajouter à n'importe quel lien d'action pour l'intercepter. Mais l'intercepteur de Spring n'est pas global.

2.1 Configuration des intercepteurs pour un certain mappage

L'intercepteur springmvc définit les paramètres d'interception pour HandlerMapping. Si l'interception est définie dans un HandlerMapping, le gestionnaire qui est mappé avec succès par HandlerMapping finira par utiliser l'intercepteur.

<span style="color: #0000ff"><</span><span style="color: #800000">bean
    </span><span style="color: #ff0000">class</span><span style="color: #0000ff">="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"</span><span style="color: #0000ff">></span>
    <span style="color: #0000ff"><</span><span style="color: #800000">property </span><span style="color: #ff0000">name</span><span style="color: #0000ff">="interceptors"</span><span style="color: #0000ff">></span>
        <span style="color: #0000ff"><</span><span style="color: #800000">list</span><span style="color: #0000ff">></span>
            <span style="color: #0000ff"><</span><span style="color: #800000">ref </span><span style="color: #ff0000">bean</span><span style="color: #0000ff">="handlerInterceptor1"</span><span style="color: #0000ff">/></span>
            <span style="color: #0000ff"><</span><span style="color: #800000">ref </span><span style="color: #ff0000">bean</span><span style="color: #0000ff">="handlerInterceptor2"</span><span style="color: #0000ff">/></span>
        <span style="color: #0000ff"></</span><span style="color: #800000">list</span><span style="color: #0000ff">></span>
    <span style="color: #0000ff"></</span><span style="color: #800000">property</span><span style="color: #0000ff">></span>
<span style="color: #0000ff"></</span><span style="color: #800000">bean</span><span style="color: #0000ff">></span>
    <span style="color: #0000ff"><</span><span style="color: #800000">bean </span><span style="color: #ff0000">id</span><span style="color: #0000ff">="handlerInterceptor1"</span><span style="color: #ff0000"> class</span><span style="color: #0000ff">="joanna.yan.ssm.interceptor.HandlerInterceptor1"</span><span style="color: #0000ff">/></span>
    <span style="color: #0000ff"><</span><span style="color: #800000">bean </span><span style="color: #ff0000">id</span><span style="color: #0000ff">="handlerInterceptor2"</span><span style="color: #ff0000"> class</span><span style="color: #0000ff">="joanna.yan.ssm.interceptor.HandlerInterceptor2"</span><span style="color: #0000ff">/></span>

Généralement déconseillé.

2.2 Configurer les intercepteurs globaux pour tous les mappages

springmvc peut configurer des intercepteurs de type global, et le framework springmvc injecte les intercepteurs de type global configurés dans chaque HandlerMapping.

    <span style="color: #008000"><!--</span><span style="color: #008000">拦截器 </span><span style="color: #008000">--></span>
    <span style="color: #0000ff"><</span><span style="color: #800000">mvc:interceptors</span><span style="color: #0000ff">></span>
        <span style="color: #008000"><!--</span><span style="color: #008000">多个拦截器,顺序执行 </span><span style="color: #008000">--></span>
        <span style="color: #0000ff"><</span><span style="color: #800000">mvc:interceptor</span><span style="color: #0000ff">></span>
            <span style="color: #008000"><!--</span><span style="color: #008000"> /**表示所有url包括子url路径 </span><span style="color: #008000">--></span>
            <span style="color: #0000ff"><</span><span style="color: #800000">mvc:mapping </span><span style="color: #ff0000">path</span><span style="color: #0000ff">="/**"</span><span style="color: #0000ff">/></span>
            <span style="color: #0000ff"><</span><span style="color: #800000">bean </span><span style="color: #ff0000">class</span><span style="color: #0000ff">="joanna.yan.ssm.interceptor.HandlerInterceptor1"</span><span style="color: #0000ff">></</span><span style="color: #800000">bean</span><span style="color: #0000ff">></span>
        <span style="color: #0000ff"></</span><span style="color: #800000">mvc:interceptor</span><span style="color: #0000ff">></span>
        <span style="color: #0000ff"><</span><span style="color: #800000">mvc:interceptor</span><span style="color: #0000ff">></span>
            <span style="color: #0000ff"><</span><span style="color: #800000">mvc:mapping </span><span style="color: #ff0000">path</span><span style="color: #0000ff">="/**"</span><span style="color: #0000ff">/></span>
            <span style="color: #0000ff"><</span><span style="color: #800000">bean </span><span style="color: #ff0000">class</span><span style="color: #0000ff">="joanna.yan.ssm.interceptor.HandlerInterceptor2"</span><span style="color: #0000ff">></</span><span style="color: #800000">bean</span><span style="color: #0000ff">></span>
        <span style="color: #0000ff"></</span><span style="color: #800000">mvc:interceptor</span><span style="color: #0000ff">></span>
    <span style="color: #0000ff"></</span><span style="color: #800000">mvc:interceptors</span><span style="color: #0000ff">></span>

3. Test d'interception

3.1 Exigences de test

Testez le timing d'exécution de chaque méthode de plusieurs intercepteurs.

3.2 Ecrire deux intercepteurs

3.3 Les deux intercepteurs sont autorisés

Informations du journal d'exécution :

<span style="color: #000000">HandlerInterceptor1...preHandle
HandlerInterceptor2...preHandle

HandlerInterceptor2...postHandle
HandlerInterceptor1...postHandle

HandlerInterceptor2...afterCompletion
HandlerInterceptor1...afterCompletion</span>

Résumé :

La méthode preHandle est exécutée dans l'ordre, et postHandle et afterCompletion sont exécutés dans l'ordre inverse de la configuration de l'intercepteur.

3.4 L'intercepteur 1 est autorisé, mais l'intercepteur 2 n'est pas autorisé

Informations du journal d'exécution :

<span style="color: #000000">HandlerInterceptor1...preHandle
HandlerInterceptor2...preHandle
HandlerInterceptor1...afterCompletion</span>

Résumé :

Une fois l'intercepteur 1 libéré, le preHandle de l'intercepteur 2 sera exécuté.

Le preHandle de l'intercepteur 2 ne sera pas libéré, et le postHandle et afterCompletion de l'intercepteur 2 ne seront pas exécutés.

Tant qu'il y a un intercepteur qui ne se libère pas, postHandle ne sera pas exécuté.

3.5 L'intercepteur 1 n'est pas autorisé, l'intercepteur 2 n'est pas autorisé

Informations du journal d'exécution :

HandlerInterceptor1...preHandle

Le preHandle de l'intercepteur 1 n'est pas libéré, et postHandle et afterCompletion ne seront pas exécutés.

Le preHandle de l'intercepteur 1 n'est pas libéré et l'intercepteur 2 n'est pas exécuté.

4.Résumé

Appliquez l'intercepteur en fonction des résultats du test.

Par exemple : intercepteur de traitement unifié des journaux, si le preHandle de l'intercepteur doit être modifié, il doit être libéré et placé en première position dans la chaîne de l'intercepteur.

Par exemple : intercepteur d'authentification de connexion, placé en première position dans la chaîne d'intercepteur. L'intercepteur de vérification d'autorisation est placé après l'intercepteur de connexion. (Parce que les autorisations sont vérifiées une fois la connexion passée)

5. Application Interceptor (implémentant l'authentification de connexion)

Exigences 5.1

(1) URL de la demande de l'utilisateur

(2) L'intercepteur effectue une vérification d'interception

Si l'url demandée est une adresse publique (une url accessible sans se connecter), laissez-la passer

Si la session utilisateur n'existe pas, accédez à la page de connexion.

Si la session utilisateur existe, relâchez-la et poursuivez l'opération.

5.2 Méthodes de connexion et de sortie du contrôleur

<span style="color: #0000ff">package</span><span style="color: #000000"> joanna.yan.ssm.controller;

</span><span style="color: #0000ff">import</span><span style="color: #000000"> javax.servlet.http.HttpSession;
</span><span style="color: #0000ff">import</span><span style="color: #000000"> org.springframework.stereotype.Controller;
</span><span style="color: #0000ff">import</span><span style="color: #000000"> org.springframework.web.bind.annotation.RequestMapping;

@Controller
</span><span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span><span style="color: #000000"> LoginController {
    
    </span><span style="color: #008000">//</span><span style="color: #008000">登录</span>
    @RequestMapping("/login"<span style="color: #000000">)
    </span><span style="color: #0000ff">public</span> String login(HttpSession session, String username, String password) <span style="color: #0000ff">throws</span><span style="color: #000000"> Exception{
        </span><span style="color: #008000">//</span><span style="color: #008000">调用service进行用户身份认证
        </span><span style="color: #008000">//</span><span style="color: #008000">...
        
        </span><span style="color: #008000">//</span><span style="color: #008000">在session中保存用户身份信息</span>
        session.setAttribute("username"<span style="color: #000000">, username);
        </span><span style="color: #0000ff">return</span> "redirect:items/queryItems.action"<span style="color: #000000">;
    }
    
    </span><span style="color: #008000">//</span><span style="color: #008000">退出</span>
    @RequestMapping("/logout"<span style="color: #000000">)
    </span><span style="color: #0000ff">public</span> String logout(HttpSession session) <span style="color: #0000ff">throws</span><span style="color: #000000"> Exception{
        </span><span style="color: #008000">//</span><span style="color: #008000">清除session</span>
<span style="color: #000000">        session.invalidate();
        </span><span style="color: #0000ff">return</span> "redirect:items/queryItems.action"<span style="color: #000000">;
    }
    
}</span>

5.3 Implémentation de l'interception de l'authentification de connexion

5.3.1Intercepteur de connexion

<span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> LoginInterceptor <span style="color: #0000ff">implements</span><span style="color: #000000"> HandlerInterceptor{

    </span><span style="color: #008000">//</span><span style="color: #008000">执行Handler完成执行此方法
    </span><span style="color: #008000">//</span><span style="color: #008000">应用场景:统一异常处理,统一日志处理</span>
<span style="color: #000000">    @Override
    </span><span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span><span style="color: #000000"> afterCompletion(HttpServletRequest request,
            HttpServletResponse response, Object handler, Exception ex)
            </span><span style="color: #0000ff">throws</span><span style="color: #000000"> Exception {
        System.out.println(</span>"HandlerInterceptor1......afterCompletion"<span style="color: #000000">);
    }

    </span><span style="color: #008000">//</span><span style="color: #008000">进入Handler方法之后,返回modelAndView之前执行
    </span><span style="color: #008000">//</span><span style="color: #008000">应用场景从modelAndView出发:将公用的模型数据(比如菜单导航)在这里传到视图,也可以在这里同意指定视图</span>
<span style="color: #000000">    @Override
    </span><span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span><span style="color: #000000"> postHandle(HttpServletRequest request, HttpServletResponse response,
            Object handler, ModelAndView modelAndView) </span><span style="color: #0000ff">throws</span><span style="color: #000000"> Exception {
        System.out.println(</span>"HandlerInterceptor1......postHandle"<span style="color: #000000">);
    }

    </span><span style="color: #008000">//</span><span style="color: #008000">进入Handler方法之前执行
    </span><span style="color: #008000">//</span><span style="color: #008000">用于身份认证、身份授权
    </span><span style="color: #008000">//</span><span style="color: #008000">比如身份认证,如果认证不通过表示当前用户没有登录,需要此方法拦截不再向下执行。</span>
<span style="color: #000000">    @Override
    </span><span style="color: #0000ff">public</span> <span style="color: #0000ff">boolean</span><span style="color: #000000"> preHandle(HttpServletRequest request, HttpServletResponse response,
            Object handler) </span><span style="color: #0000ff">throws</span><span style="color: #000000"> Exception {
        System.out.println(</span>"HandlerInterceptor1......preHandle"<span style="color: #000000">);
        </span><span style="color: #008000">//</span><span style="color: #008000">获取请求的url</span>
        String url=<span style="color: #000000">request.getRequestURI();
        </span><span style="color: #008000">//</span><span style="color: #008000">判断url是否是公开地址(实际使用时要将公开地址配置到文件中)
        </span><span style="color: #008000">//</span><span style="color: #008000">这里公开地址是登录提交的地址</span>
        <span style="color: #0000ff">if</span>(url.indexOf("login.action")>=0<span style="color: #000000">){
            </span><span style="color: #008000">//</span><span style="color: #008000">如果进行登录提交,放行</span>
            <span style="color: #0000ff">return</span> <span style="color: #0000ff">true</span><span style="color: #000000">;
        }
        </span><span style="color: #008000">//</span><span style="color: #008000">判断session</span>
        HttpSession session=<span style="color: #000000">request.getSession();
        String username</span>=(String) session.getAttribute("username"<span style="color: #000000">);
        </span><span style="color: #0000ff">if</span>(username!=<span style="color: #0000ff">null</span><span style="color: #000000">){
            </span><span style="color: #008000">//</span><span style="color: #008000">身份存在,放行</span>
            <span style="color: #0000ff">return</span> <span style="color: #0000ff">true</span><span style="color: #000000">;
        }
        
        </span><span style="color: #008000">//</span><span style="color: #008000">执行到这里,表示用户身份需要认证,跳转登录页面</span>
        request.getRequestDispatcher("/WEB-INF/jsp/login.jsp"<span style="color: #000000">).forward(request, response);
        
        </span><span style="color: #008000">//</span><span style="color: #008000">return false表示拦截,不向下执行
        </span><span style="color: #008000">//</span><span style="color: #008000">return true表示放行</span>
        <span style="color: #0000ff">return</span> <span style="color: #0000ff">false</span><span style="color: #000000">;
    }

}</span>

5.3.2 Configuration de l'intercepteur

Configuration dans springmvc.xml sous classpath :

Si cet article vous est utile, veuillez me donner un conseil sur WeChat~

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn