建模的由来:
将指定的xml字符串当作对象来使用
建模的好处:
只需要调用指定的方法就可以完成预定的字符串获取,提高代码的复用性
建模的思路:
分析需要被建模的文件中有哪几个对象
每个对象拥有的行为以及属性
定义对象从小到大(从里到外)
通过23中设计模式中的工厂模式,解析xml生产出指定对象
案例:
配置文件内容:
<?xml version="1.0" encoding="UTF-8"?>
<!--
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>
定义对象(从里到外):
ForwardModal类:
package com.entity;
import java.io.Serializable;
public class ForwardModal implements Serializable{
private String name;
private String path;
private boolean redirect;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
public boolean isRedirect() {
return redirect;
}
public void setRedirect(boolean redirect) {
this.redirect = redirect;
}
public void setRedirect(String redirect) {
this.redirect = Boolean.parseBoolean(redirect);
}
@Override
public String toString() {
return "ForwardModal [name=" + name + ", path=" + path + ", redirect=" + redirect + "]";
}
}
ActionModal类 :
package com.entity;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
public class ActionModal implements Serializable{
private String path;
private String type;
private Map<String, ForwardModal> forwardModals = new HashMap<String, ForwardModal>();
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public void put(ForwardModal forwardModal) {
if(forwardModals.containsKey(forwardModal.getName())) {//键位重复时声明异常
throw new RuntimeException("该键位["+forwardModal.getName()+"]已存在");
}
//键位未重复则加入集合中
this.forwardModals.put(forwardModal.getName(), forwardModal);
}
public ForwardModal get(String name) {
if(null==this.forwardModals.get(name)) {//当传入的键位不存在时
throw new RuntimeException("该键位["+name+"]不存在");
}
return this.forwardModals.get(name);
}
@Override
public String toString() {
return "ActionModal [name=" + path + ", type=" + type + ", forwardModals=" + forwardModals + "]";
}
}
ConfigModal类:
package com.entity;
import java.io.InputStream;
import java.io.Serializable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
public class ConfigModal implements Serializable{
private Map<String, ActionModal> actionModals = new HashMap<String, ActionModal>();
private static final String PATH="/config.xml";
public void put(ActionModal actionModal) {
if(this.actionModals.containsKey(actionModal.getPath())) {
throw new RuntimeException("该键位["+actionModal+"]已存在");
}
this.actionModals.put(actionModal.getPath(), actionModal);
}
public ActionModal get(String path) {
if(null==this.actionModals.get(path)) {
throw new RuntimeException("该键位["+path+"]不存在");
}
return this.actionModals.get(path);
}
//私有化构造函数
private ConfigModal() {}
public static ConfigModal createConfigModal(String path) throws Exception {
//创建configModal
ConfigModal configModal = new ConfigModal();
InputStream is;
if(null==path) {
is=ConfigModal.class.getResourceAsStream(PATH);
}else {
is=ConfigModal.class.getResourceAsStream(path);
}
SAXReader sax = new SAXReader();
Document doc = sax.read(is);
List<Element> actionElements = doc.selectNodes("/config/action");
for (Element actionElement : actionElements) {
ActionModal actionModal = new ActionModal();
actionModal.setPath(actionElement.attributeValue("path"));
actionModal.setType(actionElement.attributeValue("type"));
List<Element> forwardElements = actionElement.selectNodes("forward");
for (Element forwardElement : forwardElements) {
ForwardModal forwardModal = new ForwardModal();
forwardModal.setName(forwardElement.attributeValue("name"));
forwardModal.setPath(forwardElement.attributeValue("path"));
forwardModal.setRedirect(forwardElement.attributeValue("redirect"));
actionModal.put(forwardModal);
}
configModal.put(actionModal);
}
return configModal;
}
}
测试代码:
package com.zking;
import com.entity.ActionModal;
import com.entity.ConfigModal;
public class Demo {
public static void main(String[] args) throws Exception {
//取出action中path值为/regAction的action
ConfigModal createConfigModal = ConfigModal.createConfigModal(null);
ActionModal actionModal = createConfigModal.get("/regAction");
System.out.println(actionModal);
}
}
测试输出:
WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by org.dom4j.io.SAXContentHandler (file:/D:/264/Y1/J2E/J2E_05/src/lib/dom4j-1.6.1.jar) to method com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser$LocatorProxy.getEncoding()
WARNING: Please consider reporting this to the maintainers of org.dom4j.io.SAXContentHandler
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release
ActionModal [name=/regAction, type=test.RegAction, forwardModals={success=ForwardModal [name=success, path=/login.jsp, redirect=true], failed=ForwardModal [name=failed, path=/reg.jsp, redirect=false]}]