Jeecg学习笔记以及代码剖析
来源:互联网 发布:java模拟器安卓版 编辑:程序博客网 时间:2024/06/05 04:08
最近公司让学习JEECG开发平台,刚接触这个平台就喜欢上了,现在接触jeecg差不多有两个礼拜的时间了,下面说一下我对jeecg的理解以及一些简单的代码剖析,还请大神们在此指点一二。
本人邮箱: 229714871@qq.com 欢迎一起来学习交流。
废话不多说,直接进入正题:
涉及到的技术
jeecg是基于Spring MVC+hibernate+UI快速开发库+Spring JDBC+hibernates图形报表+Jquery+Ehcache架构的基础上开发出来的一个可以进行二次开发的平台。
主要功能
-【1】代码生成器:
–生成规范的后台代码+统一风格的前台页面+表单校验。
–页面校验自动生成
–支持主流数据库
–代码生成包括jsp页面,增删改查可以直接配置使用
-【2】查询条件过滤器
–页面加查询条件,只需配置页面对应的查询属性,后台不需要写任何逻辑判断,JEECG查询过滤器机制会自动追加查询条件至HQL
-【3】UI快速开发库
–UI快速开发库,针对WEB UI进行标准封装,页面统一采用UI标签实现功能:数据datagrid、表单校验、Popup、Tab、选择器、自动补全功能等,实现JSP页面零JS,开发维护非常高效
-【4】可以在线的实现各种流程
-【5】表单form组件中可以无需手动添加Check约束,主流的各项都已在生成代码的时候自动加入
-【6】权限问题也可以根据用户调整(这点十分方便
-【7】自定义标签缓存机制(分为永久缓存和临时缓存)
-【8】MiniDao数据持久层
–O/R mapping不用设置xml,零配置便于维护
– 不需要了解JDBC的知识
– SQL语句和java代码的分离
–可以自动生成SQL语句
–接口和实现分离,不用写持久层代码,用户只需写接口,以及某些接口方法对应的sql 它会通过AOP自动生成实现类
–支持自动事务处理和手动事务处理
–支持与hibernate轻量级无缝集成
–MiniDao吸收了Hibernate+mybatis的优势,支持实体维护和SQL分离
–SQL支持脚本语言
代码生成
从http://www.jeecg.org/中
导入你的开发平台(Eclipse or MyEclipse)
配置你的开发环境:
http://www.jeecg.org/forum.php?mod=viewthread&tid=2537&extra=page%3D1
接下来,运行jeecg开发平台(系统默认打开的路径)
在地址栏输入:http://localhost:8080/jeecg/
登录系统
代码生成(此处略,文档中有,可以自行查看)
http://www.jeecg.org/forum.php?mod=viewthread&tid=2764&extra=page%3D1
代码剖析(重要)
前面说了,系统默认打开的页面为:
<welcome-file-list> <welcome-file>/webpage/login/login.jsp</welcome-file> </welcome-file-list>
logn.jsp的配置为:
<form name="formLogin" id="formLogin" action="loginController.do?login" check="loginController.do?checkuser" method="post">
这里会有两个.do的配置,实际上plug-in/login/js/login.js中的的submit函数,实际上你登陆时,点击“登陆”按钮后,先loginController.do?checkuser操作验证用户名密码,然后打开登陆成功页面loginController.do?login
//登录处理函数function Login(orgId) { setCookie(); var actionurl=$('form').attr('action');//提交路径 var checkurl=$('form').attr('check');//验证路径 var formData = new Object(); var data=$(":input").each(function() { formData[this.name] =$("#"+this.name ).val(); }); formData['orgId'] = orgId ? orgId : ""; formData['langCode']=$("#langCode").val(); formData['langCode'] = $("#langCode option:selected").val(); $.ajax({ async : false, cache : false, type : 'POST', url : checkurl,// 请求的action路径 data : formData, error : function() {// 请求失败处理函数 }, success : function(data) { var d = $.parseJSON(data); if (d.success) { loginsuccess(); // todo zhanggm 没有处理多语言,暂时这样判断下吧 var title, okButton; if($("#langCode").val() == 'en') { title = "Please select Org"; okButton = "Ok"; } else { title = "请选择组织机构"; okButton = "确定"; } if (d.attributes.orgNum > 1) { $.dialog({ id: 'LHG1976D', title: title, max: false, min: false, drag: false, resize: false, content: 'url:userController.do?userOrgSelect&userId=' + d.attributes.user.id, lock:true, button : [ { name : okButton, focus : true, callback : function() { iframe = this.iframe.contentWindow; var orgId = $('#orgId', iframe.document).val(); Login(orgId); this.close(); return false; } }], close: function(){ window.location.href = actionurl; } }); } else { setTimeout("window.location.href='"+actionurl+"'", 1000); } } else { if(d.msg == "a"){ $.dialog.confirm("数据库无数据,是否初始化数据?", function(){ window.location = "init.jsp"; }, function(){ // }); } else showError(d.msg); } } });}
执行过程
执行过程为1、判断用户名密码是否正确; 2、将该用户信息加入到在线用户列表/** *检查用户名称 * *@param user *@param req *@return*/@RequestMapping(params ="checkuser")@ResponseBodypublic AjaxJson checkuser(TSUser user, HttpServletRequest req) { HttpSession session = ContextHolderUtils.getSession(); DataSourceContextHolder.setDataSourceType(DataSourceType.dataSource_jeecg);AjaxJson j = new AjaxJson(); int users = userService.getList(TSUser.class).size(); if (users == 0) { j.setMsg("a");//这里前端js会判断该字段,若用户列表为空,则提示是否初始化数据j.setSuccess(false);//该值默认为true} else { TSUser u = userService.checkUserExits(user); if (u != null) { // if (user.getUserKey().equals(u.getUserKey())) {if (true) { message= "用户: " + user.getUserName() + "["+u.getTSDepart().getDepartname() + "]" + "登录成功"; Client client = new Client(); client.setIp(IpUtil.getIpAddr(req)); client.setLogindatetime(new Date()); client.setUser(u); ClientManager.getInstance().addClinet(session.getId(),Client); //添加登陆日志systemService.addLog(message, Globals.Log_Type_LOGIN, Globals.Log_Leavel_INFO); }else{ j.setMsg("请检查U盾是否正确"); j.setSuccess(false); } } else{ j.setMsg("用户名或密码错误!"); j.setSuccess(false); } } return j; }
检查用户
login
根据sessionid获得tuser对象;
2、根据tuser对象获得TSRoleUser的list;
3、根据TSRoleUser获得对应的TSRole;
4、获取一级菜单
5、从cookie中获得默认风格,根据默认风格返回具体的页面名称
/** * 用户登录 * * @param request * @return */ @RequestMapping(params = "login") public String login(ModelMap modelMap,HttpServletRequest request) { DataSourceContextHolder.setDataSourceType(DataSourceType.dataSource_jeecg); TSUser user = ResourceUtil.getSessionUserName(); String roles = ""; if (user != null) { List<TSRoleUser> rUsers = systemService.findByProperty(TSRoleUser.class, "TSUser.id", user.getId()); for (TSRoleUser ru : rUsers) { TSRole role = ru.getTSRole(); roles += role.getRoleName() + ","; } if (roles.length() > 0) { roles = roles.substring(0, roles.length() - 1); } modelMap.put("roleName", roles); modelMap.put("userName", user.getUserName()); modelMap.put("currentOrgName", ClientManager.getInstance().getClient().getUser().getCurrentDepart().getDepartname()); request.getSession().setAttribute("CKFinder_UserRole", "admin");/* // 默认风格 String indexStyle = "shortcut"; Cookie[] cookies = request.getCookies(); for (Cookie cookie : cookies) { if (cookie == null || StringUtils.isEmpty(cookie.getName())) { continue; } if (cookie.getName().equalsIgnoreCase("JEECGINDEXSTYLE")) { indexStyle = cookie.getValue(); } } // 要添加自己的风格,复制下面三行即可// if (StringUtils.isNotEmpty(indexStyle)// && indexStyle.equalsIgnoreCase("bootstrap")) {// return "main/bootstrap_main";// }// if (StringUtils.isNotEmpty(indexStyle)// && indexStyle.equalsIgnoreCase("shortcut")) {// return "main/shortcut_main";// }//// if (StringUtils.isNotEmpty(indexStyle)// && indexStyle.equalsIgnoreCase("sliding")) {// return "main/sliding_main";// } if (StringUtils.isNotEmpty(indexStyle)&& !"default".equalsIgnoreCase(indexStyle)&& !"undefined".equalsIgnoreCase(indexStyle)) { if("ace".equals(indexStyle)){ request.setAttribute("menuMap", getFunctionMap(user)); } log.info("main/"+indexStyle.toLowerCase()+"_main"); return "main/"+indexStyle.toLowerCase()+"_main"; } */ SysThemesEnum sysTheme = SysThemesUtil.getSysTheme(request); if("ace".equals(sysTheme.getStyle())){ request.setAttribute("menuMap", getFunctionMap(user)); } return sysTheme.getIndexPath(); } else { return "login/login"; } }
对应代码
<div id="layout_north_kzmbMenu" style="width: 100px; display: none;"> <!-- 个人信息--> <div onclick="openwindow('<t:mutiLang langKey="common.profile"/>','userController.do?userinfo')"> <t:mutiLang langKey="common.profile"/> </div> <div class="menu-sep"></div> <!-- 修改密码 --> <div onclick="add('<t:mutiLang langKey="common.change.password"/>','userController.do?changepassword','', 550, 200)"> <t:mutiLang langKey="common.change.password"/> </div> <!-- 修改首页风格--> <div class="menu-sep"></div> <div onclick="add('<t:mutiLang langKey="common.change.style"/>','userController.do?changestyle','',550,200)"> <t:mutiLang langKey="common.my.style"/> </div> <!-- 清除缓存 --> <div onclick="clearLocalstorage()"> <t:mutiLang langKey="common.clear.localstorage"/> </div> </div>
具体实现在userController.java中(以下为其中一个信息)
/** * 用户信息 * * @return */ @RequestMapping(params = "userinfo") public String userinfo(HttpServletRequest request) { TSUser user = ResourceUtil.getSessionUserName(); request.setAttribute("user", user); return "system/user/userinfo"; }
导航菜单
/** * 菜单跳转 * * @return */ @RequestMapping(params = "left") public ModelAndView left(HttpServletRequest request) { TSUser user = ResourceUtil.getSessionUserName(); HttpSession session = ContextHolderUtils.getSession(); ModelAndView modelAndView = new ModelAndView(); // 登陆者的权限 if (user.getId() == null) { session.removeAttribute(Globals.USER_SESSION); modelAndView.setView(new RedirectView("loginController.do?login")); }else{ List<TSConfig> configs = userService.loadAll(TSConfig.class); for (TSConfig tsConfig : configs) { request.setAttribute(tsConfig.getCode(), tsConfig.getContents()); } modelAndView.setViewName("main/left"); request.setAttribute("menuMap", getFunctionMap(user)); } return modelAndView; }
// update-start–Author:gaofeng Date:2014-01-09 for:
新增首页风格,一级菜单点击事件的切换操作
$(".shortcut li").live("click",function(){ $(this).find(".imag1").hide(); $(this).find(".imag2").show(); $(this).siblings().find(".imag2").hide(); $(this).siblings().find(".imag1").show(); var navaa=$("#nav .panel"); navaa.hide(); navaa.eq($(this).index()).show();//获取第几个一级菜单,并与之对应 navaa.find(".panel-header").hide(); navaa.find(".panel-body").show().css("border-bottom","0px").css("height","auto"); var winheight = document.body.clientHeight - 157;//计算左侧二级菜单的行高度,以便自动判断是否需要滚动条 navaa.find(".panel-body").css("height",winheight); });
首页
webpage/main/home.jsp
数据库配置
driver=com.mysql.jdbc.Driverurl=jdbc:mysql://localhost:3306/testusername=rootpassword=931110initialSize=4maxActive =10
(先写到这儿,后续补充O(∩_∩)O~)
- Jeecg学习笔记以及代码剖析
- Jeecg 学习笔记
- JEECG学习笔记之初相识
- jeecg笔记
- x264代码剖析笔记
- 代码生成器--jeecg
- C++学习笔记:函数指针语法基础以及函数指针做函数参数的思想剖析
- 设计模式学习笔记以及java代码实现
- google_v8学习笔记:NO1 环境搭建以及代码获取
- Caffe学习笔记1-安装以及代码结构
- Caffe学习笔记1-安装以及代码结构
- Caffe学习笔记1-安装以及代码结构
- 《Python源码剖析》学习笔记
- 《STL源码剖析学习笔记》
- 《STL源码剖析》学习笔记
- jQuery源码剖析学习笔记
- dpdk 定时器学习,例子剖析以及注意事项
- v4l2学习以及代码
- SAP运行时状态条显示
- jquery easy UI datagrid+action错误分析
- Dijkstra 算法——计算有权最短路径(边有权值)
- Merge into的注意点之ORA-30926: 无法在源表中获得一组稳定的行?
- 第一篇CSDN博客,不是技术贴,仅仅纪念下!
- Jeecg学习笔记以及代码剖析
- matlab与数据库的连接
- 【FastDev4Android框架开发】RecyclerView完全解析,让你从此爱上它(二十八)
- 集合框架(ListIterator)
- Android中用ConnectivityManager 判断网络的工具类
- INotifyPropertyChanged接口
- Java发送Email
- FreeMarker入门例子
- Linux创建oracle11实例