建模的由来
就是将指定的xml字符串当作对象来操作 如果说当对一个指定的xml格式字符串完成了建模操作,好处在于,只需要调用指定的方法就可以完成预定的字符串获取;
什么是建模
简单来说创建实体类的过程就叫做建模。
1.建模的思路
1.1分析需要被建模的文件中有几个对象(就是xml文件中的节点)
1.2每个对象里的属性
1.3然后设计工厂模式,解析xml产生出指定的对象
2.建模的好处
将代码封装,提高代码的复用性,有利于项目后期的维护。
3.视例代码
首先要知道需求:
获取<config> 下<action> 属性path="/loginAction" 下的<forward>属性为path="/main.jsp"
然后对xml文件进行分析。(代码如下)
<!-- config标签:可以包含0~N个action标签 -->
<config>
<!-- action标签:可以饱含0~N个forward标签 path:以/开头的字符串,并且值必须唯一 非空 type:字符串,非空 -->
<action path="/regAction" type="test.RegAction">
<!-- forward标签:没有子标签; name:字符串,同一action标签下的forward标签name值不能相同 ; path:以/开头的字符串
redirect:只能是false|true,允许空,默认值为false -->
<forward name="failed" path="/reg.jsp" redirect="false" />
<forward name="success" path="/login.jsp" redirect="true" />
</action>
<action path="/loginAction" type="test.LoginAction">
<forward name="failed" path="/login.jsp" redirect="false" />
<forward name="success" path="/main.jsp" redirect="true" />
</action>
</config>
分析如下:
config-->ConfigMOdel类
action-->ActionModel类
forward-->ForwardModel类
分析好然后我们就要来写代码了。
3.1建类
3.2类中的属性和方法
将xml文件下的每个节点中的属性当做属性封装起来。
3.2.1ConfigModel类
package com.zking.mymvc.framework;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class ForwardModel {
private String name;
private String path;
private String redirect;
//用正则表达式写一个path要求
private static Pattern pattern = Pattern.compile("^/.+$");
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPath() {
return path;
}
public void setPath(String path) {
//设置之前判定path是否符合规则
Matcher matcher =pattern.matcher(path);
boolean b = matcher.matches();
if(!b) {
throw new RuntimeException("ForwardModel.path[" + path + "]必须以/开头");
}
this.path = path;
}
public String getRedirect() {
return redirect;
}
public void setRedirect(String redirect) {
this.redirect = redirect;
}
}
3.2.2ActionModel类
package com.zking.mymvc.framework;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class ActionModel {
private String path;
private String type;
//为什么用map
//action中有forward的子元素
private Map<String, ForwardModel> forwards=new HashMap<>();
//用正则表达式写一个path要求
private static Pattern pattern = Pattern.compile("^/.+$");
public String getPath() {
return path;
}
public void setPath(String path) {
//设置之前判定path是否符合规则
Matcher matcher =pattern.matcher(path);
boolean b = matcher.matches();
if(!b) {
throw new RuntimeException("ActionModel.path["+ path +"]必须以/开头");
}
this.path = path;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public void addForward(ForwardModel forward) {
if(forwards.containsKey(forward.getName())) {
//如果有异常抛出异常。
throw new RuntimeException("ActionModel[" + path + "]/forwardModel.name[" + forward.getName() + "]已存在");
}
forwards.put(forward.getName(), forward);
}
public ForwardModel findForward(String name) {
if(!forwards.containsKey(name)) {
throw new RuntimeException("ActionModel[" + path + "]/forwardModel.name[" + name + "]不存在");
}
return forwards.get(name);
}
}
3.2.3ForwardModel类
package com.zking.mymvc.framework;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class ForwardModel {
private String name;
private String path;
private String redirect;
//用正则表达式写一个path要求
private static Pattern pattern = Pattern.compile("^/.+$");
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPath() {
return path;
}
public void setPath(String path) {
//设置之前判定path是否符合规则
Matcher matcher =pattern.matcher(path);
boolean b = matcher.matches();
if(!b) {
throw new RuntimeException("ForwardModel.path[" + path + "]必须以/开头");
}
this.path = path;
}
public String getRedirect() {
return redirect;
}
public void setRedirect(String redirect) {
this.redirect = redirect;
}
}
3.2.4ConfigFactary类
package com.zking.mymvc.framework;
import java.io.InputStream;
import java.util.List;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
/**
* 读取config.xml放入建好的模型中
* @author Administrator
*
*/
public class ConfigFactory {
//定义一个变量用来记录config文件
private static String configName="/config.xml";
private static ConfigModel configModel=new ConfigModel();
//开始读取 (为什么要用statit:因为config.xm文件只需要解析一次)
//static特点:只会在类加载的过程中执行一次。
static {
InputStream in = ConfigFactory.class.getResourceAsStream(configName);
SAXReader reader = new SAXReader();
//读取流
try {
Document doc = reader.read(in);
//获取根元素
Element rootElement = doc.getRootElement();
//读取action
List<Element> actions = rootElement.selectNodes("action");
//遍历
for(Element action:actions) {
String path = action.attributeValue("path");
String type = action.attributeValue("type");
//new一个ActionModel对象
ActionModel actionModel = new ActionModel();
actionModel.setPath(path);
actionModel.setType(type);
//继续读取下面的子元素
List<Element> forwards = action.selectNodes("forward");
for(Element forward:forwards) {
String name = forward.attributeValue("name");
String fpath = forward.attributeValue("path");
String redirect = forward.attributeValue("redirect");
ForwardModel forwardModel = new ForwardModel();
forwardModel.setName(name);
forwardModel.setPath(fpath);
forwardModel.setRedirect(redirect);
//forward是action的子元素所以要加到action中。
actionModel.addForward(forwardModel);
}
configModel.addAction(actionModel);
}
} catch (DocumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static ConfigModel getConfigModel() {
return configModel;
}
public static void main(String[] args) {
ConfigModel configModel = getConfigModel();
ActionModel actionModel = configModel.findAction("/loginAction");
ForwardModel forwardModel = actionModel.findForward("success");
System.out.println(forwardModel.getPath());
}
}
代码运行结果:
在这过程中遇到一个错误:
这个错误是因为config.xml放到了和类同一个包下了导致执行过程中没能读取到xml文件所以Document 为null;所以一定要细心。
总结:以面向对象的编程思维来对xml文件来进行解析,把xml文件里的类容写成Model对象。