1.需求介绍
2.struts.xml
<?xml version="1.0" encoding="UTF-8"?>
<struts>
<action name="mc" class="com.hd.controller.McController">
<result name="list" type="redirect" >/jstl/mclist.jsp</result>
<result name="add" type="dispacher">/jstl/mc.jsp</result>
</action>
<action name="user" class="com.hd.controller.UserController">
<result name="list" type="redirect" >/jstl/userlist.jsp</result>
<result name="add" type="dispacher">/jstl/user.jsp</result>
</action>
</struts>
3.根据struts.xml创建相关的类:
ActionModel:
package com.hd.model;
import java.util.HashMap;
import java.util.Map;
/**
* Model ActionModel
* @author dpb
*
*/
public class ActionModel {
// 客户端请求的地址
private String name;
// 客户端处理对应的类路径
private String classes;
// 处理后对应的结果集
private Map<String,ResultModel> results = new HashMap<>();
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getClasses() {
return classes;
}
public void setClasses(String classes) {
this.classes = classes;
}
public Map<String, ResultModel> getResults() {
return results;
}
public void setResults(Map<String, ResultModel> results) {
this.results = results;
}
}
ResultModel:
package com.hd.model;
/**
* model ResultModel(调用方法的返回信息)
* @author dpb
*
*/
public class ResultModel {
// 调用方法返回的字符串
private String name;
// 跳转的方式重定向或者请求转发
private String type;
// 要跳转的路径
private String path;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
}
4.创建解析struts.xml的工具类:
导入dom4j的jar包:
成员变量:public Map<String,ActionModel> mappings = new HashMap<>();
// 1.获取到struts.xml文件的路径
String path = ActionMappingManager.class.getResource("/struts.xml").getPath();
// 2.获取SAXReader对象,解析struts.xml
SAXReader reader = new SAXReader();
try {
Document doc = reader.read(path);
// 3.获取根节点
Element root = doc.getRootElement();
// 4.获取相关的子节点action
List<Element> list = root.elements();
for (Element ele : list) {
ActionModel action = new ActionModel();
String actionName = ele.attributeValue("name");
String actionClass = ele.attributeValue("class");
// 获取action下的所有的子节点
List<Element> resultList = ele.elements();
Map<String,ResultModel> results = new HashMap<>();
for (Element resultEle : resultList) {
String resultName = resultEle.attributeValue("name");
String resultType = resultEle.attributeValue("type");
String resultPath = resultEle.getTextTrim();
// 将获取的子节点的信息保存到ResultModel对象中
ResultModel result = new ResultModel(resultName,resultType,resultPath);
results.put(resultName, result);
}
// 将每个action的属性和子节点内容保存到action对象中
action.setName(actionName);
action.setClasses(actionClass);
action.setResults(results);
// 将每个action的内容保存到map集合中
mappings.put(actionName, action);
}
} catch (DocumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
getActionMapping:
/**
* 根据actionName获取解析的对应的action节点内容
* @param actionName
* @return
*/
public ActionModel getActionMapping(String actionName ){
return mappings.get(actionName);
}
5.创建中央控制器Servlet:
1.init()初始化解析xml文件
ActionMappingManager amm ;
/**
* 初始化解析xml文件
*/
public void init(ServletConfig config) throws ServletException {
amm = new ActionMappingManager();
amm.init();
}
具体代码
// 1.获取请求的地址 http://localhost:8081/shop/mc_add
// request.getRequestURI();--> shop/mc_add
String basePath = request.getRequestURI();
// 2.获取地址中最后一个'/'的位置
int opt = basePath.lastIndexOf("/");
// 3.截取字符串
String path = basePath.substring(opt+1);
// 4.拆分,根据'_'拆分
String[] strArray = path.split("_");
String actionName = strArray[0];
String actionMethod = strArray[1];
// 5.根据actionName获取对应的actionModel
ActionModel actionModel = amm.getActionMapping(actionName);
// 6.获取请求对应的class路径
String actionClass = actionModel.getClasses();
try {
// 7.根据反射机制获取对应的实例
Object obj = Class.forName(actionClass).newInstance();
// 8.获取对应的方法
Method method = obj.getClass().getMethod(actionMethod);
// 9.执行对应的方法并获取结果
String resultName = (String) method.invoke(obj);
// 10.根据结果做出相应的跳转
ResultModel resultModel = actionModel.getResults().get(resultName);
// 11.获取跳转的类型
String type = resultModel.getType();
if("redirect".equals(type)){
// 重定向
response.sendRedirect(request.getContextPath()+resultModel.getPath());
}else{
// 请求转发
request.getRequestDispatcher(resultModel.getPath()).forward(request, response);
}
} catch (InstantiationException | IllegalAccessException | ClassNotFoundException | NoSuchMethodException | SecurityException | IllegalArgumentException | InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}