新的项目需要对用户权限进行控制,经过和项目经理商量我们决定使用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,如需转载请自行联系原作者