Easyui03完成前端页面的动态Tree

第一步: 完善后台接口

1.搭建MVC框架一定测试数据库连接
2.web.xml中配置----中央控制器----中文乱码器----过滤器
  • 2.2中央控制器比人博客在Easyui里面有

  • 2.2中文乱码器源码

      package com.zking.test.util;
    
      import java.io.IOException;
      import java.util.Iterator;
      import java.util.Map;
      import java.util.Set;
      
      import javax.servlet.Filter;
      import javax.servlet.FilterChain;
      import javax.servlet.FilterConfig;
      import javax.servlet.ServletException;
      import javax.servlet.ServletRequest;
      import javax.servlet.ServletResponse;
      import javax.servlet.http.HttpServletRequest;
      import javax.servlet.http.HttpServletResponse;
      
      /**
       * 中文乱码处理
       * 
       */
      public class EncodingFiter implements Filter {
    
      private String encoding = "UTF-8";// 默认字符集
    
      public EncodingFiter() {
      	super();
      }
    
      public void destroy() {
      }
    
      public void doFilter(ServletRequest request, ServletResponse response,
      		FilterChain chain) throws IOException, ServletException {
      	HttpServletRequest req = (HttpServletRequest) request;
      	HttpServletResponse res = (HttpServletResponse) response;
    
      // 中文处理必须放到 chain.doFilter(request, response)方法前面
      res.setContentType("text/html;charset=" + this.encoding);
      if (req.getMethod().equalsIgnoreCase("post")) {
      	req.setCharacterEncoding(this.encoding);
      } else {
      	Map map = req.getParameterMap();// 保存所有参数名=参数值(数组)的Map集合
      	Set set = map.keySet();// 取出所有参数名
      	Iterator it = set.iterator();
      	while (it.hasNext()) {
      		String name = (String) it.next();
      		String[] values = (String[]) map.get(name);// 取出参数值[注:参数值为一个数组]
      		for (int i = 0; i < values.length; i++) {
      			values[i] = new String(values[i].getBytes("ISO-8859-1"),
      					this.encoding);
      		}
      	}
      }
    
      chain.doFilter(request, response);
      }
    
      public void init(FilterConfig filterConfig) throws ServletException {
      	String s = filterConfig.getInitParameter("encoding");// 读取web.xml文件中配置的字符集
      	if (null != s && !s.trim().equals("")) {
      		this.encoding = s.trim();
      	}
      }
    
      }
    
  • 2.3过滤器

  •   package com.zking.test.util;
      
      import java.math.BigDecimal;
      
      import javax.servlet.ServletContextEvent;
      import javax.servlet.ServletContextListener;
      
      import org.apache.commons.beanutils.ConvertUtils;
      import org.apache.commons.beanutils.converters.BigDecimalConverter;
      import org.apache.commons.beanutils.converters.DoubleConverter;
      import org.apache.commons.beanutils.converters.FloatConverter;
      import org.apache.commons.beanutils.converters.IntegerConverter;
      import org.apache.commons.beanutils.converters.LongConverter;
      import org.apache.commons.beanutils.converters.ShortConverter;
      
      public class BeanUtilsListener implements ServletContextListener {
    
      //解决在数据库空值默认值0转换为null;
      @Override
      public void contextDestroyed(ServletContextEvent arg0) {
      }
    
      @Override
      public void contextInitialized(ServletContextEvent arg0) {
      	System.out.println("BeanUtilsListener contextInitialized");
      	ConvertUtils.register(new IntegerConverter(null), Integer.class);
      	ConvertUtils.register(new FloatConverter(null), Float.class);
      	ConvertUtils.register(new DoubleConverter(null), Double.class);
      	ConvertUtils.register(new LongConverter(null), Long.class);
      	ConvertUtils.register(new BigDecimalConverter(null), BigDecimal.class);
      }
    
    }
    
  • 2.4配置web.xml

      <?xml version="1.0" encoding="UTF-8"?>
      <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
    <display-name>Easyui03Tree_parent-type</display-name>
     <!-- 配置监听器 -->
    <listener>
    	<listener-class>com.zking.test.util.BeanUtilsListener</listener-class>
    </listener>
    
    <!-- 中文乱码器 -->
    <filter>
    	<filter-name>EncodingFiter</filter-name>
    	<filter-class>com.zking.test.util.EncodingFiter</filter-class>
    </filter>
    <filter-mapping>
    	<filter-name>EncodingFiter</filter-name>
    	<url-pattern>/*</url-pattern>
    </filter-mapping>
    
    <!-- 中央控制器 -->
    <servlet>
    	<servlet-name>ActionServlet</servlet-name>
    	<servlet-class>com.zking.mvc.framework.ActionServlet</servlet-class>
    </servlet>
    <servlet-mapping>
    	<servlet-name>ActionServlet</servlet-name>
    	<url-pattern>*.action</url-pattern>
    </servlet-mapping>
    <welcome-file-list>
      <welcome-file>index.html</welcome-file>
      <welcome-file>index.htm</welcome-file>
      <welcome-file>index.jsp</welcome-file>
      <welcome-file>default.html</welcome-file>
      <welcome-file>default.htm</welcome-file>
      <welcome-file>default.jsp</welcome-file>
    </welcome-file-list>
    
3.WebContent/WEB-INF/lib添加需要的mvc,jar,jackson包
4.在WebContent创建common文件然后创建head.jsp
<%@page import="java.io.PrintWriter"%>
<%@ page language="java" contentType="text/html; charset=utf-8"
    pageEncoding="utf-8"%>
<% 
	//自动化项目名
	String ctx=request.getContextPath();
	request.setAttribute("ctx", ctx);
	out.println("<script>var ctx = '"+ctx+"';</script>");	
%>

<link rel="stylesheet" type="text/css" href="${ctx}/js/jquery-easyui-1.5.1/themes/default/easyui.css">
<link rel="stylesheet" type="text/css" href="${ctx}/js/jquery-easyui-1.5.1/themes/icon.css">

<script src="${ctx}/js/jquery-easyui-1.5.1/jquery.min.js"></script>
<script src="${ctx}/js/jquery-easyui-1.5.1/jquery.easyui.min.js"></script>
5.通用分页Util/PageBean
package com.zking.test.util;

import java.io.Serializable;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

public class PageBean implements Serializable {

//页码
private int page=1;
//每页显示条数
private int rows=10;
//总记录数
private int total=0;
//是否分页标记
private boolean pagination=true;
//上一次请求的路径
private String url;
//请求参数Map集合
private Map<String,String[]> map;

public String getUrl() {
	return url;
}
public void setUrl(String url) {
	this.url = url;
}
public Map<String, String[]> getMap() {
	return map;
}
public void setMap(Map<String, String[]> map) {
	this.map = map;
}
public int getPage() {
	return page;
}
public void setPage(int page) {
	this.page = page;
}
public int getRows() {
	return rows;
}
public void setRows(int rows) {
	this.rows = rows;
}
public int getTotal() {
	return total;
}
public void setTotal(int total) {
	this.total = total;
}
public boolean isPagination() {
	return pagination;
}
public void setPagination(boolean pagination) {
	this.pagination = pagination;
}

//重载setPage/setRows/setPagination方法
public void setPage(String page) {
	if(null!=page&&!"".equals(page))
		this.page=Integer.parseInt(page);
}
public void setRows(String rows) {
	if(null!=rows&&!"".equals(rows))
		this.rows=Integer.parseInt(rows);
}
public void setPagination(String pagination) {
	if(null!=pagination&&!"".equals(pagination))
		this.pagination=Boolean.parseBoolean(pagination);
}

public void setRequest(HttpServletRequest req) {
	//获取前端提交的page/rows/pagination参数
	String page=req.getParameter("page");
	String rows=req.getParameter("rows");
	String pagination=req.getParameter("pagination");
	
	//设置属性
	this.setPage(page);
	this.setPagination(pagination);
	this.setRows(rows);
	
	//设置上一次请求的路径
	//第一次请求:
	//http://localhost:8080/项目名/请求路径.action?page=1
	//第二次请求:下一页  page=2
	//项目名+请求路径.action
	//req.getContextPath()+req.getServletPath()==req.getRequestURI()
	this.url=req.getRequestURI();
	
	//获取请求参数集合
	// checkbox name='hobby'
	// Map<String,String[]> hobby==key  value==new String[]{"篮球","足球",..}
	this.map=req.getParameterMap();
}

/**
 * 获取分页的起始位置
 * @return
 */
