新的项目需要对用户权限进行控制,经过和项目经理商量我们决定使用XML文件存储权限代码和层次关系,这样比较方便也便于维护,使用SAX读取XML文件,我发现在读取的时候可以顺便将XML文件中的内容封装为实体Bean,便于页面使用JSTL进行迭代。
一、XML结构
我的XML结构为这样的
<root>
<basemenu id="" name="基础信息" url="#">
<menu id="" name="仓储位设置" url="#">
<submenu id="" name="仓库设置" url="">
<button id="" name="查询" url="#"></button>
</submenu>
</menu>
</basemenu>
</root>
二、实体Bean
针对这种结构我定义了几个实体Bean
看名字就能知道对应的XML标记的名字,由于所有的标记都有三个属性,我就将他们抽象出来定义了一个超类,
public class WMSBean {
public String id;
public String name;
public String url;
//省略set,get方法
下面依次是各个实体类的代码
public class RootBean {
public List<BaseMenuBean> baseMenuBean;
public class BaseMenuBean extends WMSBean {
public List<MenuBean> menuBean;
public class MenuBean extends WMSBean {
public List<Submenu> submenu;
public class Submenu extends WMSBean {
public List<Button> button;
public class Button extends WMSBean {
}
实体类内部成员变量使用了List类型,这样的话可以存放多个相同的标记(Button在最底层没有成员变量)
三、解析XML并封装
开始看我解析XML的代码了
public class ParseXml extends DefaultHandler {
public RootBean rootBean;//成员变量
public ParseXml() {
super();
this.rootBean = new RootBean();//初始化
}
public void startElement(String namespaceURI, String localName,//此方法读取XML元素
String name, Attributes atts) {
WMSBean bean = this.doInstanceBean(name);//调用doInstanceBean方法
for (int i = 0; i < atts.getLength(); i++) {//对实体Bean进行初始化
if ("id".equals(atts.getLocalName(i))) {
bean.setId(atts.getValue(i));
}
if ("name".equals(atts.getLocalName(i))) {
bean.setName(atts.getValue(i));
}
if ("url".equals(atts.getLocalName(i))) {
bean.setUrl(atts.getValue(i));
}
}
this.doSetBean(bean);//将实体Bean进行封装
}
//根据名称初始化一个实体对象,并返回,这个方法充分的利用了java的多态特性
private WMSBean doInstanceBean(String name) {
if ("basemenu".equals(name)) {
return new BaseMenuBean();
} else if ("menu".equals(name)) {
return new MenuBean();
} else if ("submenu".equals(name)) {
return new Submenu();
} else if ("button".equals(name)) {
return new Button();
} else {
}
return null;
}
private void doSetBean(WMSBean bean) {
if (bean instanceof BaseMenuBean) {//判断其类型
this.rootBean.setBaseMenuBean((BaseMenuBean) bean);
}
else if (bean instanceof MenuBean) {
List<BaseMenuBean> baseMenuBeanList = this.rootBean .getBaseMenuBean();
baseMenuBeanList.get(baseMenuBeanList.size() - 1).setMenuBea( (MenuBean) bean);
//获得List中最后一个对想,并add
}
else if (bean instanceof Submenu) {
List<BaseMenuBean> baseMenuBeanList = this.rootBean .getBaseMenuBean();
BaseMenuBean baseMenuBean = baseMenuBeanList.get(baseMenuBeanList
.size() - 1);
List<MenuBean> menuBeanList = baseMenuBean.getMenuBean();
menuBeanList.get(menuBeanList.size() - 1).setSubmenu((Submenu) bean);
}
else if (bean instanceof Button) {//依次重复相同操作
List<BaseMenuBean> baseMenuBeanList = this.rootBean .getBaseMenuBean();
BaseMenuBean baseMenuBean = baseMenuBeanList.get(baseMenuBeanList
.size() - 1);
List<MenuBean> menuBeanList = baseMenuBean.getMenuBean();
MenuBean menuBean = menuBeanList.get(menuBeanList.size() - 1);
List<Submenu> submenuList = menuBean.getSubmenu();
submenuList.get(submenuList.size() - 1).setButton((Button) bean);
} else { }
}
public RootBean getRootBean() {
return rootBean;
}
public void setRootBean(RootBean rootBean) {
this.rootBean = rootBean;
}
}
四、调用、运行
public ModelAndView menu(HttpServletRequest request, HttpServletResponse response) throws Exception {
SAXParserFactory sf = SAXParserFactory.newInstance();
SAXParser sp = sf.newSAXParser();//初始化对象
ParseXml parseXml = new ParseXml();//初始化对象
sp.parse(new InputSource(this.getServletContext().getRealPath(
"/WEB-INF/quanxian.xml")), parseXml);
//通过Servlet容器获得xml文件,将我们的parseXml作为参数传递进去
RootBean bean = parseXml.getRootBean();//获得parseXml内部的成员变量RootBean
return new ModelAndView().addObject("RootBean", bean);
//添加进request对象中并返回到页面以供迭代
}
五、迭代
为了代码的简练我省去了一部分html代码,只保留了迭代RootBean部分的代码,使用JSTL进行迭代,即简单又不出错。
<c:forEach items="${RootBean.baseMenuBean}" var="base">
<li id="${base.id}"><a href="${base.url}">${base.name}</a>
<ul>
<c:forEach items="${base.menuBean}" var="menu">
<li id="${menu.id}"><a href="${menu.url}">${menu.name}</a>
<ul>
<c:forEach items="${menu.submenu}" var="sub">
<li id="${sub.id}"><a href="${sub.url}">${sub.name}</a>
<ul>
<c:forEach items="${sub.button}" var="button">
<li id="${button.id}"><a href="${button.url}">${button.name}</a></li>
</c:forEach>
</ul>
</li>
</c:forEach>
</ul>
</li>
</c:forEach>
</ul>
</li>
</c:forEach>
总结,不是所有的应用都要按照某某方式去做,我没有使用Digester但是我封装的实体也比较灵活,至少很符合我的使用,这已经足够了。
本文转自 tony_action 51CTO博客,原文链接:http://blog.51cto.com/tonyaction/46873,如需转载请自行联系原作者