Terry.Li-彬

          虛其心,可解天下之問;專其心,可治天下之學;靜其心,可悟天下之理;恒其心,可成天下之業。

            BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
            143 隨筆 :: 344 文章 :: 130 評論 :: 0 Trackbacks
          package my.mvc;
          
          import java.io.*;
          import java.lang.reflect.*;
          import java.net.URLDecoder;
          import java.util.*;
          
          import javax.servlet.*;
          import javax.servlet.http.*;
          
          import my.db.DBException;
          import my.util.ResourceUtils;
          
          import org.apache.commons.lang.StringUtils;
          import org.apache.commons.lang.math.NumberUtils;
          
          /**
           * 業務處理方法入口,URI的映射邏輯:
           * /action/xxxxxx/xxxx -> com.dlog4j.action.XxxxxxAction.xxxx(req,res)
           * <pre>
          	林花謝了春紅,
          	太匆匆,
          	無奈朝來寒雨晚來風。
          
          	胭脂淚,
          	相留醉,
          	幾時重,
          	自是人生長恨水長東。
           * </pre>
           * @author Winter Lau (http://my.oschina.net/javayou)<br> */
          public final class ActionServlet extends HttpServlet {
          
          	private final static String ERROR_PAGE = "error_page";
          	private final static String GOTO_PAGE = "goto_page";
          	private final static String THIS_PAGE = "this_page";
          	private final static String ERROR_MSG = "error_msg";
          	
          	private final static String UTF_8 = "utf-8";	
          	private List<String> action_packages = null;
          	private final static ThreadLocal<Boolean> g_json_enabled = new ThreadLocal<Boolean>();
          	
          	@Override
          	public void init() throws ServletException {
          		String tmp = getInitParameter("packages");
          		action_packages = Arrays.asList(StringUtils.split(tmp,','));
          		String initial_actions = getInitParameter("initial_actions");
          		for(String action : StringUtils.split(initial_actions,','))
          			try {
          				_LoadAction(action);
          			} catch (Exception e) {
          				log("Failed to initial action : " + action, e);
          			}
          	}
          
          	@Override
          	public void destroy() {
          		for(Object action : actions.values()){
          			try{
          				Method dm = action.getClass().getMethod("destroy");
          				if(dm != null){
          					dm.invoke(action);
          					log("!!!!!!!!! " + action.getClass().getSimpleName() + 
          						" destroy !!!!!!!!!");
          				}
          			}catch(NoSuchMethodException e){
          			}catch(Exception e){
          				log("Unabled to destroy action: " + action.getClass().getSimpleName(), e);
          			}
          		}
          		super.destroy();
          	}
          	
          	@Override
          	protected void doGet(HttpServletRequest req, HttpServletResponse resp)
          			throws ServletException, IOException {
          		process(RequestContext.get(), false);
          	}
          
          	@Override
          	protected void doPost(HttpServletRequest req, HttpServletResponse resp)
          			throws ServletException, IOException {
          		process(RequestContext.get(), true);
          	}
          	
          	/**
          	 * 執行Action方法并進行返回處理、異常處理
          	 * @param req
          	 * @param resp
          	 * @param is_post
          	 * @throws ServletException
          	 * @throws IOException
          	 */
          	protected void process(RequestContext req, boolean is_post) 
          		throws ServletException, IOException 
          	{
          		try{
          			req.response().setContentType("text/html;charset=utf-8");
          			if(_process(req, is_post)){ 
          				String gp = req.param(GOTO_PAGE);
          				if(StringUtils.isNotBlank(gp))
          					req.redirect(gp);
          			}
          		}catch(InvocationTargetException e){
          			Throwable t = e.getCause();
          			if(t instanceof ActionException)
          				handleActionException(req, (ActionException)t);
          			else if(t instanceof DBException)
          				handleDBException(req, (DBException)t);
          			else
          				throw new ServletException(t);
          		}catch(ActionException t){
          			handleActionException(req, t);
          		}catch(IOException e){
          			throw e;
          		}catch(DBException e){
          			handleDBException(req, e);
          		}catch(Exception e){
          			log("Exception in action process.", e);
          			throw new ServletException(e);
          		}finally{
          			g_json_enabled.remove();
          		}
          	}
          	
          	/**
          	 * Action業務異常
          	 * @param req
          	 * @param resp
          	 * @param t
          	 * @throws ServletException
          	 * @throws IOException
          	 */
          	protected void handleActionException(RequestContext req, ActionException t)	
          		throws ServletException, IOException 
          	{		
          		handleException(req, t.getMessage());
          	}
          	
          	protected void handleDBException(RequestContext req, DBException e) 
          		throws ServletException, IOException 
          	{
          		log("DBException in action process.", e);
          		handleException(req, ResourceUtils.getString("error", 
          			"database_exception", e.getCause().getMessage()));
          	}
          	
          	/**
          	 * URL解碼
          	 * 
          	 * @param url
          	 * @param charset
          	 * @return
          	 */
          	private static String _DecodeURL(String url, String charset) {
          		if (StringUtils.isEmpty(url))
          			return "";
          		try {
          			return URLDecoder.decode(url, charset);
          		} catch (Exception e) {
          		}
          		return url;
          	}
          
          	protected void handleException(RequestContext req, String msg) 
          		throws ServletException, IOException 
          	{
          		String ep = req.param(ERROR_PAGE);
          		if(StringUtils.isNotBlank(ep)){
          			if(ep.charAt(0)=='%')
          				ep = _DecodeURL(ep, UTF_8);
          			ep = ep.trim();
          			if(ep.charAt(0)!='/'){
          				req.redirect(req.contextPath()+"/");
          			}
          			else{
          				req.request().setAttribute(ERROR_MSG, msg);
          				req.forward(ep.trim());
          			}
          		}
          		else{
          			if(g_json_enabled.get())
          				req.output_json("msg", msg);
          			else
          				req.print(msg);
          		}
          	}	
          	
          	/**
          	 * 業務邏輯處理
          	 * @param req
          	 * @param resp
          	 * @param is_post_method
          	 * @throws IllegalAccessException 
          	 * @throws InstantiationException 
          	 * @throws IOException 
          	 * @throws ServletException
          	 * @throws IOException
          	 * @throws InvocationTargetException 
          	 * @throws IllegalArgumentException 
          	 */
          	private boolean _process(RequestContext req, boolean is_post)
          			 throws InstantiationException,
          					IllegalAccessException, 
          					IOException, 
          					IllegalArgumentException,
          					InvocationTargetException
          	{
          		String requestURI = req.uri();
          		String[] parts = StringUtils.split(requestURI, '/');
          		if(parts.length<2){
          			req.not_found();
          			return false;
          		}
          		//加載Action類
          		Object action = this._LoadAction(parts[1]);
          		if(action == null){
          			req.not_found();
          			return false;
          		}
          		String action_method_name = (parts.length>2)?parts[2]:"index";
          		Method m_action = this._GetActionMethod(action, action_method_name);
          		if(m_action == null){
          			req.not_found();
          			return false;
          		}
          		
          		//判斷action方法是否只支持POST
          		if (!is_post && m_action.isAnnotationPresent(Annotation.PostMethod.class)){
          			req.not_found();
          			return false;
          		}
          		
          		g_json_enabled.set(m_action.isAnnotationPresent(Annotation.JSONOutputEnabled.class));
          		
          		if(m_action.isAnnotationPresent(Annotation.UserRoleRequired.class)){
          			IUser loginUser = req.user();
          			if(loginUser == null){
          				String this_page = req.param(THIS_PAGE, "");
          				throw req.error("user_not_login", this_page);
          			}
          			if(loginUser.IsBlocked())
          				throw req.error("user_blocked");
          			
          			Annotation.UserRoleRequired urr = (Annotation.UserRoleRequired)
          				m_action.getAnnotation(Annotation.UserRoleRequired.class);
          			if(loginUser.getRole() < urr.role())
          				throw req.error("user_role_deny");			
          		}
          		
          		//調用Action方法之準備參數
          		int arg_c = m_action.getParameterTypes().length;
          		switch(arg_c){
          		case 0: // login()
          			m_action.invoke(action);
          			break ;
          		case 1:
          			m_action.invoke(action, req);
          			break;
          		case 2: // login(HttpServletRequest req, HttpServletResponse res)
          			m_action.invoke(action, req.request(), req.response());
          			break ;
          		case 3: // login(HttpServletRequest req, HttpServletResponse res, String[] extParams)
          			StringBuilder args = new StringBuilder();
          			for(int i=3;i<parts.length;i++){
          				if(StringUtils.isBlank(parts[i]))
          					continue;
          				if(args.length() > 0)
          					args.append('/');
          				args.append(parts[i]);
          			}
          			boolean isLong = m_action.getParameterTypes()[2].equals(long.class);
          			m_action.invoke(action, req.request(), req.response(), isLong ? NumberUtils.toLong(
          					args.toString(), -1L) : args.toString());
          			break ;
          		default:
          			req.not_found();
          			return false;
          		}
          		
          		return true;
          	}
          	
          	/**
          	 * 加載Action類
          	 * @param act_name
          	 * @return
          	 * @throws InstantiationException
          	 * @throws IllegalAccessException
          	 * @throws ClassNotFoundException
          	 */
          	protected Object _LoadAction(String act_name) 
          		throws InstantiationException,IllegalAccessException 
          	{
          		Object action = actions.get(act_name);
          		if(action == null){
          			for(String pkg : action_packages){
          				String cls = pkg + '.' + StringUtils.capitalize(act_name) + "Action";
          				action = _LoadActionOfFullname(act_name, cls);
          				if(action != null)
          					break;
          			}
          		}
          		return action ;
          	}
          	
          	private Object _LoadActionOfFullname(String act_name, String cls) 
          		throws IllegalAccessException, InstantiationException 
          	{
          		Object action = null;
          		try {								
          			action = Class.forName(cls).newInstance();
          			try{
          				Method action_init_method = action.getClass().getMethod("init", ServletContext.class);
          				action_init_method.invoke(action, getServletContext());
          			}catch(NoSuchMethodException e){
          			}catch(InvocationTargetException excp) {
          				excp.printStackTrace();
          			}
          			if(!actions.containsKey(act_name)){
          				synchronized(actions){
          					actions.put(act_name, action);
          				}
          			}
          		} catch (ClassNotFoundException excp) {}
          		return action;
          	}
          	
          	/**
          	 * 獲取名為{method}的方法
          	 * @param action
          	 * @param method
          	 * @return
          	 */
          	private Method _GetActionMethod(Object action, String method) {
          		String key = action.getClass().getSimpleName() + '.' + method;
          		Method m = methods.get(key);
          		if(m != null) return m;
          		for(Method m1 : action.getClass().getMethods()){
          			if(m1.getModifiers()==Modifier.PUBLIC && m1.getName().equals(method)){
          				synchronized(methods){
          					methods.put(key, m1);
          				}
          				return m1 ;
          			}
          		}
          		return null;
          	}
          
          	private final static HashMap<String, Object> actions = new HashMap<String, Object>();
          	private final static HashMap<String, Method> methods = new HashMap<String, Method>();
          
          }
          posted on 2013-08-19 16:41 禮物 閱讀(638) 評論(0)  編輯  收藏

          只有注冊用戶登錄后才能發表評論。

          網站導航:
           
          主站蜘蛛池模板: 沙洋县| 富民县| 左贡县| 金乡县| 驻马店市| 准格尔旗| 马公市| 高要市| 武山县| 博乐市| 镇远县| 墨竹工卡县| 大港区| 辛集市| 革吉县| 吐鲁番市| 司法| 庄浪县| 海晏县| 仁化县| 额济纳旗| 旌德县| 新巴尔虎右旗| 邓州市| 集安市| 谢通门县| 南漳县| 襄垣县| 罗田县| 巩留县| 汾西县| 竹山县| 祥云县| 河北区| 肃宁县| 宁波市| 彰武县| 吕梁市| 安新县| 商都县| 喀喇沁旗|