public int getStartIndex() {
	//第1页:(1-1)*10  ==0    limit 0,10
	//第2页:(2-1)*10  ==10   limit 10,10
	//..
	return (this.page-1)*this.rows;
}

//获取末页、上一页、下一页
/**
 * 获取末页
 * @return
 */
public int getMaxPager() {
	int maxPager=this.total/this.rows;
	if(this.total%this.rows!=0)
		maxPager++;
	return maxPager;
}

/**
 * 获取上一页
 * @return
 */
public int getPreviousPager() {
	int previousPager=this.page-1;
	if(previousPager<=1)
		previousPager=1;
	return previousPager;
}

/**
 * 获取下一页
 * @return
 */
public int getNextPager() {
	int nextPager=this.page+1;
	if(nextPager>getMaxPager())
		nextPager=getMaxPager();
	return nextPager;
}
@Override
public String toString() {
	return "PageBean [page=" + page + ", rows=" + rows + ", total=" + total + ", pagination=" + pagination
			+ ", url=" + url + ", map=" + map + "]";
}

}
6.在Dao/BaseDAO方法中实现
package com.zking.test.dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;

import com.zking.test.util.DBAccess;
import com.zking.test.util.PageBean;

public class BaseDAO<K> {

// 回调接口:遍历ResultSet
public static interface Callback<K> {
	public List<K> foreach(ResultSet rs) throws SQLException;
}

/**
 * 通用分页查询
 * 
 * @param sql
 *            普通sql
 * @param pageBean
 *            分页工具类
 * @param callback
 *            回调接口,用来遍历rs结果集
 * @return
 */
public List<K> executeQuery(String sql, PageBean pageBean, Callback<K> callback) {
	Connection conn = null;
	PreparedStatement pstmt = null;
	ResultSet rs = null;

	// 1. 查满足条件的总记录数
	if (null != pageBean && pageBean.isPagination()) {
		try {
			conn = DBAccess.getConnection();// 获得connection
			String countSql = this.getCountSql(sql);
			System.out.println(countSql);
			pstmt = conn.prepareStatement(countSql);
			rs = pstmt.executeQuery();
			if (rs.next()) {
				int total = rs.getInt(1);
				pageBean.setTotal(total);
			}
		} catch (Exception e) {
			throw new RuntimeException(e);
		} finally {
			DBAccess.close(null, pstmt, rs);// 没有关闭
		}
	}

	// 2.查指定页码并满足条件的记录
	try {
		if (null == conn) {
			conn = DBAccess.getConnection();
		}
		String pageSql = sql;
		if (null != pageBean && pageBean.isPagination()) {
			pageSql = this.getPageSql(sql, pageBean);
		}
		pstmt = conn.prepareStatement(pageSql);
		rs = pstmt.executeQuery();
		return callback.foreach(rs);
	} catch (Exception e) {
		throw new RuntimeException(e);
	} finally {
		DBAccess.close(conn, pstmt, rs);
	}

}

/**
 * 将普通sql转换成查全部的sql
 */
private String getCountSql(String sql) {
	return "select count(*) from (" + sql + ") t1";
}

/**
 * 将普通sql转换成支持分页的sql
 */
private String getPageSql(String sql, PageBean pageBean) {
	return sql + " limit " + pageBean.getStartIndex() + ", " + pageBean.getRows();
}
}
7.TreeNodeDao是否实现通用分页
package com.zking.test.dao;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import com.zking.test.entity.TreeNode;

public class TreeNodeDao extends BaseDAO<TreeNode>{

public List<TreeNode> listTreeNodeid(TreeNode treeNode){
	String sql="select * from t_tree_node where 1=1";
	//判断枝节点是否有子节点
	if(null==treeNode.getParentNodeId()) {
		sql+=" and parent_node_id is null";
	}else {
		sql+=" and parent_node_id="+treeNode.getParentNodeId();
	}
	sql+=" order by position";
	// 返回sql语句,是否分页,然后再返回一个回掉函数Callback带泛型<TreeNode>
	return this.executeQuery(sql, null, new Callback<TreeNode>() {
		@Override
		public List<TreeNode> foreach(ResultSet rs) throws SQLException {
			List<TreeNode> list = new ArrayList<TreeNode>();
			TreeNode n=null;
			while(rs.next()) {
				n= new TreeNode();
				n.setTreeNodeId(rs.getInt("tree_node_id"));
				n.setTreeNodeName(rs.getString("tree_node_name"));
				n.setTreeNodeType(rs.getInt("tree_node_type"));
				
				n.setParentNodeId(rs.getInt("parent_node_id"));
				n.setUrl(rs.getString("url"));
				n.setPosition(rs.getInt("position"));
				
				n.setIcon(rs.getString("icon"));
				list.add(n);
			}
			return list;
		}
	});
}

}
8.action/TreeNodeAction将json发送前端页面显示动态数据
package com.zking.test.action;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.zking.mvc.framework.Action;
import com.zking.mvc.framework.ModelDriver;
import com.zking.test.dao.TreeNodeDao;
import com.zking.test.entity.TreeNode;

