`

动态扩展struts-menu

阅读更多
前端时间把struts-menu扩展成动态从数据库中读取的方式,遇到了一些问题,归纳如下:
从上面的资料不难看出要动态构造sturts-menu菜单只需要构造出符合
struts-menu中需要用的menuComponent,并把这些menuComponen添加到
MenuRepository中,设置MenuRepository的displayers,并把MenuRepository
存入到容器中,那么只要在jsp中指定MenuRepository和displayer以及是否需要
权限控制即可以打印出菜单了。路子已经有了,第一部要做的就是构造这个list,
官方例子为了方便演示将持久层和业务层放在一起了,我是分开做的:构造自定义
的Menu对象,如下为所需的属性,struts-menu的menuComponent的属性要比这些多很多,需要的可以自己查查看。
Model层
Menu对象所需属性:
private String parentName; 
 
private String name;
 
private String title; 
 
private String description; 
 
private String location;
 
private String roles;
service层:
1)interface:
public interface MenuManager {
 
 /**
  * 通过menuList构造MenuRepository来生成struts-menu
  * @return MenuRepository
  */
 public MenuRepository getMenuRepository();
}
2)impl
public class MenuManagerImpl implements MenuManager {
 
 private AcegiCacheManager acegiCacheManager;
 
 private ResourcesDao resourcesDao;
 public AcegiCacheManager getAcegiCacheManager() {
  return acegiCacheManager;
 }
 public void setAcegiCacheManager(AcegiCacheManager acegiCacheManager) {
  this.acegiCacheManager = acegiCacheManager;
 }
 public ResourcesDao getResourcesDao() {
  return resourcesDao;
 }
 public void setResourcesDao(ResourcesDao resourcesDao) {
  this.resourcesDao = resourcesDao;
 }
 
 /**
  * 从数据库中读取资源构造Menu的list对象
  * @return menuList
  */
 private List getMenuList(){
  List menuList = new ArrayList();
  Menu menu = null;
  Resources res = null;
  String roles;
  String parentId;
  String parentName;  
  List ressList = resourcesDao.getResourcesByType(com.wonder.cdc.oa.service.security.Constants.RESOURCE_URL);
  if(ressList != null){
   for(int i = 0; i < ressList.size(); i++){
    res = (Resources)ressList.get(i);
    menu = new Menu();
    if(!StringUtils.isBlank(res.getResource())){
     roles = acegiCacheManager.getPrivsByResources(res.getResource());
    }else{
     roles = "";
    }
    menu.setDescription(res.getDescription());
    if(!StringUtils.isBlank(res.getResource())){
     menu.setLocation(res.getResource());
    }
    menu.setName(res.getName());
    //如果为子类的情况下需存入父类的名字
    if(res.getId().length() > 3){
     parentId = res.getId().substring(0,res.getId().length() - 3);
     parentName = resourcesDao.findNameById(parentId);
     if(!StringUtils.isBlank(parentName)){
      menu.setParentName(parentName);
     }
    }    
    menu.setRoles(roles);
    menu.setTitle(res.getName());
    menuList.add(menu);
   }
  }
  return menuList;
 }
 /**
  * @see com.wonder.cdc.oa.service.MenuManager#getMenuRepository()
  */
 public MenuRepository getMenuRepository(){
  MenuRepository repository = new MenuRepository();
  List list = getMenuList();
  for (int i=0; i < list.size(); i++) {
            MenuComponent menuComponent = new MenuComponent();
            Menu menu = (Menu)list.get(i);
            String name = menu.getName();
            menuComponent.setName(name);
            String parent = (String) menu.getParentName();
            if (parent != null) {
                MenuComponent parentMenu = repository.getMenu(parent);
                if (parentMenu == null) {
                    parentMenu = new MenuComponent();
                    parentMenu.setName(parent);
                    repository.addMenu(parentMenu);
                }
                menuComponent.setParent(parentMenu);
            }
            String title = (String) menu.getTitle();
            menuComponent.setTitle(title);
            String description = (String) menu.getDescription();
            menuComponent.setDescription(description);
            String location = (String) menu.getLocation();
            if(!StringUtils.isBlank(location)){
             menuComponent.setLocation("/" + Constants.APP_NAME + location);
            }           
            String roles = (String) menu.getRoles();
            if(!StringUtils.isBlank(roles)){
             menuComponent.setRoles(roles);
            }
            repository.addMenu(menuComponent);
        }
  return repository;
 }
}
需要注意的,如果location为空则菜单项不显示,如果菜单项没有对应权限那么就不要设置setRoles,如果
setRoles为空字符串,而当前用户又没有空字符串的权限的话那么此菜单项也不显示。
现在数据都准备好了,在何处构造MenuRepository对象合适那?
我想到了3处,但是权衡利弊后我选择了第一项。

1.系统启动时
优点:响应快速
缺点:如果修改resources以及用户相关信息需重新启动系统后修改才可以生效或者修改resources的同时更新application范围内的
MenuRepository,后者导致增加代码量,增加日后系统维护、扩展的难度
疑问:如果在系统正式发布后菜单项不变的情况下是可行的,系统启动MenuRepository对象会常驻内存,仅需要1次访问数据库
2.用户登陆时
优点:菜单灵活度提高,菜单相关信息改变后的响应时间缩短,只需用户再次登陆就可以生效
缺点:每个用户登陆都要构造用户相对应的MenuRepository对象存在会话中,过度占用系统资源
3.定指标签,每个页面包含
优点:菜单灵活度提高,只需刷新页面即可获得最新的菜单项
缺点:每次刷新页面都会访问一次数据库,导致系统性能降低,当然可以通过cache来解决过渡访问数据库的问题,但同时也增加了代码量

我想针对不同的应用可以采取如上3种不同的解决方案(我认为的3种,应该会有更好的),针对我们目前的项目感觉采取第一种方案比较适合
启动时实现就非常的简单了,在实现了ServletContextListener的类的contextInitialized(ServletContextEvent event)中添加如下代码:
        MenuRepository defaultRepository = (MenuRepository) context.getAttribute(MenuRepository.MENU_REPOSITORY_KEY);
        MenuRepository mr = menuManager.getMenuRepository();
        mr.setDisplayers(defaultRepository.getDisplayers());
        context.setAttribute("repository",mr);
这里我遇到了一个问题,context.getAttribute(MenuRepository.MENU_REPOSITORY_KEY)这句返回的是个空
到网上查了一下(http://struts-menu.sourceforge.net/faq.html
发现menu-config.xml文件是通过MenuContextListener加载的,查看了一下web.xml确实声明了这个listener.
我怀疑这里是否能加载上.继续看那个网页发现如果version在2.3以上(我的是2.4)可以通过spring的ioc容器来管理。
修改一下,重起,问题解决了。但是为什么通过listener的方式加载不了我还没有研究,正常来讲应该也是可以的。
剩下的就是页面了:
包含这句就可以了

java 代码
  1. <menu:useMenuDisplayer name="Velocity" config="WEB-INF/classes/cssHorizontalMenu.vm" permissions="rolesAdapter"  
  2. repository="repository">  
  3. <ul id="primary-nav" class="menuList">  
  4.     <li class="pad">&nbsp;</li>  
  5.     <c:if test="${empty pageContext.request.remoteUser}"><li><a href="<c:url value="/login.jsp"/>"  
  6. class="current"><fmt:message key="login.title"/></a></li></c:if>  
  7.     <c:forEach var="menu" items="${repository.topMenus}">  
  8.       <menu:displayMenu name="${menu.name}"/>  
  9.     </c:forEach>  
  10. </ul>  
  11. </menu:useMenuDisplayer>  



分享到:
评论

相关推荐

    struts-menu文件

    8. **自定义扩展**:除了基本功能,开发者还可以通过继承或扩展Struts-menu提供的类,实现自定义的菜单行为,如添加自定义的菜单样式、菜单展开动画等。 9. **优化与性能**:为了提高性能,Struts-menu通常会缓存...

    Struts-Menu实例教程

    此外,如果你需要更复杂的功能,可以通过扩展Struts-Menu的API或实现自定义标签来满足需求。 9. **最佳实践** - 分离菜单配置:将菜单配置文件与业务逻辑代码分离,便于维护和更新。 - 权限设计:合理规划用户...

    使用Struts-menu轻松实现网页菜单.doc

    此版本包含核心库`struts-menu-2.4.1.jar`和Web应用包`struts-menu-2.4.1.war`,后者需解压后获取所需文件。 #### 集成Struts-menu 要将Struts-menu集成到现有的Struts应用中,需遵循以下步骤: 1. **放置JAR包**...

    struts-menu 人门 demo

    Struts-menu入门Demo是一个针对Java Web开发人员的实践教程,主要使用了Struts、Hibernate和MySQL这三大核心技术。这个入门示例提供了一个完整的项目结构,包括数据库文件,使得开发者能够直接运行并理解其工作原理...

    struts-menu例子

    Struts-menu是一个基于Java的开源项目,用于在Struts框架中生成动态菜单。这个例子是Struts-menu的一个实例,提供给需要了解或使用Struts-menu的开发者参考。下面将详细介绍Struts-menu及其在实际开发中的应用,以及...

    Struts-menu例子加视频

    4. **动态菜单**:Struts-menu支持动态生成菜单,这意味着菜单内容可以根据用户角色、权限或业务状态动态变化。这在多用户、多权限的复杂应用中非常实用。 5. **视频教程**:“速动画教程第十四集.exe”和“.rtf”...

    struts-menu-2.0

    Struts-menu-2.0是基于Apache Struts框架的一个扩展组件,主要用于构建Web应用程序的菜单系统。这个组件的出现,极大地简化了在Struts应用中创建动态、可配置的菜单的过程,使得开发者能够更加专注于业务逻辑,而...

    struts-menu权限按钮(项目例子)

    5. **自定义扩展**:Struts-menu提供了丰富的API和扩展点,开发者可以根据需求自定义菜单的行为,如添加新的菜单类型、实现复杂的权限逻辑等。 在实际项目中,Struts-menu的使用可以极大地提高开发效率,减少因权限...

    Struts-menu源码分析(转贴).rar

    Struts-menu是一个基于Apache Struts框架的菜单管理组件,它为Web应用提供了动态生成和管理菜单的功能。在分析Struts-menu的源码时,我们可以深入理解Struts框架的工作原理、MVC模式的应用以及如何实现自定义标签库...

    struts-menu-2.4.3-src

    开发者可以借此机会学习如何使用和扩展Struts Menu,提升其在实际项目中的应用效果。 在实际开发中,Struts Menu 提供了动态生成菜单的能力,可以根据用户的权限和应用状态自动生成相应菜单,这在多用户角色和复杂...

    struts-menu

    通过Struts-menu,我们可以将菜单配置与业务逻辑分离,从而实现更好的可维护性和可扩展性。 首先,让我们深入理解Struts-menu的核心概念和功能: 1. **配置文件**:Struts-menu的配置通常基于XML文件,这些文件...

    Struts-Menu.jar

    StrutsMenu是Struts的一个扩展,它的主要功能是自动生成Web应用的导航菜单,减轻开发者的负担,使他们可以更专注于业务逻辑。 在描述中提到了两个关键的文件: 1. struts-menu-2.4.3.jar:这是StrutsMenu的核心库...

    基于数据库的struts-menu.rar

    这个"基于数据库的struts-menu.rar"学习例子旨在教你如何在Struts框架中实现动态菜单,这些菜单数据是从数据库中获取的,而不是硬编码在程序中。这增加了应用的灵活性,使得管理员能够通过数据库来管理和更新菜单项...

    J2EE 0.4—加入批量CRUD功能、加入框架页面、加入struts-menu等

    3. **Struts Menu**:Struts Menu 是一个开源的Apache Struts插件,用于生成动态菜单。它根据用户权限和业务数据自动生成Web应用的导航菜单,简化了开发过程。Struts Menu 可以与Hibernate、EJB等持久层技术集成,...

    速动画教程系列第14集

    Struts-menu 是一个专门针对Struts框架设计的插件,它允许开发者轻松地创建动态、可配置的树状菜单。这个库提供了一套JSP标签,使得在JSP页面中嵌入和管理树形菜单变得简单。通过定义XML配置文件,你可以指定菜单项...

    初涉StrutsMenu

    StrutsMenu是一个在Java Web开发中常用的开源工具,主要用于生成基于Struts框架的动态菜单。这个工具可以帮助开发者轻松地在Web应用中构建出层次结构清晰、功能强大的菜单系统,节省了手动编写HTML或JSP代码的时间。...

    Struts 1.3.8jar包

    8. **Plug-ins**: Struts 1.3.8 可以通过插件扩展功能,比如 Struts-menu 插件可以方便地生成应用程序的菜单。 9. **Validator Framework**: Struts 1.3.8 包含了验证框架,提供了表单验证的工具,可以在服务器端...

    Struts Menu用户指南

    Struts Menu是Apache Struts框架的一个扩展,它提供了一种简便的方式来创建和管理网页应用的导航结构。通过XML配置文件,开发者可以定义菜单层次、链接、权限控制等,使得菜单的生成与维护变得简单且灵活。 二、...

    Struts-2.1.6整合Tiles2全攻略

    &lt;put-attribute name="menu" value="/tiles/menu.jsp"/&gt; &lt;put-attribute name="footer" value="/tiles/footer.jsp"/&gt; &lt;put-attribute name="title" value="添加书目"/&gt; &lt;put-attribute name="body" value=...

Global site tag (gtag.js) - Google Analytics