学习框架的开头曲: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>
学习框架的第一天,好饭不怕晚,加油!