一、自定义拦截器:
     继承AbstractInterceptor,覆写intercept方法,实现功能逻辑,最后在Struts.xml文件中配置了自定义拦截器,首先自定义拦截器栈,

  1. <!-- 配置拦截器 -->
  2. <interceptors>
  3. <interceptor name="cusInterceptor" class="com.swust.interceptor.CusInterceptor"/>
  4. <!-- 声明拦截器栈 -->
  5. <interceptor-stack name="myStack">
  6. <interceptor-ref name="cusInterceptor"/>
  7. <interceptor-ref name="defaultStack"/>
  8. </interceptor-stack>
  9. </interceptors>

然后自定义拦截器栈,使得单个包内或者整个项目经过自定义拦截器

  1. <!-- 默认本包中的所有action都要经过myStack这个拦截器栈 -->
  2. <default-interceptor-ref name="myStack"></default-interceptor-ref>

最后可以利用自定义拦截器通过地址栏的地址进行用户相应的权限控制

  1. package com.swust.oa.interceptor;
  2.  
  3. import com.swust.oa.domain.User;
  4. import com.swust.oa.struts2.action.LoginLogoutAction;
  5.  
  6. import com.opensymphony.xwork2.ActionContext;
  7. import com.opensymphony.xwork2.ActionInvocation;
  8. import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
  9.  
  10. @SuppressWarnings("serial")
  11. public class CheckPrivilegeInterceptor extends AbstractInterceptor {
  12.  
  13. public String intercept(ActionInvocation invocation) throws Exception {
  14. System.out.println("CheckPrivilegeInterceptor.intercept()");
  15.  
  16. // 获取当前的登录用户
  17. User user = (User) ActionContext.getContext().getSession().get("user");
  18. // 获取当前访问的URL(action的名称),需要处理一下UI后缀
  19. String url = invocation.getProxy().getActionName();
  20. if (url.endsWith("UI")) {
  21. url = url.substring(0, url.length() - 2);
  22. }
  23. // 一、未登录的情况
  24. if (user == null) {
  25. if (invocation.getProxy().getAction() instanceof LoginLogoutAction) {
  26. // 如果正在使用登录用功能,则放行
  27. return invocation.invoke(); // 放行
  28. } else {
  29. // 如果不是正在使用登录功能,则转到登录页面
  30. return "loginUI";
  31. }
  32. }
  33. // 二、已登录的情况
  34. else {
  35. if (user.hasPrivilegeByUrl(url)) {
  36. // 如果有权限,则放行
  37. return invocation.invoke(); // 放行
  38. } else {
  39. // 如果没有有权,则转到错误页面
  40. return "privilegeError";
  41. }
  42. }
  43. }
  44. }

