Maison > Java > javaDidacticiel > Résoudre le problème du délai d'expiration de session dans le projet Javaweb

Résoudre le problème du délai d'expiration de session dans le projet Javaweb

黄舟
Libérer: 2017-09-21 10:16:04
original
2352 Les gens l'ont consulté

Cet article présente principalement la solution de délai d'expiration de session pour les projets Javaweb. La classification de la solution est relativement claire et le contenu est détaillé. Les amis dans le besoin peuvent s'y référer.

Dans le développement Web Java, Session nous offre beaucoup de commodité. La session est maintenue entre le navigateur et le serveur. Le délai d'attente de session s'entend comme : une session est créée entre le navigateur et le serveur. Étant donné que le client n'interagit pas avec le serveur pendant une longue période (temps de veille), le serveur détruit cette session lorsque le client interagit à nouveau avec le serveur. la session précédente n'existe pas.

0. Exigences

Toutes les requêtes /web/** doivent être connectées et interceptées, et la page de connexion passera à la session lorsque le la session expire.

1. Introduction

De manière générale, le délai d'expiration de la session sera configuré lors de l'utilisation du projet. S'il n'est pas configuré, la valeur par défaut est de 30 minutes. , c'est-à-dire qu'après 30 minutes d'inactivité, la session expirera et l'utilisateur devra se reconnecter au système.

La configuration du délai d'expiration de session est configurée dans le web.xml du projet principal, comme suit :


<span style="font-size: 14px;"> <!-- 设置Session超时时间 -->  
    <session-config>  
        <!-- 分钟 -->  
            <session-timeout>60</session-timeout>  
            <!-- 去除URL上显示的jsessionid, 防止打开Tab页时出现JS错误 -->  
            <tracking-mode>COOKIE</tracking-mode>  
    </session-config></span><span style="font-size:24px;">  
</span>
Copier après la connexion

2. Classification des requêtes

Les requêtes dans les projets en cours sont principalement divisées en deux types : l'une est une requête normale, qui initie une requête et renvoie une vue et un modèle, l'autre est une requête Ajax, qui renvoie principalement des données de modèle. Lorsque le backend effectue un traitement, il doit renvoyer un contenu différent en fonction de différentes requêtes.

Pour les requêtes ordinaires, nous renvoyons directement le script JavaScript. Le contenu du script peut être de passer à la page de connexion.

Pour les requêtes Ajax, un code d'état autre que 200 doit être renvoyé, afin que la requête ajax entre dans la fonction de rappel d'erreur et la fonction de rappel d'erreur Ajax globale AjaxError.

3. Traitement du backend Délai d'expiration de la session

Le backend utilise le traitement de l'intercepteur de SpringMVC. Pourquoi un intercepteur est-il utilisé ici ? D'une part, l'URL de la requête ne peut pas être trop restrictive, comme /* C'est un gaspillage de ressources pour filtrer toutes les requêtes. En revanche, certaines URL n'ont pas besoin d'être interceptées. Par exemple, les requêtes vers la page de connexion ne doivent pas être interceptées, sinon elles seront redirigées en boucle. D’un autre côté, nous devons uniquement intercepter les requêtes du contrôleur et non les autres requêtes.

Jetons un coup d'œil à l'implémentation de l'intercepteur :


/** 
* Web端登录拦截器
* 处理请求时Session失效的问题,包含Ajax请求和普通请求
* @ClassName WebLoginInterceptor 
* @author zhangshun
* @date 2016年10月20日 上午11:14:52
*/
public class WebLoginInterceptor extends HandlerInterceptorAdapter{
    /**
     * 日志对象
     */
    private Logger logger = LoggerFactory.getLogger(WebLoginInterceptor.class);
    /**
     * 默认注销URL
     * 即Session超时后,发起请求到此地址,只对普通请求有效
     */
    private static final String DEFAULT_LOGOUT_URL = "/web/logout";
    /**
     * 注销URL
     */
    private String logoutUrl;
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
            Object handler) throws Exception {
        User user = SessionUtils.getUserFromRequestAcrossCas(request);
        String uri = request.getRequestURI();    
                if(user == null){
                    response.setContentType("text/html;charset=UTF-8");
                    if(request.getHeader("x-requested-with") != null 
                                && request.getHeader("x-requested-with").equalsIgnoreCase("XMLHttpRequest")){ 
                        // Ajax请求, 前段根据此header进行处理
                        response.setHeader("sessionTimeout", "Session time out, you need relogin !");
                        // 返回未认证的状态码(401)
                        response.setStatus(HttpStatus.UNAUTHORIZED.value());
                            logger.debug("请求路径:" + uri + ", 请求方式 :Ajax请求, Session超时, 需要重新登录!");
                        }else{
                            // 普通请求
                            String path = request.getContextPath();
                            StringBuffer basePath = new StringBuffer()
                                    .append(request.getScheme())
                                    .append("://")
                                    .append(request.getServerName())
                                    .append(":")
                                    .append(request.getServerPort())
                                    .append(path)
                                    .append("/");
                            StringBuffer responseStr = new StringBuffer()
                                    .append("<html><header><script type=\"text/javascript\">")
                                    .append("window.location.href=\"")
                                        .append(basePath).append(getLogoutUrl()).append("\";")
                                    .append("</script></header></html>");
                                response.getWriter().write(responseStr.toString());
                                logger.debug("请求路径:" + uri + ",请求方式 :普通请求, Session超时, 需要重新登录!");
                        }
                    return false;
                }
                return true;
    }
    public String getLogoutUrl() {
        // 使用默认值
        if(StringUtils.isEmpty(logoutUrl)){
            return DEFAULT_LOGOUT_URL;
        }
        return logoutUrl;
    }
    public void setLogoutUrl(String logoutUrl) {
        this
}
Copier après la connexion

