JFinal에 ROR와 유사한 Flash 기능 추가 - 두 번째 버전 구현

9703 단어 FlashjFinal
며칠 전에 제1판을 만들었다.일부 피드백을 받았는데 어제 코드를 재구성하여 1판보다 좀 더 유연하게 만들었고 ehcache 기반의 실현 외에 Session 기반의 실현도 실현했다.
부호를 띄우다.
package com.jfinal.flash;

import java.util.Map;

import javax.servlet.http.HttpSession;

/**
 * flash     。
 * @author dafei
 */
public interface IFlashManager {
	/**
	 *   flash      。
	 *
	 * @param sessionKey
	 *            session  
	 * @param curAction
	 *              ActionPath
	 * @param key
	 *             
	 * @param value
	 *             
	 */
	public void setFlash(HttpSession session, String curAction, String key,
			Object value);

	/***
	 *    redirect forwardAction
	 *       ,    actionPath key        actionPath  key。
	 *
	 * @param sessionKey
	 *            session Id 
	 * @param curAction
	 *              ActionPath
	 * @param nextAction
	 *               ActionPath
	 */
	public void updateFlashKey(HttpSession session, String curAction,
			String nextAction);

	/**
	 *  cache   Flash Map
	 *
	 * @param sessionKey
	 *            session  
	 * @param curAction
	 *              ActionPath
	 * @return Flash Map
	 */
	public Map<String, Object> getFlash(HttpSession session, String curAction);
}
세션 기반 구현
package com.jfinal.ext.flash;

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

import javax.servlet.http.HttpSession;

import com.jfinal.flash.IFlashManager;

/**
 *
 *   Session   Flash   
 *
 * @author dafei
 *
 */
public class SessionFlashManager implements IFlashManager{

    /**
     *    session  
     */
    private final static String sessionKeyPrefix = "_flash_";

    /**
     *     
     */
    public SessionFlashManager() {
    }

    @SuppressWarnings("unchecked")
    public void setFlash(HttpSession session, String curAction, String key,
            Object value) {
    	String sessionKey = sessionKeyPrefix + curAction.replace("/", "_");
        Object obj = session.getAttribute(sessionKey);
        Map<String, Object> map = null;
        if (obj != null) {
            map = (Map<String, Object>) obj;
        } else {
            map = new ConcurrentHashMap<String, Object>();
            session.setAttribute(sessionKey, map);
        }
        map.put(key, value);
    }

    public void updateFlashKey(HttpSession session, String curAction,
            String nextAction) {
        String oldKey = sessionKeyPrefix + curAction.replace("/", "_");
        String newkey = sessionKeyPrefix + nextAction.replace("/", "_");
        Object obj = session.getAttribute(oldKey);
        if (obj != null) {
        	session.removeAttribute(oldKey);
            session.setAttribute(newkey, obj);
        }
    }

    @SuppressWarnings("unchecked")
    public Map<String, Object> getFlash(HttpSession session, String curAction) {
        String sessionActionKey = sessionKeyPrefix + curAction.replace("/", "_");
        Map<String, Object> map = null;
        Object obj = session.getAttribute(sessionActionKey);
        if (obj != null) {
            map = (Map<String, Object>) obj;
            session.removeAttribute(sessionActionKey);
        }
        return map;
    }
}

Ehcache 기반 구현
package com.jfinal.ext.flash;

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

import javax.servlet.http.HttpSession;

import com.jfinal.flash.IFlashManager;
import com.jfinal.kit.StringKit;
import com.jfinal.plugin.ehcache.CacheKit;

/**
 *
 *   ehcache   Flash   
 *
 * @author dafei
 *
 */
public class EhCacheFlashManager implements IFlashManager{
    /**
     * ehcache   cache  。
     */
    private final String flashCacheName;

    /**
     *  
     */
    private ReentrantLock lock = new ReentrantLock();

    /**
     *     
     * @param flashCacheName  ehcache   cache  。
     */
    public EhCacheFlashManager(String flashCacheName ) {
    	if (StringKit.isBlank(flashCacheName)){
			throw new IllegalArgumentException("flashCacheName can not be blank.");
    	}
    	this.flashCacheName = flashCacheName;
    }

    @SuppressWarnings("unchecked")
    public void setFlash(HttpSession session, String curAction, String key,
            Object value) {
    	String sessionKey = session.getId();
        sessionKey = sessionKey + curAction.replace("/", "_");
        lock.lock();
        Object obj = CacheKit.get(flashCacheName, sessionKey);
        Map<String, Object> map = null;
        if (obj != null) {
            map = (Map<String, Object>) obj;
        } else {
            map = new ConcurrentHashMap<String, Object>();
            CacheKit.put(flashCacheName, sessionKey, map);
        }
        lock.unlock();
        map.put(key, value);
    }

