模仿 Struts2 核心流程:配置解析 → Action 映射管理 → 反射實例化 → 請求分發 → 結果視圖跳轉。
<framework>
<actions>
<action name="loginAction" class="cn.hq.Action.LoginAction">
<result name="success">success.jsp</result>
<result name="login">index.jsp</result>
</action>
</actions>
</framework>
// Action 接口
public interface Action {
String execute(HttpServletRequest req, HttpServletResponse resp) throws Exception;
String SUCCESS = "success";
String LOGIN = "login";
}
// ActionMapping 封裝 action 節點
public class ActionMapping {
private String name, className;
private Map<String, String> results = new HashMap<>();
// getter/setter/addResult
}
// ActionMappingManager 解析 XML 管理映射 (dom4j)
public class ActionMappingManager {
private Map<String, ActionMapping> mappings = new HashMap<>;
public ActionMappingManager(String[] configFiles) { ... 初始化解析 ... }
public ActionMapping getMapping(String name) { return mappings.get(name); }
}
// ActionManager 反射獲取 Action 實例
public class ActionManager {
public static Action getAction(String className) {
Class<?> clazz = Thread.currentThread().getContextClassLoader().loadClass(className);
return (Action) clazz.newInstance();
}
}
public class MyServlet extends HttpServlet {
private ActionMappingManager manager;
@Override public void init(ServletConfig config) {
String cfg = config.getInitParameter("config");
String[] files = cfg != null ? cfg.split(",") : new String[]{"Framework.xml"};
manager = new ActionMappingManager(files);
}
protected void doPost(HttpServletRequest req, HttpServletResponse resp) {
String path = req.getRequestURI().substring(req.getContextPath().length());
String actionName = path.substring(1, path.lastIndexOf('.')); // /loginAction.do -> loginAction
ActionMapping mapping = manager.getMapping(actionName);
Action action = ActionManager.getAction(mapping.getClassName());
String result = action.execute(req, resp);
String view = mapping.getResults().get(result);
resp.sendRedirect(view);
}
}
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>cn.hq.servlet.MyServlet</servlet-class>
<init-param>
<param-name>config</param-name>
<param-value>Framework.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
public class LoginAction implements Action {
public String execute(HttpServletRequest req, HttpServletResponse resp) {
if ("1".equals(req.getParameter("name")) && "1".equals(req.getParameter("pwd"))) {
return SUCCESS;
}
return LOGIN;
}
}