⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 actioncontroller.java

📁 Jodd是一个开源的公用Java基础类库
💻 JAVA
字号:
package jodd.servlet;

import java.io.IOException;
import java.util.HashMap;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import jodd.util.ReflectUtil;
import jodd.util.StringUtil;

/**
 * Represents a controller part of mvc2 framework.
 * <p>
 *
 * During initialization, configuration xml file is read and all data are
 * loaded by controller. When request is received, controller will lookup for
 * the adequate <code>ActionServlet.doAction()</code> or defined mapped
 * method to invoke. Depending of the resulting string and the configuration,
 * controller will perform forwarding or redirection to the destination view.
 * <p>
 *
 * Controller allows intercepting of all invoked actions, by using the ActionFilter.
 *
 * @see ActionServlet
 * @see ActionFilter
 */
public class ActionController extends ActionServlet {

	/**
	 * Holds all actions defined in xml configuration files.
	 */
	private HashMap actionsMap = new HashMap();
	/**
	 * Holds all global data.
	 */
	private ActionData global_forwards = new ActionData();
	/**
	 * Global controller ActionFilter.
	 */
	private ActionFilter actionFilter = null;

	// ---------------------------------------------------------------- init

	private String configPath;
	private String configFile;
	private String configFilter;

	/**
	 * Initialization of the controler. Reads all actions xml configuration
	 * files and populates actionsMap; and initialize ActionFilter if defined.
	 *
	 * @param config actionsMap
	 *
	 * @exception ServletException
	 * @see #reload
	 */
	public void init(javax.servlet.ServletConfig config) throws ServletException {
		super.init(config);
		
		// build path for the main config file
		configPath = config.getServletContext().getRealPath("");
		configFile = config.getInitParameter("config");
		configFilter = config.getInitParameter("filter");

		reload();
	}

	/**
	 * Reloads configuration XML files. This method should be used in
	 * developement, since it is not synchronized with the main dispatcher. It
	 * re-reads configuration files and resets all ActionServlet settings, while
	 * server and controller are active. This makes posible to change
	 * configuration without restarting server.
	 */
	public void reload() throws ServletException {
		actionsMap = new HashMap();
		global_forwards = new ActionData();
		ActionControllerUtil.parseFile(actionsMap, global_forwards, configPath, configFile);

		if (configFilter != null) {
			ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
			if (classLoader == null) {
				classLoader = ActionController.class.getClassLoader();
			}
			try {
				Class c = classLoader.loadClass(configFilter);
				actionFilter = (ActionFilter) c.newInstance();
			} catch (Exception ex) {
				actionFilter = null;
			}
		} else {
			actionFilter = null;
		}
	}

	// ---------------------------------------------------------------- doRequest


	/**
	 * Unique request parameter name that holds ActionData for the current
	 * invoked action, as defined in the configuration xml file. It is used
	 * internally.
	 *
	 * @see jodd.servlet.ActionData
	 */
	public static String ACTION_DATA = "jodd.servlet.ActionController.actionData";

	/**
	 * Unique request parameter name that holds action path of the the current
	 * invoked action, as defined in the configuration xml file. It is used
	 * internally.
	 */
	public static String ACTION_PATH = "jodd.servlet.ActionController.actionPath";
	
	/**
	 * Unique <b>global</b> forward name that will be used in case when action is
	 * not mapped to a request.
	 */
	public static String ACTION_NOT_FOUND = "jodd.servlet.ActionController.actionNotFound";
	
	/**
	 * Request dispatcher - the controller.<p>
	 *
	 * The request uri will be processed first. Controller will try to find
	 * specific Action type (defined in actions xml configuration file). Very
	 * first time when action is required its class (child of ActionServlet) will
	 * be loaded and instanced. Next time, actions instance will be found in the
	 * buffer, so actions will be instanced just once (when accessed first time).
	 * <p>
	 *
	 * If Action can not be found, controller will forward to ACTION_NOT_FOUND
	 * global forward mapping.
	 * <p>
	 *
	 * Method doAction() will be invoked on founded action. This method returns a
	 * string that represents a forward name (defined in actions xml
	 * configuration file). Alternatively, if defined so, mapped method will be
	 * invoked.
	 * <p>
	 *
	 * On the end, controller will perform forward or redirection to path defined
	 * with returned forward name string (that doAction() returns), as defined in
	 * configuration file. If forward name can not be found, then global forwards
	 * will be examined. If global forward can not be found, that it is assumed
	 * that no forwards are used, and that returned string represents a page.
	 *
	 * @param request
	 * @param response
	 *
	 * @exception IOException
	 * @exception ServletException
	 */
	public void doRequest(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
		String uri = request.getRequestURI();
		String ctxPath = request.getContextPath();
		int i = uri.indexOf(ctxPath);
		String actionPath = uri.substring(i + ctxPath.length());

		ActionData actionData = (ActionData) actionsMap.get(actionPath);
		if (actionData == null) {
			String actionNotFoundPath = global_forwards.getForwardPath(ACTION_NOT_FOUND);
			if (actionNotFoundPath == null) {
				actionNotFoundPath = ACTION_NOT_FOUND;
			}
			forward(request, response, actionNotFoundPath);
			return;
		}

		// invoke action and get results
		String actionResult = invokeAction(request, response, actionData, actionPath);

		// forward/redirect:
		// split returned forward to uri and parameters.
		// first examine local forwards and then global forwards.
		// if none found, assume it is a normal page.
		if (actionResult != null) {
			String actionResultUri = actionResult;
			String actionResultParams = "";
			i = actionResult.indexOf('?');
			if (i != -1) {
				actionResultUri = actionResult.substring(0, i);
				actionResultParams = actionResult.substring(i + 1);
			}

			String fwdPath = actionData.getForwardPath(actionResultUri);
			if (fwdPath == null) {
				fwdPath = global_forwards.getForwardPath(actionResultUri);
			}
			if (fwdPath == null) {
				fwdPath = actionResultUri;
			}

			// add params to fwdPath
			if (actionResultParams.length() > 0) {
				i = fwdPath.indexOf('?');
				if (i != -1) {
					fwdPath += "&" + actionResultParams;
				} else {
					fwdPath += "?" + actionResultParams;
				}
			}
			if (actionData.isForwardRedirect(actionResultUri)) {
				redirect(request, response, fwdPath);
			} else {
				forward(request, response, fwdPath);
			}
		}
	}


