`

一个AJAX+Spring MVC程序的基本原理

阅读更多

程序功能描述:在页面上点击一个“Disable Account”按钮,后台实现Disable某个账号,程序原理如下:

  1. 首先在页面上点击按钮,该按钮的ID是“disableAccountBtn”,找出页面加载的JS文件,在文件中搜索出该ID,发现如下代码:
    $('#disableAccountBtn').click(function() {
    $('#promptWinYes').unbind('click').click(function() {
    $('#promptWin').dialog('close');
    $.getJSON(DISABLE_USER_ACTION, {
    uid : clientId
    }, function(data) {
    switchButtonVisible(false);
    showAlertWin('Warning', DISABLE_USER_CALLBACK_MSG);
    });
    });
    showPromptWin('Warning', DISABLE_USER_MSG);
    }); 
     其中$.getJSON来调用并获取远程的JSON字符串,将其转换为JSON对象,如果成功,则执行回调函数,再从JS中查找DISABLE_USER_ACTION="../disableUser.action. 可见这个调用最终执行了
    ../disableUser.action?uid=userID这个service
  2. 查找后台JAVA代码,在UserManagementController.java中找到如下方法:
    @RequestMapping("/disableUser.action")
    	public ModelAndView disableUser(HttpServletRequest request)
    			throws Exception {
    		return WorkflowController.disableClient(request, clientAction);
    	}
     此处用的是Spring MVC的框架,这个方法用到了clientAction
  3. 再进入WorkflowController.disableClient(request, clientAction)
     public static ModelAndView disableClient(HttpServletRequest httpReq, ClientAction clientAction) {
            String clientId = httpReq.getParameter("uid");
            UserBean sales = resolveSales(httpReq);
    
            String methodId = "{" + sales.getId() + "," + clientId + "," + System.currentTimeMillis() + "}";
            logger.info("/disableUser.action BEGIN " + methodId);
    
            boolean success = true;
            String errorMsg = null;
            try {
                clientAction.disableClient(clientId, sales);
            } catch (Throwable e) {
                logger.error("Failed to disable user " + methodId, e);
                success = false;
                errorMsg = "Server Internal Error. Please contact the system Admin.";
            } finally {
                logger.info("/disableUser.action END " + methodId);
            }
    
            ModelMap model = new ModelMap();
            model.addAttribute("success", success);
            model.addAttribute("errorMsg", errorMsg);
            return new ModelAndView("results", model);
        }
     可见,这个service执行成功后,返回的字符串是
    {"errorMsg":null,"success":true}
  4. 进入clientAction.disableClient(clientId, sales)方法,ClientAction里面有很多方法:
     /**
         * Action to disable an existing client.
         * 
         * @param clientId
         * @param currentUser
         * @throws Exception
         */
        public void disableClient(String clientId, UserBean currentUser) throws Exception {
        	umUserService.createESFDataIfMissing(clientId);
            UserProfile oldUser = umUserService.getUserProfile(clientId);
            disableClient(currentUser, oldUser);
        }
     
  5. 再进入dsiableClient:
     void disableClient(UserBean salesUserBean, UserProfile clientUserProfile) throws Exception {
            if (salesUserBean == null || clientUserProfile == null) {
                return;
            }
            String clientId = clientUserProfile.getUid();
            String clientName = clientUserProfile.getDisplayName();
            UserRequestEntity userEntity = new UserRequestEntity();
            userEntity.setTitle(UMTConstants.USER_PROFILE_TITLE + "(Disable)");
            userEntity.setClientId(clientId);
            userEntity.setClientName(clientName);
            userEntity.setSalesId(salesUserBean.getId());
            userEntity.setSalesName(salesUserBean.getName());
    
            //restore old user profile
            try {
                userEntity.setProfile(JsonUtil.write(clientUserProfile));
            } catch (Exception e) {
                logger.error("Failed to encode user profile into JSON.", e);
            }
    
            umWorkflow.startDisableClientWorkflow(userEntity, UMTConstants.WF_DISABLE_CLIENT);
        } 
  6. 最后调用通用的startDisableClientWorkflow()方法:
     /**
         * Start the workflow to disable an existing client.
         * 
         * @param userEntity the user profile provided by front-end, cannot be null
         */
        public void startDisableClientWorkflow(UserRequestEntity userEntity, String workflowName) throws Exception {
            //1) save records into request tables
            UserRequestEntityHelper.validatePV(userEntity);
            UMRequestEntity umEntity = requestTracker.save(userEntity);
            Long requestId = umEntity.getId();
            logger.info("Saved request entity of [disable] for {" + userEntity.getClientId() + "} as " + requestId);
    
            //2) update request status
            umEntity.setStatus(UMRequestEntity.Status.ESF_DISABLE);
            startWorkflow(requestId, workflowName, umEntity);
        }
     startWorkflow():
     /**
         * Start workflow for request.
         * 
         * @param requestId
         * @param workflowName
         * @param umEntity
         * @throws Exception
         */
        public void startWorkflow(Long requestId, String workflowName, UMRequestEntity umEntity) throws Exception {
            logger.info("Start workflow " + workflowName + " for request [" + requestId + "]");
    
            //1) get workflow and start the process instance
            UMWorkflowBean workflowBean = workflowRepository.findUMWorkflowByName(workflowName);
            String processId = workflowService.startProcessInstance(workflowBean.getProcessName(), new HashMap<String, String>());
    
            //2) update request status
            if (umEntity == null) {
                umEntity = new UMRequestEntity();
                umEntity.setStatus(UserRequestEntity.Status.PROCESSING);
                umEntity.setStatusFlag(0);
            }
            umEntity.setId(requestId);
            umEntity.setWorkflowId(workflowBean.getWorkflowId());
            umEntity.setProcessId(processId);
            requestTracker.update(umEntity);
            logger.info("Started workflow for request [" + requestId + "]");
    
            //3) transit to first state
            Set<String> nextStates = workflowService.findActiveStates(processId);
            StateHandler nextStateHandler = null;
            for (String nextState : nextStates) {
                nextStateHandler = handlerRepository.getByState(nextState);
                if (nextStateHandler != null) {
                    break;
                }
            }
            if (nextStateHandler != null) {
                nextStateHandler.execute(requestId);   
            }
        }
    }
  7.  找到WorkFlowService的实现类对应的方法:
     /**
         * Start the process instance.
         * 
         */
        public String startProcessInstance(String processKey, Map<String, String> variables) {
            ProcessInstance processInstance = executionService.startProcessInstanceByKey(processKey, variables);
            return processInstance.getId();
        }
     ExecutionService这个类属于JBPM,全称是Java Business Process Management,是一种基于J2EE的轻量级工作流管理系统。

总结:这类AJAX+Spring MVC的程序基本原理就是前台JS代码去调用后台的Service.测试的时候打开Fidder或者Firebug就能捕捉到具体的service已经传递的参数

接下去是真证的Disable逻辑:

  1. 在ESFServiceImpl里有一个disableUser()方法:
    public void disableUser(String operator, String userId) throws Exception {
    		//		Map<String, String> userESFAttrMap = queryUserESFInfo(userId);
    		//		if (userESFAttrMap == null) {
    		//			throw new Exception("Disable user error. Can not find user: "
    		//					+ userId);
    		//		}
    		//		if (ESFConstans.STATUS_ENABLED.equals(userESFAttrMap
    		//				.get(ESFConstans.CLIENT_USERS_ATTR.STATUS))) {
    		//			changeUserStatus(operator, userId);
    		//		}
    		Connection con = null;
    		CallableStatement st = null;
    		ResultSet rs = null;
    		try {
    			con = getConnection();
    			st = con.prepareCall(ESFConstans.CALL_DISABLE_USER);
    			st.setString(1, userId);
    			st.setString(2, operator);
    			st.execute();
    		} catch (SQLException e) {
    			throw e;
    		} catch (Exception e) {
    			throw e;
    		} finally {
    			closeAllDBResources(rs, st, con);
    		}
    	}
     其中使用CallableStatement调用了存储过程ESFConstans.CALL_DISABLE_USER:
    public static final String CALL_DISABLE_USER = "call "
    		+ schema
    		+ "cdc_rules_gmo_serve."
    		+ profix
    		+ "set_status_v2(?,0,?)";
     
分享到:
评论

相关推荐

    Spring + Hibernate + Spring mvc +Ajax 整合

    Spring、Hibernate、Spring MVC 和 Ajax 是四个在Java Web开发中广泛应用的技术框架,它们共同构建了一个高效、灵活且功能丰富的后端系统。以下是对这些技术及其整合应用的详细说明: Spring框架是一个全面的企业级...

    Spring+Spring mvc+Hibernate+Bootstrap、企业级员工信息管理系统

    后台通过自定义注解结合一个访问拦截器实现整个系统的权限控制 04. 系统前台采用全采用的Html+jQuery开发 05. 系统前台与后台的交互全部使用 Ajax 异步请求 06. 自定义 SecureValid 注解实现权限的控制 07. ...

    【项目原型】spring+spring mvc+mybatis+shiro+maven+bootstrap+ajax+json+分页+逆向工程

    【项目原型】spring+spring mvc+mybatis+shiro+maven+bootstrap+ajax+json+分页+逆向工程 包含现在最流行的技术框架,快速部署各种应用,加入shiro权限框架,安全,美观,你值得拥有

    人事管理系统(注解 Mybatis+Spring+Spring MVC框架整合AJAX+JQuery实现登录、注册以及验证码和验证注册用户信息,包括数据库备份)

    三期答辩课程设计,人事管理系统Mybatis+Spring+Spring MVC框架整合AJAX+JQuery实现登录、注册以及验证码和验证注册用户信息,包括数据库备份,课设说明,答辩PPT,Windows下sts(eclipse) 。

    Spring+SpringMVC+Mybatis+Maven+bootstrap+ajax+jQuery整合开发简单的员工后台管理系统

    在本项目中,"Spring+SpringMVC+Mybatis+Maven+bootstrap+ajax+jQuery整合开发简单的员工后台管理系统",我们看到一个基于Java技术栈的Web应用开发实例。这个系统利用了多个核心技术来构建一个功能完备的员工管理...

    一个完整的mabits+spring+spring mvc项目

    【标题】"一个完整的mabits+spring+spring mvc项目"揭示了这是一个基于特定技术栈构建的企业级应用。Mabits通常指的是Mabits框架,它是一个轻量级的Java开发框架,用于快速构建企业级应用。Spring是Java领域广泛应用...

    activiti+spring mvc+maven+extjs mvc+mybatis一个简单的请假工作流

    标题中的“activiti+spring mvc+maven+extjs mvc+mybatis”是一个集成的IT解决方案,用于构建一个简单的请假工作流程应用。这个项目利用了多种技术来创建一个前端和后端无缝协作的系统。 1. **Activiti**:Activiti...

    ajax+jsf+spring+hibernate

    **Spring框架** 是一个全面的Java企业级应用开发框架,它提供了依赖注入(DI)、面向切面编程(AOP)、事务管理以及大量可扩展的模块,如Spring MVC、Spring Data等。Spring MVC是Spring框架的一部分,用于构建Web...

    Spring MVC+Spring+MyBatis+BootsStrap+Ajax+JQuery整合开发汽车销售管理平台

    项目描述 它是一个针对汽车销售有关的后台管理...spring+spring mvc+mybatis+bootstrap+jquery 数据库文件 链接:https://pan.baidu.com/s/1qWF4Nx3xGjjtW3fW-pjRDg 提取码:nfwj jar包文件 压缩包WEB-INF/lib下

    基于hibernate + spring + spring mvc + bootstrap的管理系统实现

    本项目名为“基于hibernate + spring + spring mvc + bootstrap的管理系统实现”,它利用了四大核心技术来创建一个功能完善的后端管理系统。下面将详细解析这四个技术及其在项目中的作用。 1. Hibernate:Hibernate...

    spring mvc+ajax

    Spring MVC 是一个基于Java的轻量级Web应用框架,它为构建模型-视图-控制器(MVC)架构的应用程序提供了强大的支持。Ajax(Asynchronous JavaScript and XML)是一种在无需重新加载整个网页的情况下,能够更新部分...

    Maven+Spring MVC +Hibernate Validate

    综上所述,"Maven+Spring MVC +Hibernate Validate"项目结合了多种强大技术,构建了一个高效、健壮的Web应用解决方案,涵盖了项目管理、服务端控制、数据持久化、数据验证、前端交互以及文件处理等多个方面。...

    mysql+spring mvc 实现分页

    Spring MVC提供了一个强大的分页工具类:`org.springframework.data.domain.Pageable`。它包含了当前页、每页记录数、排序方式等信息。我们可以创建一个接口方法,接收`Pageable`对象作为参数,然后在Service层根据...

    spring2.0MVC+spring2.5MVC+portletMVC

    至于Portlet MVC,它是Spring MVC的一个扩展,专为portlet应用设计。portlet应用常在门户服务器中运行,如Liferay或WebSphere Portal。Portlet MVC主要特性包括: 1. **portlet生命周期**:portlet有初始化、渲染、...

    整合spring data jpa + spring mvc + easyui

    标题 "整合spring data jpa + spring mvc + easyui" 暗示了这个项目是关于构建一个基于Java的Web应用程序,使用了Spring框架的重要组件,包括Spring Data JPA、Spring MVC以及EasyUI。让我们详细了解一下这些技术...

    基于Spring+Spring MVC+Mybatis的员工管理考勤系统

    Spring MVC是Spring框架的一个模块,专门用于处理Web应用程序。它提供了一种MVC(Model-View-Controller)设计模式的实现,使得前端与后端逻辑分离,提高了开发效率和代码质量。在员工管理考勤系统中,Spring MVC...

    spring+spring mvc+mybatis+easyui整合demo

    这个"spring+spring mvc+mybatis+easyui整合demo"项目是针对这些技术的一个集成示例,旨在帮助开发者了解如何将它们协同工作以构建一个功能完备的Web应用程序。 首先,Spring框架作为基础,它提供了依赖注入(DI)...

    一个ajax+spring+hibernate整合project

    Spring框架是Java领域的一个重量级轻量级应用框架,它提供了一种全面的编程和配置模型,用于简化企业级应用的开发。Spring的核心特性包括依赖注入(DI)和面向切面编程(AOP),同时提供了对JDBC、ORM、事务管理等的...

Global site tag (gtag.js) - Google Analytics