二、修改struts原生标签
    在项目源文件下新建和框架中相同的包名和文件名称,同时修改源文件,之后即可实现覆盖元标签功能

  1. package org.apache.struts2.views.jsp.ui;
  2.  
  3. import javax.servlet.http.HttpServletRequest;
  4. import javax.servlet.http.HttpServletResponse;
  5. import javax.servlet.jsp.JspException;
  6.  
  7. import org.apache.struts2.components.Anchor;
  8. import org.apache.struts2.components.Component;
  9.  
  10. import com.swust.oa.domain.User;
  11.  
  12. import com.opensymphony.xwork2.util.ValueStack;
  13.  
  14. /**
  15. * @see Anchor
  16. */
  17. public class AnchorTag extends AbstractClosingTag {
  18.  
  19. private static final long serialVersionUID = -1034616578492431113L;
  20.  
  21. protected String href;
  22. protected String includeParams;
  23. protected String scheme;
  24. protected String action;
  25. protected String namespace;
  26. protected String method;
  27. protected String encode;
  28. protected String includeContext;
  29. protected String escapeAmp;
  30. protected String portletMode;
  31. protected String windowState;
  32. protected String portletUrlType;
  33. protected String anchor;
  34. protected String forceAddSchemeHostAndPort;
  35.  
  36. @Override
  37. public int doEndTag() throws JspException {
  38. // 获取当前登录用户
  39. User user = (User) pageContext.getSession().getAttribute("user");
  40. // 获取当前访问的URL(actionName),就是本类的action属性值
  41. // >> 去掉参数
  42. String url = action;
  43. int pos = url.indexOf('?');
  44. if (pos > -1) {
  45. url = url.substring(0, pos); // 去掉参数
  46. }
  47. // >> 去掉UI后缀(例:userAction_addUI就是userAction_add权限)
  48. if (url.endsWith("UI")) {
  49. url = url.substring(0, url.length() - 2);
  50. }
  51.  
  52. if (user.hasPrivilegeByUrl(url)) {
  53. return super.doEndTag(); // 正常显示超链接标签,并继续执行后面的内容
  54. } else {
  55. return EVAL_PAGE; // 不显示当前的超链接标签,只继续执行后面的内容
  56. }
  57. }
  58.  
  59. public Component getBean(ValueStack stack, HttpServletRequest req, HttpServletResponse res) {
  60. return new Anchor(stack, req, res);
  61. }
  62.  
  63. protected void populateParams() {
  64. super.populateParams();
  65.  
  66. Anchor tag = (Anchor) component;
  67. tag.setHref(href);
  68. tag.setIncludeParams(includeParams);
  69. tag.setScheme(scheme);
  70. tag.setValue(value);
  71. tag.setMethod(method);
  72. tag.setNamespace(namespace);
  73. tag.setAction(action);
  74. tag.setPortletMode(portletMode);
  75. tag.setPortletUrlType(portletUrlType);
  76. tag.setWindowState(windowState);
  77. tag.setAnchor(anchor);
  78.  
  79. if (encode != null) {
  80. tag.setEncode(Boolean.valueOf(encode).booleanValue());
  81. }
  82. if (includeContext != null) {
  83. tag.setIncludeContext(Boolean.valueOf(includeContext).booleanValue());
  84. }
  85. if (escapeAmp != null) {
  86. tag.setEscapeAmp(Boolean.valueOf(escapeAmp).booleanValue());
  87. }
  88. if (forceAddSchemeHostAndPort != null) {
  89. tag.setForceAddSchemeHostAndPort(Boolean.valueOf(forceAddSchemeHostAndPort).booleanValue());
  90. }
  91. }
  92.  
  93. public void setHref(String href) {
  94. this.href = href;
  95. }
  96.  
  97. public void setEncode(String encode) {
  98. this.encode = encode;
  99. }
  100.  
  101. public void setIncludeContext(String includeContext) {
  102. this.includeContext = includeContext;
  103. }
  104.  
  105. public void setEscapeAmp(String escapeAmp) {
  106. this.escapeAmp = escapeAmp;
  107. }
  108.  
  109. public void setIncludeParams(String name) {
  110. includeParams = name;
  111. }
  112.  
  113. public void setAction(String action) {
  114. this.action = action;
  115. }
  116.  
  117. public void setNamespace(String namespace) {
  118. this.namespace = namespace;
  119. }
  120.  
  121. public void setMethod(String method) {
  122. this.method = method;
  123. }
  124.  
  125. public void setScheme(String scheme) {
  126. this.scheme = scheme;
  127. }
  128.  
  129. public void setValue(String value) {
  130. this.value = value;
  131. }
  132.  
  133. public void setPortletMode(String portletMode) {
  134. this.portletMode = portletMode;
  135. }
  136.  
  137. public void setPortletUrlType(String portletUrlType) {
  138. this.portletUrlType = portletUrlType;
  139. }
  140.  
  141. public void setWindowState(String windowState) {
  142. this.windowState = windowState;
  143. }
  144.  
  145. public void setAnchor(String anchor) {
  146. this.anchor = anchor;
  147. }
  148.  
  149. public void setForceAddSchemeHostAndPort(String forceAddSchemeHostAndPort) {
  150. this.forceAddSchemeHostAndPort = forceAddSchemeHostAndPort;
  151. }
  152. }

三、懒加载

一般懒加载通过设置hibernate配置文件设置相关实体属性的懒加载为false,如果要实现延迟关闭
session,例如要在一次请求结束之后才实现关闭session,则可以在web.xml文件中添加如下拦截器:

  1. <filter>
  2. <filter-name>OpenSessionInViewFilter</filter-name>
  3. <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
  4. </filter>
  5. <filter-mapping>
  6. <filter-name>OpenSessionInViewFilter</filter-name>
  7. <url-pattern>*.action</url-pattern>
  8. </filter-mapping>

即可以实现延迟关闭session的功能。

四、js插件制作

  1. (function($){
  2. $.confirm = function(json){
  3. $("a").each(function(){
  4. if($(this).text()=="删除"){
  5. $(this).unbind("click");
  6. $(this).bind("click",function(){
  7. json.callback();
  8. return window.confirm(json.message);
  9. });
  10. }
  11. });
  12. }
  13. })(&);

如上所述就可以制作出删除提示窗口插件

