阻止跨网站跟踪(Prevent Cross-Site Tracking)时cookie未获取到,造成服务端获取session失败

跨域获取cookie失效解决方案

参考:http://www.bubuko.com/infodetail-357996.html

1、iphone 自带浏览器(Safari)跨网站跟踪时,需要关闭Safari设置中"阻止跨网站跟踪",如下图:
阻止跨网站跟踪(Prevent Cross-Site Tracking)时cookie未获取到,造成服务端获取session失败_第1张图片

2、iphone 中firefox 以及Google Chrome浏览器由于涉及到用户隐私,默认时关闭

由于以上2点,自定义Session

请求时需带参数token,示例:
http://localhost:8080/test/info?token=12345678


Locale locale = new Locale("en", "US");
ActionContextUtil.getContext(token).getSession().put(Constants.WW_TRANS_I18N_LOCALE, locale);

String themeName = "default";
ActionContextUtil.getContext(token).getSession().put(Constants.SESSION_KEY_THEME_NAME, themeName);

ActionContextUtil.getContext(token).setCustomI18N();
ActionContextUtil.getContext(token).setThemeName();

配置文件config.properties

#定时任务周期(单位:毫秒):1分钟 = 1000*60
periodTime=60000

#自定义session超时时间(单位:毫秒):30分钟 = 1000*60*30
sessionTimeout=300000

web.xml 配置监听器

		
		cn.ding.listener.ServiceDataTaskListener

创建监听器

package cn.ding.listener;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import org.apache.log4j.Logger;
import cn.co.test.task.TimerManager;

public class ServiceDataTaskListener implements ServletContextListener {

	private static Logger logger = Logger.getLogger(ServiceDataTaskListener.class);

	@Override
	public void contextInitialized(ServletContextEvent sce) {
		try {
			new TimerManager();
		} catch (Exception e) {
			logger.error(e);
		}

	}

	@Override
	public void contextDestroyed(ServletContextEvent sce) {

	}

}

定时任务

package cn.ding.task;

import java.io.IOException;
import java.io.InputStream;
import java.util.Calendar;
import java.util.Iterator;
import java.util.Map.Entry;
import java.util.Properties;
import java.util.TimerTask;
import org.apache.log4j.Logger;
import org.springframework.util.CollectionUtils;
import cn.ding.beans.ActionContext;
import cn.ding.util.ActionContextUtils;

public class ServiceDataTimerTask extends TimerTask {

	private static Logger logger = Logger.getLogger(ServiceDataTimerTask.class);

	// 自定义session超时时间:30分钟 = 1000*60*30
	private static long timeout = 300000;

	public ServiceDataTimerTask() {
		Properties properties = new Properties();
		InputStream inputStream = Thread.currentThread().getContextClassLoader()
				.getResourceAsStream("config.properties");

		try {
			properties.load(inputStream);
			timeout = Integer.parseInt(properties.get("sessionTimeout").toString());
		} catch (IOException e) {
			logger.error(e);
		} finally {
			if (inputStream != null) {
				try {
					inputStream.close();
				} catch (IOException e) {
					logger.error(e);
				}
			}
		}
	}

	@Override
	public void run() {

        // 用户账号失效时间
//        if (CollectionUtils.isNotEmpty(ActionContextUtil.getActionContextMap())) {
//
//            Iterator> iterator = ActionContextUtil.getActionContextMap().entrySet()
//                    .iterator();
//
//            while (iterator.hasNext()) {
//                Map.Entry context = iterator.next();
//                if (context.getValue().expire(timeout)) {
//                    iterator.remove();
//                }
//            }
//        }

        if (CollectionUtils.isNotEmpty(ActionContextUtil.getActionContextMap())) {

            ActionContextUtil.getActionContextMap().entrySet().removeIf(context -> context.getValue().expire(timeout));
        }

}

package cn.ding.task;

import java.io.IOException;
import java.io.InputStream;
import java.util.Calendar;
import java.util.Properties;
import java.util.Timer;

import cn.ding.task.ServiceDataTimerTask;

public class TimerManager {

	public TimerManager() throws IOException {
		Properties properties = new Properties();
		InputStream inputStream = Thread.currentThread().getContextClassLoader()
				.getResourceAsStream("config.properties");

		properties.load(inputStream);
		inputStream.close();
		long periodTime = Long.parseLong(properties.get("periodTime").toString());

		Timer timer = new Timer();

		NFDFlightDataTimerTask task = new NFDFlightDataTimerTask();
		
		// 执行任务,延迟500毫秒
        timer.schedule(task, 500L, periodTime);
	}

}
package cn.ding.util;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import cn.ding.beans.ActionContext;

public class ActionContextUtils {

