最近因为工作需要,学习了ligerui框架。但是,因为在公司,我们只是作为最低层的码农,所以环境都已经搭建好了,我们这些码农平时都是直接拿到工程,然后在别人的框架上不断的ctrl + c、ctrl + v,然后修修补补。所以为了摆脱这种困境,决定自己使用简单的servlet搭建一个ligerui,然后测试下ligerui这玩意到底是怎么跑起来的。
1、下载ligerui相关组件。这个很简单,直接去www.ligerui.com即可找到。
2、使用Eclipse创建一个web工程,然后搭建下面这个目录结构。
3、将ligerui的相关组件加入到WebContent/ligerUI下面,相关组件内容为:
4、通过上面几个步奏,我们已经搭建好了一个最基本ligerui的环境了。我们可以直接访问ligerUI/index.htm,这个虽然是静态的数据,但是可以告诉你相关的文件是否全部导入。在这里需要注意一点,在引用ligerui组件时,jsp中使用全路径来访问这些组件,不要使用相对路径。因为在jsp环境中,forward指令会改变当前路径。
5、模拟一个ligerui的tree组件。在模拟时,我们先观察ligerui的静态数据格式,然后使用面向对象的思想提取出相关组件的javabean即可。
下面的数据是ligerui首页indexdata.js的数据格式,观察数据,然后结合ligerui效果图
{isexpand:"false",text:"布局",children:[ {url:"demos/layout/layoutMinWidth.htm",text:"最小宽度"}, {url:"demos/layout/layoutAutoHeight.htm",text:"自动高度"}, {url:"demos/layout/layoutAutoHeightAndDiff.htm",text:"高度补差"}, {url:"demos/layout/layoutCenterOnly.htm",text:"只显示中间部分"}, {url:"demos/layout/layoutFixedHeight.htm",text:"固定高度"}, {url:"demos/layout/layoutFullHeight.htm",text:"全屏高度"}, {url:"demos/layout/layoutHalfHeight.htm",text:"百分比高度"}, {url:"demos/layout/layoutLeftMiddleOnly.htm",text:"只显示左侧和中间"}, {url:"demos/layout/layoutLeftWidth.htm",text:"限制左边宽度"}, {url:"demos/layout/layoutLeftHide.htm",text:"左边刚开始隐藏"}, {url:"demos/layout/layoutHideToggle.htm",text:"左边右边不允许隐藏"}, {url:"demos/layout/layoutResizeDisable.htm",text:"左边底部不允许调整大小"} ] }
从上面可以看到,一个菜单有子菜单,或者是多个子叶子节点。下面是具体的代码:
package net.itaem.vo; import java.util.List; import net.sf.json.JSONArray; import net.sf.json.JSONObject; /** * 菜单 * * 用来模拟ligerui的菜单 * * */ public class MenuVo { /** * id值 * */ private String id; /** * 菜单名 * */ private String text; /** * 是否打开菜单,默认不打开 * */ private boolean isexpand; /** * 菜单下面的子菜单 * */ private List<MenuVo> children; /** * 该菜单的父亲菜单 * */ private MenuVo parent; //父menu菜单id /** * 菜单的url * */ private String url; public MenuVo(){ } public MenuVo(String id, String text, boolean isexpend){ this.id = id; this.text = text; this.isexpand = isexpend; } public String getUrl() { return url; } public void setUrl(String url) { this.url = url; } public MenuVo getParent() { return parent; } public void setParent(MenuVo parent) { this.parent = parent; } public String getId() { return id; } public void setId(String id) { this.id = id; } public String getText() { return text; } public void setText(String text) { this.text = text; } public boolean isIsexpand() { return isexpand; } public void setIsexpand(boolean isexpand) { this.isexpand = isexpand; } public List<MenuVo> getChildren() { return children; } public void setChildren(List<MenuVo> children) { this.children = children; } /** * 使用递归的方式来生成这个Menu的json格式字符串 * @return 返回该菜单的json格式字符串 * @see MenuVo#menuJson(MenuVo) * */ @Override public String toString() { JSONObject json = new JSONObject(); //生成这个节点的基本数据 json.put("text", text); json.put("isexpand", isexpand); json.put("url", url); if(parent != null){ json.put("pid", parent.getId()); } //生成这个节点的子菜单数据 JSONArray childrenJson = new JSONArray(); if(children != null){ for(MenuVo child: children){ //让每个子menu递归的去生成json数据 childrenJson.add(toJson(child)); } json.put("children", childrenJson); } return json.toString(); } /** * 递归入口 * @see MenuVo#toJson() * */ private String toJson(MenuVo menu){ JSONObject json = new JSONObject(); if(menu.getChildren() != null){ //生成这个菜单节点的基本数据 json.put("text", menu.getText()); json.put("id", menu.getId()); if(menu.getParent() != null){ json.put("pid", menu.getParent().getId()); } json.put("isexpand", menu.isIsexpand()); if(menu.getParent() != null){ json.put("pid", menu.getParent().getId()); } //生成这个菜单节点的子菜单数据 JSONArray childrenJson = new JSONArray(); if(menu.getChildren() != null){ for(MenuVo child: menu.getChildren()){ //让每个子menu递归的去生成json数据 childrenJson.add(toJson(child)); } json.put("children", childrenJson); } }else{ //这个节点不是菜单,是菜单下面的一个具体子节点,该节点已经没有子节点了 json.put("id", menu.getId()); if(menu.getParent() != null){ json.put("pid", menu.getParent().getId()); } json.put("text", menu.getText()); json.put("url", menu.getUrl()); } return json.toString(); } /** * hasCode方法 * 由于业务逻辑需要,重写 * */ @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((children == null) ? 0 : children.hashCode()); result = prime * result + ((id == null) ? 0 : id.hashCode()); result = prime * result + (isexpand ? 1231 : 1237); result = prime * result + ((parent == null) ? 0 : parent.hashCode()); result = prime * result + ((text == null) ? 0 : text.hashCode()); result = prime * result + ((url == null) ? 0 : url.hashCode()); return result; } /** * equals方法 * 由于业务逻辑需要,重写 * */ @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; MenuVo other = (MenuVo) obj; if (children == null) { if (other.children != null) return false; } else if (!children.equals(other.children)) return false; if (id == null) { if (other.id != null) return false; } else if (!id.equals(other.id)) return false; if (isexpand != other.isexpand) return false; if (parent == null) { if (other.parent != null) return false; } else if (!parent.equals(other.parent)) return false; if (text == null) { if (other.text != null) return false; } else if (!text.equals(other.text)) return false; if (url == null) { if (other.url != null) return false; } else if (!url.equals(other.url)) return false; return true; } }
上面我们使用递归的形式来生成每个menu的json数据,因为一个菜单下面可以有N级的子菜单,所以很适合使用递归的方式来解决问题。
下面我们使用servlet来生成一个 10 * 10 * 3的目录菜单。下面是servlet:
package net.itaem.servlet; import java.io.IOException; import java.util.ArrayList; import java.util.List; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import net.itaem.vo.MenuVo; import net.sf.json.JSONArray; public class LigerUiTreeServlet extends HttpServlet{ /** * */ private static final long serialVersionUID = 145235235L; @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doPost(req, resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { JSONArray json = new JSONArray(); //生成一个10 * 10 *3的树 for(int i=0; i<10; i++){ MenuVo menu = new MenuVo(); menu.setText("text" + i); menu.setId(i + ""); //偶数的菜单展开 menu.setIsexpand(false); List<MenuVo> children = new ArrayList<MenuVo>(); for(int j=0; j<10; j++){ MenuVo menu1 = new MenuVo(); menu1.setText("text" + i + j); menu1.setId(i + "" + j); children.add(menu1); menu1.setParent(menu); List<MenuVo> menu1Children = new ArrayList<MenuVo>(); for(int k=0; k<3; k++){ MenuVo menuVo = new MenuVo(); menuVo.setText("text" + i + "" + j + "" + k); menuVo.setId("text" + i+ "" + j + ""+ k); menuVo.setUrl("#"); menuVo.setParent(menu1); menu1Children.add(menuVo); } menu1.setChildren(menu1Children); menu.setChildren(children); } json.add(menu.toString()); System.out.println(menu.toString()); } req.setAttribute("treeData", json.toString()); req.getRequestDispatcher("ligerUI/index.jsp").forward(req, resp); } }
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5"> <display-name></display-name> <servlet> <servlet-name>LigerUiTreeServlet</servlet-name> <servlet-class>net.itaem.servlet.LigerUiTreeServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>LigerUiTreeServlet</servlet-name> <url-pattern>/ligerTree.do</url-pattern> </servlet-mapping> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> </web-app>
总结:从上面的例子我们可以看出,快速搭建一个ligerui环境难度并不高。作为一个java web工程师,我们应该多掌握这种开源框架。虽然上面的例子只是模拟了一个menu树,但是窥斑见豹,我们有了这个例子,其他的ligerui组件也肯定可以搞定了。