五、js面向对象写法
    分析所需要的方法的实现步骤,然后利用面向对象的方法将该需求进行分解,将该需求作为对象来对待,对其进行模块划分,一般涉及数据区,方法区两大类,最后在$().ready(function(){...});中进行调用该对象的相应方法完成相应的功能。

  1. var tree = {
  2. zTree: '',
  3. pNode: '',
  4. setting: {
  5. isSimpleData: true,
  6. treeNodeKey: "mid",
  7. treeNodeParentKey: "pid",
  8. showLine: true,
  9. root: {
  10. isRoot: true,
  11. nodes: []
  12. },
  13. callback: {
  14. /**
  15. * @param {Object} event
  16. * 鼠标事件
  17. * @param {Object} treeId
  18. * 树的容器ID
  19. * @param {Object} treeNode
  20. * 当前点击的节点
  21. */
  22. expand: function(event, treeId, treeNode){
  23. tree.pNode = treeNode;
  24. tree.loadNodeByPNODE();
  25. }
  26. }
  27. },
  28. /**
  29. * 1、回调函数是由服务器端触发的,什么时候执行由服务器决定
  30. * 2、回调函数是由jQuery内核调用的
  31. * 3、客户端存在两个线程
  32. * 4、如果在js代码中,有一些代码要用到回调函数中的数据,那么这些代码必须放在回调函数中
  33. */
  34. loadTree: function(){
  35. $.post("menuitemAction_getAllMenuitem.action", null, function(data){
  36. $("#tree").zTree(tree.setting, data.menuitemList);
  37. });
  38. },
  39. /**
  40. * 一般情况下,如果一段代码中要用到一个变量,而这个变量的值是在回调函数中赋值的,这个时候一定要确保使用该函数时,回调函数已经执行了
  41. */
  42. loadRootNode: function(){
  43. var parameter = {
  44. pid: 0
  45. };
  46. $.post("menuitemAction_showMenuitemsByPid.action", parameter, function(data){
  47. tree.zTree = $("#tree").zTree(tree.setting, data.menuitemList);
  48. });
  49. },
  50. /**
  51. * 该方法是在点击父节点的+号的时候执行的,这就意味着在执行该方法的时候,树早已经生成了,所以才能用tree.zTree;
  52. */
  53. loadNodeByPNODE: function(){
  54. var parameter = {
  55. pid: tree.pNode.mid
  56. };
  57. if (!tree.zTree.getNodeByParam("pid", tree.pNode.mid)) {
  58. $.post("menuitemAction_showMenuitemsByPid.action", parameter, function(data){
  59. /**
  60. * 把查询出来的子节点追加到父节点上
  61. */
  62. tree.zTree.addNodes(tree.pNode, data.menuitemList, true);
  63. });
  64. }
  65. }
  66. };
  67. $().ready(function(){
  68. //tree.loadTree();
  69. tree.loadRootNode();
  70. //该方法能输出什么不确定:因为在执行该代码的时候,回调函数执行不确定,所以tree.zTree的赋值也不确定
  71. //alert(tree.zTree);
  72. });

上面就是在界面加载zTree的JS面向对象写法

六、通过泛型技术对Dao层和控制层的提取重构,提高代码的复用性;

  1. public BaseDao<T>{
  2. private Class classes;
  3. public BaseDao(){
  4. ParameterizedType parameterizedType = (ParameterizedType)this.getClass().getGenericSuperclass();
  5. this.classes = (Class) parameterizedType.getActualTypeArguments()[0];
  6. }
  7. }

七、用OGNL可以调用类的方法用于权限的设计
在实体User中有hasPrivilegeByName()方法用于判断用户的权限,则ognl可以直接调用该方法在页面中进行判断

  1. <%-- 显示一级菜单 --%>
  2. <s:if test="#session.user.hasPrivilegeByName(name)">
  3. <li class="level1">
  4. <div onClick="menuClick(this);" class="level1Style">
  5. <img src="${pageContext.request.contextPath}/style/images/MenuIcon/${icon}" class="Icon" />
  6. ${name}
  7. </div>
  8. </li>
  9. </s>

八、适配器设计模式

  1. public interface UserService extends BaseService{
  2.  
  3. public void geT();
  4.  
  5. public void getUserById();
  6. }
  1. public UserServiceImple exends BaseServiceimpl implements UserService{
  2. public User getUserById(){}
  3. }
  1. public BaseServiceImpl implements BaseService{
  2. public T getT(){}
  3. }

其中UserServiceImpl充当了适配器的角色,用来提供Userservice中所需要而BaseService中没有的方法