	// ---------------------------------------------------------------- invoke action


	/**
	 * Unique <b>global</b> forward name that will be used in case when action is
	 * not mapped to a request.
	 */
	public static String INVOKE_ACTION_PARAMS = "jodd.servlet.ActionController.invokeActionParams";

	/**
	 * Invoke specified action as it would be invoked by ActionController.
	 *
	 * <p>
	 * NOTE: request parameters are passed from the current request!!!
	 * Instead, they are passed as a HashMap in request attribute under the key:
	 * INVOKE_ACTION_PARAMS.
	 *
	 * @param request    http request
	 * @param response   http response
	 * @param actionPath action path, as defined in configuration xml file
	 *
	 * @return resulting forward String, or ACTION_NOT_FOUND if not founded
	 * @exception IOException
	 * @exception ServletException
	 * @see #doRequest
	 */
	public String invokeAction(HttpServletRequest request, HttpServletResponse response, String actionPath) throws IOException, ServletException {
		String actionPathUri = actionPath;
		int i = actionPath.indexOf('?');
		if (i != -1) {
			actionPathUri = actionPath.substring(0, i);
			HashMap map = ServletUtil.getUrlParams(actionPath);
			request.setAttribute(INVOKE_ACTION_PARAMS, map);
		}

		ActionData actionData = (ActionData) actionsMap.get(actionPathUri);
		if (actionData == null) {
			return ACTION_NOT_FOUND;
		}
		return invokeAction(request, response, actionData, actionPathUri);
	}

	/**
	 * Invokes an request once ActionData has been found.
	 *
	 * @param request    http request
	 * @param response   http responce
	 * @param actionData valida action data
	 * @param actionPath valid action path
	 *
	 * @return action forward string
	 * @exception IOException
	 * @exception ServletException
	 */
	private String invokeAction(HttpServletRequest request, HttpServletResponse response, ActionData actionData, String actionPath) throws IOException, ServletException {

		ActionServlet action = actionData.getAction();

		// is action already loaded ?
		if (action == null) {
			ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
			if (classLoader == null) {
				classLoader = ActionController.class.getClassLoader();
			}
			try {
				Class c = classLoader.loadClass((String) actionData.getType());
				action = (ActionServlet) c.newInstance();
			} catch (Exception ex) {
				action = null;
				throw new ServletException("can't load ActionServlet " + (String)actionData.getType(), ex);
			}
			action.controller = this;		// store controller reference in each action servlet
			actionData.setAction(action);
			actionsMap.put(actionPath, actionData);
		}

		// invoke founded action
		String actionResult = null;
		if (action != null) {
			request.setAttribute(ACTION_DATA, actionData);
			request.setAttribute(ACTION_PATH, actionPath);
			String method = actionData.getMethod();
			
			// invoke filter
			String actionFilterResult = null;
			if (actionFilter != null) {
				actionFilterResult = actionFilter.onAction(request, response, action);
			}
			if (actionFilterResult == null) {
				if (method == null) {
					// invoke default method
					actionResult = action.doAction(request, response);
				} else {
					// invoke mapped metod
					try {
						// faster:
						actionResult = StringUtil.toString(ReflectUtil.invoke(action, method, new Object[] {request, response}, new Class[] {HttpServletRequest.class, HttpServletResponse.class}));
						// slower:
						//actionResult = StringUtil.toString(ReflectUtil.invoke(action, method, new Object[] {request, response}));
					} catch (Exception ex) {
					}
				}
				if (actionFilter != null) {
					actionFilterResult = actionFilter.onAfterAction(request, response, action, actionResult);
					if (actionFilterResult != null) {
						actionResult = actionFilterResult;
					}
				}
			} else {
				actionResult = actionFilterResult;
			}
		}
		return actionResult;
	}

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -