第一步: 完善后台接口
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>