OA项目总结的更多相关文章

  1. 【Java EE 学习 67 上】【OA项目练习】【JBPM工作流的使用】

    OA项目中有极大可能性使用到JBPM框架解决流程控制问题,比如请假流程.报销流程等等. JBPM:JBoss Business Process Management,翻译过来就是业务流程管理.实际上就 ...

  2. [deviceone开发]-企业OA项目开源分享

    一.简介 是一个真实的企业OA项目改造的开源项目,几乎涵盖了所有常用的组件,包括环信实现在线聊天等功能,类似微信的朋友圈功能,自定义的智能搜索等,而且这个是真实的通过Http链接后台web服务,里面很 ...

  3. 01传智_jbpm与OA项目_整体项目架构

    oA项目: 项目结构如下:

  4. 基于SSH2的OA项目1.0_20161206_需求分析与框架搭建

    1. SSH项目 OA项目,办公自动化,将公司的数据,文档,流程实现在系统中的管理. 降低人员交流过程中的成本.提高办公的效率. 2 .系统管理 主要实现系统权限的管理,不同的用户登陆后看到菜单项不一 ...

  5. OA项目实战(二) 开发准备

    上次的博文OA系统实践(一) 概述中,我们已经了解了OA的相关概念.从本次博文开始,我们做一个简单的OA实例. 在OA开发之前,有几个工作们需要提前做.一个是对需求进行分析,另一个是对开发环境进行选择 ...

  6. 第一周博客之二---OA项目环境搭建及开发包部署

    OA项目环境搭建 一个项目想要能够在开发人员打包好项目包之后进行测试,就必须进行项目测试环境的搭建,要根据开发工程师的开发环境采用不同的测试环境,以下只是浅谈下Java项目OA(办公自动化平台)的环境 ...

  7. OA项目_环境搭建

    OA项目现在要做成微服务,用的框架是springboot,所用的编程工具是idea,maven,做为一个程序员最关心的就是我需要在那个架包中编写代码,我们只需关注domain,repository,s ...

  8. 修改struts2自定义标签的源代码,在原有基础上增加功能(用于OA项目权限判断,是否显示某个权限)

    OA项目在做权限判断时  原始方式: 现在完成的功能 :通过改变struts2自定标签源代码   在原有的基础上  增加判断权限的功能  而页面上使用标签的方式 还是下图 步骤: 打开文件 搜索< ...

  9. 搭建OA项目环境及卸载指南

    一.项目介绍 1).JDK是什么? 全称:Java Development Kit 中文名:java开发工具包 作用:提供java项目的运行环境         JDK安装 a.jdk.jre 安装 ...

  10. oa项目面试准备

    熟悉项目在ssm框架下的编程流程,了解mysql html spring springmvc mybatis技术.了解过springboot编程. 在上个寒假跟着培训机构用springboot框架编写 ...

随机推荐

  1. VC使用双缓冲避免绘图闪烁的正确使用方法【转】

    使用内存DC绘图,然后实现双缓冲,避免绘图闪烁,这个小技术简单但很有效.但是仍然有很多人说使用了双缓冲,图片却仍然有闪烁,分析了几个这样的例子,发现 其实不是双缓冲的技术问题,而是使用者没有正确理解和 ...

  2. 【HTML5】DOMContentLoaded事件

    这个事件是从HTML中的onLoad的延伸而来的,当一个页面完成加载时,初始化脚本的方法是使用load事件,但这个类函数的缺点是仅在所有资源都完全加载后才被触发,这有时会导致比较严重的延迟,开发人员随 ...

  3. Android Popupwindow 拖动

    版本号:1.0 日期:2014.4.29 版权:© 2014 kince 转载注明出处 关于View的拖动大家应该比較了解了,比方对一个控件IamgeView拖动,或者一个视图View拖动,实现方式也 ...

  4. 网页播放音频、视频文件——基于web的html 5的音乐播放器(转载)

    文章转载自:开源中国社区 [http://www.oschina.net] 想通过手机客户端(支持 Android.iPhone 和 Windows Phone)访问开源中国:请点这里 HTML5 是 ...

  5. 字符串分割--Java中String.split()用法

    转载自:http://blog.163.com/zs_note/blog/static/199386112201110804233558/ 在java.lang包中有String.split()方法, ...

  6. xmanager 使用

    linux 上安装xterm windows上启动命令: /usr/bin/xterm -ls -display $DISPLAY

  7. qt检测网络连接状态【只能检测和路由器的连接,不能测试到外网的连接】

    #include <QCoreApplication>#include <QDebug>#include <QTextStream>#include <QDi ...

  8. 解决一个Android Studio gradle的小问题

    自从Android Studio有了gradle之后,就经常有问题,最近在Ubuntu上用Android Studio的时候就遇到一个问题,每次项目目录更改了,Import项目,打开项目,还是新建项目 ...

  9. ObjectiveC 文件操作一

    1,引用和使用文件 NSFileManager 是一个单例对象,在mac应用中可以获取任何地址,在IOS中获取的是相对应的应用程序的地址.可以使用 defaultManager 来得到当前应用程序地址 ...

  10. 谷歌日志库GLog 使用说明

    1 引用头文件 加载库 #include <glog/include/logging.h> #pragma comment(lib,"libglog.lib") 2 初 ...