public class TreeNodeAction extends Action implements ModelDriver<TreeNode> {
	//接收参数的TreeNode对象
	private TreeNode treeNode = new TreeNode();
	//调用TreeNodeDao方法
	private TreeNodeDao treeNodeDao = new TreeNodeDao();

public TreeNodeAction() {
}
@Override
public TreeNode getModel() {
	return treeNode;
}
@Override
public String execute(HttpServletRequest request, HttpServletResponse response)
		throws ServletException, IOException {
	List<TreeNode> listTreeNodeid = treeNodeDao.listTreeNodeid(treeNode);
	//以前使用作用域request向jsp传递数据
			//request.setAttribute("treeNodeslist", treeNodeslist);
			
			//1.将数据转换easyui的ture插件需要的格式id/text/state/attributes
			List<Map<String, Object>> listmap = new ArrayList<Map<String,Object>>();
			for(TreeNode treeNode : listTreeNodeid) {
				Map<String, Object> map = new HashMap<String,Object>();
				map.put("id", treeNode.getTreeNodeId());
				map.put("text", treeNode.getTreeNodeName());
				map.put("state", treeNode.islefe() ? "open":"closed");//closed(枝)能继续打开||open(叶)无法打开
				listmap.add(map);
			}
			
			//2.现在用treeNodeslist转换为json字符串,然后使用io流将json字符串传递给客户端
			ObjectMapper  mapper =  new ObjectMapper();
			String json = mapper.writeValueAsString(listmap);
			//io流
			PrintWriter out = response.getWriter();
			//将list集合发送给客户端
			out.println(json);//print+ln换行,解决了缓存问题
			
			// 一定要return null页面跳转
			//重点:如果返回了结果码那么页面就会重定向和转发,然后结果集就拿不到了。
			return null;
}

}
9.配置action向前端提供的接口
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE config[
  <!ELEMENT config (action+)>
  <!ELEMENT action (forward*)>
  <!ELEMENT forward EMPTY>
  
  <!ATTLIST action
    path CDATA #REQUIRED
    type CDATA #REQUIRED
  >
  
  <!ATTLIST forward
  	name CDATA #REQUIRED
    path CDATA #REQUIRED
    redirect (true|false) "false"
  >
]>
<config>
	<action path="/treeNodeAction" type="com.zking.test.action.TreeNodeAction">
	</action>
	<!-- 
	<action path="/numberAction" type="com.zking.oa.action.NumberAction">
		<forward name="a" path="/a.jsp" redirect="false"/>
		<forward name="b" path="/b.jsp" redirect="true"/>
	</action>
	<action path="/studentAction" type="com.zking.oa.action.StudentAction">
	</action>
	 -->
</config>

第二步: 使用postmain进行测试

在这里插入图片描述

------ 获取到了结果集就开始下一步

第三步: 完成前端页面的动态tree

1.WebContent下创建index.jsp编写前端动态树数据
<%@ page language="java" contentType="text/html; charset=utf-8"
    pageEncoding="utf-8"%>
<%@include file="/common/head.jsp"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>easyui01课程</title>
<script type="text/javascript">
$(function() {
	var url = ctx+"/treeNodeAction.action";
	$('#tt').tree({    
		//向Action请求数据
	    url:url,
	    //在请求加载远程数据之前触发,返回false可以取消加载操作。
	    onBeforeLoad:function(node){
	    	console.log(node);
	    	//如果打开枝节点node就不为空就会进入判断
	    	if(node){//java:if(ture|false),js:if(任意值),--if(v)--v=null,v=''  默认为false;
	    		//重新给url指向的路径
	    		var url2 = ctx + "/treeNodeAction.action?parentNodeId="+node.id;
	    		console.log(url2);
	    		//返回树控件属性。
	    		var options = $('#tt').tree("options");
	    		console.log(options);
	    		//找到原来路径修改为新的路径
	    		options.url = url2;
	    	}
	    }
	});  
});
</script>
</head>
<body class="easyui-layout">   
    <!-- 北 -->
   <div data-options="region:'north',title:'XXX管理系统',split:true" style="height:100px;"></div>   
   <!-- 西  -->
    <div data-options="region:'west',title:'导航栏',split:true" style="width:15%;">
    	<ul id="tt" class="easyui-tree"></ul> 
    </div>   
       <!-- 中 -->
    <div data-options="region:'center',border:false" style="padding:5px;background:#eee;padding: 0;margin: ">
		<div class="easyui-tabs" data-options="fit:true,tabWidth:112">
			<div title="Home" style="padding:10px" data-options="closable:true">
				<iframe scrolling="no" frameborder="0" src="a.jsp" width="99%" height="99%"></iframe>
			</div>
			<div title="Maps" style="padding:10px">
				<p>Maps Content.</p>
			</div>
			<div title="Journal" style="padding:10px">
				<p>Journal Content.</p>
			</div>
			<div title="History" style="padding:10px">
				<p>History Content.</p>
			</div>
			<div title="References" style="padding:10px">
				<p>References Content.</p>
			</div>
			<div title="Contact" data-options="tabWidth:110" style="padding:10px">
				<p>Contact Content.</p>
			</div>
		</div>
    </div>  
</body> 
</html>
2.iframe获取父页面元素
<iframe scrolling="no" frameborder="0" src="" width="99%" height="99%"></iframe>

《结果》在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值