    public void updateFlashKey(HttpSession session, String curAction,
            String nextAction) {
    	String sessionKey = session.getId();
        String oldKey = sessionKey + curAction.replace("/", "_");
        String newkey = sessionKey + nextAction.replace("/", "_");
        lock.lock();
        Object obj = CacheKit.get(flashCacheName, oldKey);
        if (obj != null) {
            CacheKit.remove(flashCacheName, oldKey);
            CacheKit.put(flashCacheName, newkey, obj);
        }
        lock.unlock();
    }

    @SuppressWarnings("unchecked")
    public Map<String, Object> getFlash(HttpSession session, String curAction) {
    	String sessionKey = session.getId();
        String sessionActionKey = sessionKey + curAction.replace("/", "_");
        Map<String, Object> map = null;
        lock.lock();
        Object obj = CacheKit.get(flashCacheName, sessionActionKey);
        if (obj != null) {
            map = (Map<String, Object>) obj;
            CacheKit.remove(flashCacheName, sessionActionKey);
        }
        lock.unlock();
        return map;
    }
}

Constants 클래스를 어셈블하고 다음 코드를 추가합니다.
/**
	 *     session   。
	 */
	private IFlashManager flashManager = new SessionFlashManager();

	public IFlashManager getFlashManager() {
		return flashManager;
	}

	public void setFlashManager(IFlashManager flashManager) {
		this.flashManager = flashManager;
	}

호출이 용이하도록 Controller를 수정하고 두 변수를 정의했습니다.
초기화 섹션
private boolean setFlashFalg = false;
	private IFlashManager flashManager;

	void init(HttpServletRequest request, HttpServletResponse response, String urlPara) {
		this.request = request;
		this.response = response;
		this.urlPara = urlPara;
		flashManager = Config.getConstants().getFlashManager();
	}

	public IFlashManager getFlashManager(){
		return this.flashManager;
	}

Controller의 기타 코드 수정
public String parsePath(String currentActionPath, String url){
		if(url.startsWith("/")){//    
			return url.split("\\?")[0];
		}else if(!url.contains("/")){//   detail   。
			return "/"+ currentActionPath.split("/")[1] + "/" + url.split("\\?")[0];
		}else if(url.contains("http:")|| url.contains("https:")){
			return null;
		}
		///abc/def","bcd/efg?abc
		return currentActionPath + "/" + url.split("\\?")[0];
	}

public void setFlash(String key, Object value){
		String actionPath = this.request.getRequestURI();
		flashManager.setFlash(this.getSession(false),actionPath, key, value);
		setFlashFalg = true;
	}

public void forwardAction(String actionUrl) {
		if(setFlashFalg){//      Flash。  key。
			String actionPath = this.request.getRequestURI();
			//    actionPath key        actionPath  key
			flashManager.updateFlashKey(this.getSession(false), actionPath, actionUrl);
			setFlashFalg =false;
		}
		render = new ActionRender(actionUrl);
	}

public void redirect(String url) {
		if(setFlashFalg){
			String actionPath = this.request.getRequestURI();
			String newActionPath = parsePath(actionPath, url);
			flashManager.updateFlashKey(this.getSession(false), actionPath, newActionPath);
			setFlashFalg = false;
		}
		render = renderFactory.getRedirectRender(url);
	}

	/**
	 * Redirect to url
	 */
	public void redirect(String url, boolean withQueryString) {
		if(setFlashFalg){
			String actionPath = this.request.getRequestURI();
			String newActionPath = parsePath(actionPath, url);
			flashManager.updateFlashKey(this.getSession(false), actionPath, newActionPath);
			setFlashFalg = false;
		}
		render = renderFactory.getRedirectRender(url, withQueryString);
	}

차단기가 새로 추가되었습니다.
public class Flash implements Interceptor{
	@Override
	/**
	 *         ActionPath, Cache           Action Flash  Map
     *   ,   Map,    key,value      request   。
	 */
	public void intercept(ActionInvocation ai) {
		Controller c = ai.getController();
		HttpSession session = c.getSession(false);
		if(null == session){
			return;
		}
		String curAction = ai.getViewPath()+ai.getMethodName();
		Map<String, Object> flashMap = c.getFlashManager().getFlash(session, curAction);
		if(flashMap != null){
			for(Entry<String,Object> flashEntry: flashMap.entrySet()){
				c.setAttr(flashEntry.getKey(), flashEntry.getValue());
			}
		}
		ai.invoke();
	}
}

초기화를 호출합니다. 설정하지 않을 때 기본적으로session 기반의 실현 방식을 사용합니다.
public void configConstant(Constants me) {
		//         
		loadPropertyFile("database.properties");
		//    httl    
		me.setMainRenderFactory(new HttlRenderFactory());
		me.setFlashManager(new EhCacheFlashManager("flashCache"));
}
사용 방식은 제1판과 같다.

좋은 웹페이지 즐겨찾기