Jugez si la session a expiré en obtenant l'existence de l'objet User dans la session. Si la session expire, il sera renvoyé selon différentes méthodes de requête. S'il s'agit d'une requête normale, le script JavaScript sera renvoyé directement, ce qui pourra renvoyer la page vers d'autres URL. S'il s'agit d'une requête Ajax, un code d'état 401 sera renvoyé et sessionTimeout sera ajouté à l'en-tête renvoyé. Ces données seront utilisées sur le front-end.

L'intercepteur est configuré comme suit dans le fichier de configuration SpringMVC :


<span style="font-size:14px;"><!-- MVC拦截器 -->
<mvc:interceptors>
    <!-- Web登录拦截器 -->
    <mvc:interceptor>
        <mvc:mapping path="/web/**"/>
        <mvc:exclude-mapping path="/web/index"/><!-- 防止循环重定向到首页 -->
        <mvc:exclude-mapping path="/web/login"/>
        <mvc:exclude-mapping path="/web/logout"/>
        <mvc:exclude-mapping path="/web/doLogin"/>
        <bean class="com.woyi.mhub.interceptor.WebLoginInterceptor"/>
    </mvc:interceptor>
</mvc:interceptors></span><span style="font-size:24px;">
</span>
Copier après la connexion

4.

Pour les requêtes ordinaires, le backend renvoie un script JavaScript, qui sera exécuté immédiatement. Le frontend n'a besoin d'aucun traitement ici.

Pour les requêtes Ajax, le backend renvoie un code d'état 401 et le sessionTimeout défini dans l'en-tête. La fonction de rappel ajaxComplete de jQuery est utilisée ici, comme suit :


// 实现ajax请求时判断Session是否失效 
$(document).ajaxComplete(function(event, response, settings) { 
 var sessionTimeout = response.getResponseHeader("SessionTimeout"); 
 if(sessionTimeout != null && typeof sessionTimeout != "undefined" && sessionTimeout.length > 0){ 
  // 这里写Session超时后的处理方法 
 } 
});
Copier après la connexion

D'accord, c'est tout. Les utilisateurs dont la session expire seront traités.

Résumé

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!

Étiquettes associées:
source:php.cn
Déclaration de ce site Web
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
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal