學習架構的開頭曲:miniMVC
1.目錄結構
core.web中的filter包中ActionFilter 的代碼
package com.mxl.core.web.filter;
import com.mxl.core.web.ActionConfig;
import com.mxl.core.web.ActionContext;
import com.mxl.core.web.ResultConfig;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
public class ActionFilter implements Filter {
//key存儲action元素的name屬性
//value用來存儲action元素的封裝類actionConfig對象
private Map<String, ActionConfig> actionConfigMap = new HashMap<>();
public void init(FilterConfig config) throws ServletException {
Document document = this.getDocument();
//擷取actions.xml中所有的action元素,每一個action元素應該封裝成一個ActionConfig對象
NodeList nodeList = document.getElementsByTagName("action");
for (int i = 0;i < nodeList.getLength();i++){
Element actionEl = (Element) nodeList.item(i);//每一個action元素
String name = actionEl.getAttribute("name");
String className = actionEl.getAttribute("class");
String method = actionEl.getAttribute("method");
ActionConfig actionConfig = new ActionConfig(name, className, method);
actionConfigMap.put(name,actionConfig);
//--------------------------------------------------------
//讀取action元素中的result元素,并封裝成對象
NodeList resultNodeList = actionEl.getElementsByTagName("result");
for (int j = 0;j < resultNodeList.getLength();j++){
Element resultEl = (Element) resultNodeList.item(j);//result元素
String resultName = resultEl.getAttribute("name");
String type = resultEl.getAttribute("type");
String path = resultEl.getTextContent();
ResultConfig resultConfig = new ResultConfig(resultName, type, path);
actionConfig.getResultMap().put(resultName, resultConfig);
}
System.out.println(actionConfigMap);
}
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws ServletException, IOException {
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse resp = (HttpServletResponse) response;
//-------------------------------------------------------------
ActionContext ctx = new ActionContext(req, resp);
ActionContext.setContext(ctx);
//-------------------------------------------------------------
// System.out.println("通用的操作");
//擷取請求的資源名稱
String requestUri = req.getRequestURI().substring(1);
ActionConfig actionConfig = actionConfigMap.get(requestUri);
if (actionConfig==null){
chain.doFilter(req, resp);
return;
}
String className = actionConfig.getClassName();//Action類全限定名
String method = actionConfig.getMethod();//Action類的處理請求的方法
try {
Class actionClass = Class.forName(className);
Object actionObj = actionClass.newInstance();
Method actionClassMethod = actionClass.getMethod(method);
//使用反射調用action方法,傳回邏輯視圖的名稱
Object ret = actionClassMethod.invoke(actionObj);
if (ret!=null){
String viewName = ret.toString();
//根據邏輯視圖名,取出對應的resultConfig對象
ResultConfig resultConfig = actionConfig.getResultMap().get(viewName);
if (resultConfig!=null){
//跳轉方式
String type = resultConfig.getType();
//實體路徑
String path = resultConfig.getPath();
//跳轉方式
if ("dispatcher".equals(type)){
req.getRequestDispatcher(path).forward(req, resp);
}else if ("redirect".equals(type)){
resp.sendRedirect(req.getContextPath()+path);
}
}
}
}catch (Exception e) {
e.printStackTrace();
}
}
public Document getDocument(){
InputStream in = Thread.currentThread().getContextClassLoader()
.getResourceAsStream("actions.xml");
try {
return DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(in);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public void destroy() {
}
}
core.web中的ActionConfig
package com.mxl.core.web;
import java.util.HashMap;
import java.util.Map;
//封裝action元素中的所有資訊
// <action name="employee" class="com.mxl.crm.web.adtion.EmployeeAction" method="excute"></action>
public class ActionConfig {
private String name;//action元素的name屬性
private String className;//action元素的class屬性
private String method;//action元素的method屬性
//action元素中具有多個result元素
private Map<String,ResultConfig> resultMap = new HashMap<>();
public ActionConfig(String name, String className, String method) {
this.name = name;
this.className = className;
this.method = method;
}
public String getName() {
return name;
}
public String getClassName() {
return className;
}
public String getMethod() {
return method;
}
public Map<String, ResultConfig> getResultMap() {
return resultMap;
}
@Override
public String toString() {
return "ActionConfig{" +
"name='" + name + '\'' +
", className='" + className + '\'' +
", method='" + method + '\'' +
", resultMap=" + resultMap +
'}';
}
}
core.web中的ActionContext
package com.mxl.core.web;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
//Action的環境
//封裝了請求和響應對象
public class ActionContext {
private HttpServletRequest request;
private HttpServletResponse response;
//為每一個線程都配置設定一個ActionContext對象的副本,這就安全了
private static ThreadLocal<ActionContext> threadLocal = new ThreadLocal<>();
public static ActionContext getContext() {
return threadLocal.get();
}
public static void setContext(ActionContext context) {
threadLocal.set(context);
}
public ActionContext(HttpServletRequest request, HttpServletResponse response) {
this.request = request;
this.response = response;
}
public HttpServletRequest getRequest() {
return request;
}
public HttpServletResponse getResponse() {
return response;
}
}
core.web中的ResultConfig
package com.mxl.core.web;
//封裝了result元素的資訊
public class ResultConfig {
private String name;//result的name
private String type;//result的type
private String path;//result的文本内容
public ResultConfig(String name, String type, String path) {
this.name = name;
this.type = type;
this.path = path;
}
public String getName() {
return name;
}
public String getType() {
return type;
}
public String getPath() {
return path;
}
public String toString() {
return "ResultConfig{" + "name='" + name + '\'' + ", type='" + type + '\'' + ", path='" + path + '\'' + '}';
}
}
com.mxl.crm.web.adtion中的DepartmentAction
package com.mxl.crm.web.adtion;
import com.mxl.core.web.ActionContext;
import javax.servlet.ServletException;
import java.io.IOException;
public class DepartmentAction {
//傳回邏輯視圖名稱
public String excute() throws ServletException, IOException {
System.out.println("department.........");
return "list";
}
}
com.mxl.crm.web.adtion中的EmployeeAction
package com.mxl.crm.web.adtion;
import com.mxl.core.web.ActionContext;
import javax.servlet.ServletException;
import java.io.IOException;
public class EmployeeAction {
public String excute() throws ServletException, IOException {
System.out.println("employee.........");
return "input";
}
}
actions.xml的内容
<?xml version="1.0" encoding="UTF-8"?>
<actions>
<!--每一個action元素-->
<!--
action元素:表示每一個Action元素
name屬性:請求action對象的資源名稱
class屬性:表示該Action對象的全限定名稱
method屬性:目前請求action類中的某一個方法
-->
<action name="department" class="com.mxl.crm.web.adtion.DepartmentAction" method="excute">
<!--結果視圖-->
<!--result元素表示action請求之後的結果視圖
name屬性:action方法傳回的結果試圖
type屬性:視圖跳轉方式,請求轉發/url重定向
文本内容:結果視圖的實體路徑
-->
<result name="list" type="dispatcher">/WEB-INF/views/department/list.jsp</result>
<result name="input" type="redirect">/WEB-INF/views/department/input.jsp</result>
</action>
<action name="employee" class="com.mxl.crm.web.adtion.EmployeeAction" method="excute">
<result name="list" type="dispatcher">/WEB-INF/views/employee/list.jsp</result>
<result name="input" type="redirect">/WEB-INF/views/employee/input.jsp</result>
</action>
</actions>
web.xml中filter配置
<filter>
<filter-name>ActionFilter</filter-name>
<filter-class>com.mxl.core.web.filter.ActionFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>ActionFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
學習架構的第一天,好飯不怕晚,加油!