	private ActionContextUtils() {

	}
/**
     * 线程本地变量
     */
    private static ThreadLocal threadActionContext = new ThreadLocal();
	private static Map actionContext = new ConcurrentHashMap();

    public static ActionContext getContext() {
        return threadActionContext.get();
    }

    public static void setContext(ActionContext context) {
        threadActionContext.set(context);
    }

    public static void setContext(String key) {
        actionContext.put(key, new ActionContext());
    }

    public static ActionContext getContext(String key) {
        ActionContext context = actionContext.get(key);
        if (context == null) {
            actionContext.put(key, new ActionContext());
        }
        return actionContext.get(key);
    }

	public static Map getActionContextMap() {
		return actionContext;
	}

	/**
	 * 是否存在
	 * 
	 * @param key
	 * @return key存在返回true,否则返回false
	 */
	public static boolean isExists(String key) {
		return actionContext.get(key) == null ? false : true;
	}
}

package cn.ding.beans;

import java.io.Serializable;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;

import cn.ding.constant.Constants;

public class ActionContext implements Serializable {

	private static final long serialVersionUID = -7943856181845154348L;

	public static final String SESSION = "session";

	public static final String LOCALE = "locale";
	
    /**
     * 自定义超时时间,单位毫秒(ms):30分钟 = 1000*60*30
     */
    private static final long INTERVAL = 1800000L;
   
    /**
     * 创建时间,单位毫秒(ms)
     */
    private long creationTime = System.currentTimeMillis();

	private Map context = new HashMap();

	public ActionContext() {
		context.put(SESSION, new HashMap());
	}

	/**
	 * 重新设置Session
	 */
	public void reset() {

		creationTime = System.currentTimeMillis();

		setThemeName();

		setCustomI18N();

		setBackUrl();
	}

	/**
	 * 国际化
	 */
	public void setCustomI18N() {
		Locale locale = (Locale) getSession().get(Constants.WW_TRANS_I18N_LOCALE);

		if (locale != null) {
			com.opensymphony.xwork2.ActionContext.getContext().getSession().put(Constants.WW_TRANS_I18N_LOCALE, locale);

			setLocale(locale);
		}

	}

	/**
	 * 主题
	 */
	public void setThemeName() {
		String themeName = (String) getSession().get(Constants.SESSION_KEY_THEME_NAME);

		if (themeName != null) {
			com.opensymphony.xwork2.ActionContext.getContext().getSession().put(Constants.SESSION_KEY_THEME_NAME,
					themeName);
		}
	}

	/**
	 * 设置当前操作的区域设置。
	 * 
	 * @param locale 当前操作的区域设置.
	 */
	public void setLocale(Locale locale) {
		put(LOCALE, locale);

		com.opensymphony.xwork2.ActionContext.getContext().setLocale(locale);
	}

	/**
	 * 获取当前操作的区域设置。如果从未指定区域设置,则使用平台的{@link java.util.Locale#getDefault() 默认区域设置}
	 * 
	 * @return 当前操作的区域设置。
	 */
	public Locale getLocale() {
		Locale locale = (Locale) get(LOCALE);

		if (locale == null) {
			locale = Locale.getDefault();
			setLocale(locale);
		}

		return locale;
	}

	/**
	 * 设置返回路径,JSP页面在使用
	 * 
	 * @param locale
	 */
	public void setBackUrl() {
		String backUrl = (String) getSession().get(Constants.SESSION_KEY_CALL_BACK_URL);

		if (backUrl != null) {
			com.opensymphony.xwork2.ActionContext.getContext().getSession().put(Constants.SESSION_KEY_CALL_BACK_URL,
					backUrl);
		}
	}

	/**
	 * 设置操作会话值的映射
	 * 
	 * @param session 会话值
	 */
	public void setSession(Map session) {

		put(SESSION, session);
	}

	/**
	 * 获取会话映射中值的映射。
	 * 
	 * @return 会话值
	 */
	@SuppressWarnings("unchecked")
	public Map getSession() {

		return (Map) get(SESSION);
	}
    /**
     * 是否到期,超时时间默认30分钟
     *
     * @return {@code true} 如果时间已到期
     */
    public boolean expire() {
        return (System.currentTimeMillis()) > (creationTime + INTERVAL);
    }

    /**
     * 是否到期
     *
     * @param interval 间隔时间,单位毫秒(ms)
     * @return {@code true} 如果时间已到期
     */
    public boolean expire(long interval) {
        return (System.currentTimeMillis()) > (creationTime + interval);
    }
	public Object get(String key) {
		return context.get(key);
	}

	public void put(String key, Object value) {
		context.put(key, value);
	}

	public long getExpireTime() {
		return expireTime;
	}

}

你可能感兴趣的:(Java)