Spring Boot 2实战项目:信息管理系统(二)------ 持久层、分页、业务逻辑接口及其实现类、Web层

1. Repository持久层

Spring Data 建议定义接口完成SQL语句的操作,该接口可以直接作为Repository组件使用。当使用repository模式时,既能体现业务逻辑组件封装repository组件的门面模式,也可以分离业务逻辑组件和repository组件的功能:业务逻辑组件负责业务逻辑的变化,而repository组件负责持久化的技术变化,这正是桥接模式的应用。

引入repository模式后,每个repository组件包含了数据库的访问逻辑,每个repository组件可对一个数据库表完成基本的CRUD操作。

在spring data 当中,基本的增删改查已经在父类JpaRepository 中完成,自定义接口中只需通过@Query 注解完成个性化查询即可。

1.1 DeptRepository

public interface DeptRepository extends JpaRepository<Dept, Long> {

	@Query("select new Map(p.id, p.name) from Dept t")
	public List<HashMap<String, Object>> findDepts();
}

1.2 JobRepository

public interface JobRepository extends JpaRepository<Job, Long> {
	
	@Query("select new Map(j.id , j.code, j.name) from Job j")
	public List<Map<String, Object>> findJobs();
}

1.3 ModuleRepository

public interface ModuleRepository extends JpaRepository<Module, Long>, JpaSpecificationExecutor<Module> {

	@Modifying
	@Query("delete Module m where m.code like ?1")
	public void setCode(String code) ;
    
	@Query("select m from Module m where m.code like :parentCode and length(m.code) = :sonCodeLen")
	public List<Module> findModules(@Param("parentCode")String parentCode, @Param("sonCodeLen")int sonCodeLen);
	
	@Query("select Max(m.code) from Module m where m.code like :parentCode and  length(m.code) = :sonCodeLen ")
	public String findUniqueEntity(@Param("parentCode")String parentCode, @Param("sonCodeLen")int sonCodeLen);
}

1.4 PopedomRepository

public interface PopedomRepository extends JpaRepository<Popedom, Long> {

	@Query("select p.opera.code from Popedom p where p.role.id = :id and p.module.code = :parentCode")
	public List<String> findByIdAndParentCode(@Param("id")long id, @Param("parentCode")String parentCode);
    
	@Modifying
	@Query("delete Popedom p where p.role.id = :id and p.module.code = :parentCode")
	public void setByIdAndParentCode(@Param("id")long id, @Param("parentCode")String parentCode);
	
	@Query("select distinct p.module.code from Popedom p where "
			+ "p.role.id in(select r.id from Role r "
			+ "inner join r.users u where u.id = ?1 ) "
			+ "order by p.module.code asc")
	public List<String> getUserPopedomModuleCodes(long id);

	@Query("select distinct p.opera.code from Popedom p "
			+ "where p.role.id in(select r.id from Role r "
			+ "inner join r.users u where u.id = ?1 ) order by p.opera.code asc")
	public List<String> getUserPopedomOperasCodes(long id);
}

1.5 RoleRepository

public interface RoleRepository extends JpaRepository<Role, Long>, JpaSpecificationExecutor<Role> {

}

1.6 UserRepository

public interface UserRepository extends JpaRepository<User, Long>, JpaSpecificationExecutor<User> {

	@Query("select u.id from User u where u.id not in(select u.id from User u inner join u.roles r where r.id = ?1)")
	List<String> getRolesUsers(long id);

	@Query("select u.id from User u inner join u.roles r where r.id = ?1")
	List<String> findRoleUsers(long id);
}

2JSP页面分页功能

2.1 分页实体

package org.oa.common.util.page;

public class PageModel {

	/** 分页中默认一个5条数据 */
	public static final int PAGE_DEFAULT_SIZE = 5;

	/** 分页总数据条数 */
	private long recordCount;
	/** 当前页面 */
	private int pageIndex;
	/** 每页分多少条数据 */
	private int pageSize = PAGE_DEFAULT_SIZE;

	/** 总页数 */
	private int totalSize;

	public long getRecordCount() {
		this.recordCount = this.recordCount <= 0 ? 0 : this.recordCount;
		return recordCount;
	}

	public void setRecordCount(long recordCount) {
		this.recordCount = recordCount;
	}

	public int getPageIndex() {
		this.pageIndex = this.pageIndex <= 0 ? 1 : this.pageIndex;
		/** 判断当前页面是否超过了总页数:如果超过了默认给最后一页作为当前页 */
		return pageIndex;
	}

	public void setPageIndex(int pageIndex) {
		this.pageIndex = pageIndex;
	}

	public int getPageSize() {
		this.pageSize = this.pageSize <= PAGE_DEFAULT_SIZE ? PAGE_DEFAULT_SIZE : this.pageSize;
		return pageSize;
	}

	public void setPageSize(int pageSize) {
		this.pageSize = pageSize;
	}

	public int getTotalSize() {
		if (this.getRecordCount() <= 0) {
			totalSize = 0;
		} else {
			totalSize = (int) ((this.getRecordCount() - 1) / this.getPageSize() + 1);
		}
		return totalSize;
	}

	public int getFirstLimitParam() {
		return (this.getPageIndex() - 1) * this.getPageSize();
	}

}

2.2 自定义标签库

package org.oa.common.util.page;

import java.io.IOException;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.SimpleTagSupport;

public class PagerTag extends SimpleTagSupport {

	/** 定义请求URL中的占位符常量 */
	private static final String TAG = "{0}";

	/** 当前页码 */
	private int pageIndex;
	/** 每页显示的数量 */
	private int pageSize;
	/** 总记录条数 */
	private int recordCount;
	/** 请求URL page.action?pageIndex={0} */
	private String submitUrl;

	/** 定义总页数 */
	private int totalPage = 0;

	/** 在页面上引用自定义标签就会触发一个标签处理类 */
	@Override
	public void doTag() throws JspException, IOException {
		/** 定义它拼接是终的结果 */
		StringBuilder res = new StringBuilder();

		res.append("<center>\n" + "\t\t<p style=\"text-align: center;\">\n" + "\t\t\t<!-- 设计导航-->\n"
				+ "\t\t\t<nav class=\"nav form-inline\">\n" + "\t\t\t\t <ul class=\"pagination alin\">");
		/** 定义它拼接中间的页码 */
		StringBuilder str = new StringBuilder();
		/** 判断总记录条数 */
		if (recordCount > 0) { // 1499 / 15 = 100
			/** 需要显示分页标签,计算出总页数 需要分多少页 */
			totalPage = (this.recordCount - 1) / this.pageSize + 1;

			/** 判断上一页或下一页需不需要加a标签 */
			if (this.pageIndex == 1) { // 首页
				str.append("<li class=\"disabled\" ><a href=\"#\">上一页</a></li>");

				/** 计算中间的页码 */
				this.calcPage(str);

				/** 下一页需不需要a标签 */
				if (this.pageIndex == totalPage) {
					/** 只有一页 */
					str.append("<li class=\"disabled\" ><a href=\"#\">下一页</a></li>");
				} else {
					String tempUrl = this.submitUrl.replace(TAG, String.valueOf(pageIndex + 1));
					str.append("<li><a href='" + tempUrl + "'>下一页</a></li>");
				}
			} else if (this.pageIndex == totalPage) { // 尾页
				String tempUrl = this.submitUrl.replace(TAG, String.valueOf(pageIndex - 1));
				str.append("<li><a href='" + tempUrl + "'>上一页</a></li>");

				/** 计算中间的页码 */
				this.calcPage(str);

				str.append("<li class=\"disabled\" ><a href=\"#\">下一页</a></li>");
			} else { // 中间
				String tempUrl = this.submitUrl.replace(TAG, String.valueOf(pageIndex - 1));
				str.append("<li><a href='" + tempUrl + "'>上一页</a></li>");

				/** 计算中间的页码 */
				this.calcPage(str);

				tempUrl = this.submitUrl.replace(TAG, String.valueOf(pageIndex + 1));
				str.append("<li><a href='" + tempUrl + "'>下一页</a></li>");
			}

			res.append(str);

			/** 开始条数 */
			int startNum = (this.pageIndex - 1) * this.pageSize + 1;
			/** 结束条数 */
			int endNum = (this.pageIndex == this.totalPage) ? this.recordCount : this.pageIndex * this.pageSize;

			res.append("<li><a style=\"background-color:#D4D4D4;\" href=\"#\">共<font color='red'>" + this.recordCount
					+ "</font>条记录,当前显示" + startNum + "-" + endNum + "条记录</a>&nbsp;</li>");

			res.append("<div class=\"input-group\">\n"
					+ "\t\t\t\t\t\t\t\t\t      <input id='pager_jump_page_size' value='" + this.pageIndex
					+ "' type=\"text\" style=\"width: 60px;text-align: center;\" class=\"form-control\" placeholder=\""
					+ this.pageIndex + "\"\">\n" + "\t\t\t\t\t\t\t\t\t      <span class=\"input-group-btn\">\n"
					+ "\t\t\t\t\t\t\t\t\t        <button class=\"btn btn-info\" id='pager_jump_btn' type=\"button\">GO</button>\n"
					+ "\t\t\t\t\t\t\t\t\t      </span>\n" + "\t\t\t\t\t   \t\t\t\t </div>");

			res.append("<script type='text/javascript'>");
			res.append("   document.getElementById('pager_jump_btn').onclick = function(){");
			res.append("      var page_size = document.getElementById('pager_jump_page_size').value;");
			res.append("      if (!/^[1-9]\\d*$/.test(page_size) || page_size < 1 || page_size > " + this.totalPage
					+ "){");
			res.append("          alert('请输入[1-" + this.totalPage + "]之间的页码!');");
			res.append("      }else{");
			res.append("         var submit_url = '" + this.submitUrl + "';");
			res.append("         window.location = submit_url.replace('" + TAG + "', page_size);");
			res.append("      }");
			res.append("}");
			res.append("</script>");

		} else {
			res.append(
					"<li><a style=\"background-color:#D4D4D4;\" href=\"#\">总共<font color='red'>0</font>条记录,当前显示0-0条记录。</a>&nbsp;</li>");
		}

		res.append("</ul></nav></p></center>");
		this.getJspContext().getOut().print(res.toString());
	}

	/** 计算中间页码的方法 */
	private void calcPage(StringBuilder str) {
		/** 判断总页数 */
		if (this.totalPage <= 11) {
			/** 一次性显示全部的页码 */
			for (int i = 1; i <= this.totalPage; i++) {
				if (this.pageIndex == i) {
					/** 当前页码 */
					str.append("<li class=\"active\" ><a href=\"#\">" + i + "</a></li>");
				} else {
					String tempUrl = this.submitUrl.replace(TAG, String.valueOf(i));
					str.append("<li><a href='" + tempUrl + "'>" + i + "</a></li>");
				}
			}
		} else {
			/** 靠首页近些 */
			if (this.pageIndex <= 8) {
				for (int i = 1; i <= 10; i++) {
					if (this.pageIndex == i) {
						/** 当前页码 */
						str.append("<li class=\"active\" ><a href=\"#\">" + i + "</a></li>");
					} else {
						String tempUrl = this.submitUrl.replace(TAG, String.valueOf(i));
						str.append("<li><a href='" + tempUrl + "'>" + i + "</a></li>");
					}
				}
				str.append("<li><a href=\"#\">...</a></li>");
				String tempUrl = this.submitUrl.replace(TAG, String.valueOf(this.totalPage));
				str.append("<li><a href='" + tempUrl + "'>" + this.totalPage + "</a></li>");

			}
			/** 靠尾页近些 */
			else if (this.pageIndex + 8 >= this.totalPage) {
				String tempUrl = this.submitUrl.replace(TAG, String.valueOf(1));
				str.append("<li><a href='" + tempUrl + "'>1</a></li>");
				str.append("<li><a href=\"#\">...</a></li>");

				for (int i = this.totalPage - 10; i <= this.totalPage; i++) {
					if (this.pageIndex == i) {
						/** 当前页码 */
						str.append("<li class=\"active\" ><a href=\"#\">" + i + "</a></li>");
					} else {
						tempUrl = this.submitUrl.replace(TAG, String.valueOf(i));
						str.append("<li><a href='" + tempUrl + "'>" + i + "</a></li>");
					}
				}
			}
			/** 在中间 */
			else {
				String tempUrl = this.submitUrl.replace(TAG, String.valueOf(1));
				str.append("<li><a href='" + tempUrl + "'>1</a></li>");
				str.append("<li><a href=\"#\">...</a></li>");

				for (int i = this.pageIndex - 4; i <= this.pageIndex + 4; i++) {
					if (this.pageIndex == i) {
						/** 当前页码 */
						str.append("<li class=\"active\" ><a href=\"#\">" + i + "</a></li>");
					} else {
						tempUrl = this.submitUrl.replace(TAG, String.valueOf(i));
						str.append("<li><a href='" + tempUrl + "'>" + i + "</a></li>");
					}
				}

				str.append("<li><a href=\"#\">...</a></li>");
				tempUrl = this.submitUrl.replace(TAG, String.valueOf(this.totalPage));
				str.append("<li><a href='" + tempUrl + "'>" + this.totalPage + "</a></li>");
			}
		}
	}

	/** setter method */
	public void setPageIndex(int pageIndex) {
		this.pageIndex = pageIndex;
	}

	public void setPageSize(int pageSize) {
		this.pageSize = pageSize;
	}

	public void setRecordCount(int recordCount) {
		this.recordCount = recordCount;
	}

	public void setSubmitUrl(String submitUrl) {
		this.submitUrl = submitUrl;
	}
}

2.3 tld标签文件

<?xml version="1.0" encoding="utf-8"?>
<taglib xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
    					http://java.sun.com/xml/ns/javaee/web-jsptaglibrary_2_1.xsd"
   						version="2.1">
   
  <!-- 描述 自定义标签版本的一种描述 --> 
  <description>Page 1.0 core library</description>
  <!-- 显示的名称 导包进行的一个展示 -->
  <display-name>Page core</display-name>
  <!-- 版本号 -->
  <tlib-version>1.0</tlib-version>
  <!-- 短名 -->
  <short-name>page</short-name>
  <!-- uri :导包 -->
  <uri>/page-tags</uri>
  
  <!-- 定义一个标签 -->
  <tag>
  		<!-- 标签名 -->
  		<name>page</name>
  		<!-- 标签处理类 -->
  		<tag-class>org.oa.common.util.page.PagerTag</tag-class>
  		<!-- 设置标签为空 -->
  		<body-content>empty</body-content>
  		
  		<!-- 定义标签的属性 -->
  		<attribute>
  			<!-- 属性名 表示分页的第几页 -->
  			<name>pageIndex</name>
  			<!-- 必须的 -->
  			<required>true</required>
  			<!-- run time expression value 为true支持EL表达式 -->
  			<rtexprvalue>true</rtexprvalue>
  		</attribute>
  		
  		<!-- 定义标签的属性 -->
  		<attribute>
  			<!-- 属性名 表示分页标签 ,每页显示多少条数据 -->
  			<name>pageSize</name>
  			<!-- 必须的 -->
  			<required>true</required>
  			<!-- run time expression value 为true支持EL表达式 -->
  			<rtexprvalue>true</rtexprvalue>
  		</attribute>
  		<!-- 定义标签的属性 -->
  		<attribute>
  			<!-- 属性名  记录分页的总数 -->
  			<name>recordCount</name>
  			<!-- 必须的 -->
  			<required>true</required>
  			<!-- run time expression value 为true支持EL表达式 -->
  			<rtexprvalue>true</rtexprvalue>
  		</attribute>
  		<!-- 定义标签的属性 -->
  		<attribute>
  			<!-- 属性名 -->
  			<name>submitUrl</name>
  			<!-- 必须的 -->
  			<required>true</required>
  			<!-- run time expression value 为true支持EL表达式 -->
  			<rtexprvalue>true</rtexprvalue>
  		</attribute>
  		<!-- 定义标签的属性 -->
  		<attribute>
  			<!-- 属性名 -->
  			<name>style</name>
  			<!-- 必须的 -->
  			<required>false</required>
  			<!-- run time expression value 为true支持EL表达式 -->
  			<rtexprvalue>true</rtexprvalue>
  		</attribute>
  </tag>
</taglib>

3. 业务层接口及其实现类

SysService:

package org.oa.sys.service;

import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpSession;

import org.common.util.page.PageModel;
import org.oa.sys.domain.Dept;
import org.oa.sys.domain.Module;
import org.oa.sys.domain.Role;
import org.oa.sys.domain.User;
import org.oa.sys.dto.UserModule;
import org.oa.sys.vo.TreeData;

public interface SysService {

    /**
     * @return 查询所有的部门
     */
    List<Dept> getAllDepts();

    /**
     * 异步登录的业务层接口方法
     * @param params
     * @return
     */
    Map<String, Object> login(Map<String, Object> params);

    /**
     * 根据用户的主键查询用户信息,包含了延迟加载的部门和职位信息
     * @param userId
     * @return
     */
    User getUserById(Long id);

    /**
     * 修改自己
     * @param user
     */
    void updateSelf(User user, HttpSession session);

    /**
     * @return 异步加载部门与职位的json字符串信息写回到页面
     */
    Map<String, Object> getAllDeptsAndJobsAjax();

    /**
     * 分页查询用户信息 
     * 
     * @param user
     * @param pageModel
     * @return
     */
    List<User> getUsersByPage(User user, PageModel pageModel);

    /**
     * 批量删除用户
     * @param ids
     */
    void deleteUserByUserIds(String ids);

    /**
     * 校验用户是否已经被注册 
     * @param userId
     * @return
     */
    String isUserValidAjax(Long id);

    /**
     * 
     * @param user 
     */
    void addUser(User user);

    /**
     * 根据userId修改用户信息
     * @param user
     */
    void updateUser(User user);

    /**
     * 激活用户
     * @param user
     */
    void activeUser(User user);

    /**
     * 加载所有的模块树
     * @return
     */
    List<TreeData> loadAllModuleTrees();

    /**
     * 根据父节点查询所有的子模块
     * @param parentCode
     * @return
     */
    List<Module> getModulesByParent(String parentCode, PageModel pageModel);

    /**
     * 根据父节点查询所有的子模块 
     * 不分页
     * @param parentCode
     * @return
     */
    List<Module> getModulesByParent(String parentCode);

    /**
     * 批量删除菜单
     * @param ids
     */
    void deleteModules(String ids);

    /**
     * 为当前父节点菜单添加子节点模块
     * @param parentCode
     * @param module
     */
    void addModule(String parentCode, Module module);

    /**
     * 根据编号查询模块信息
     * @param code
     * @return
     */
    Module getModuleByCode(String code);

    /**
     * 修改模块
     * @param module
     */
    void updateModule(Module module);

    /**
     * 分页查询角色信息
     * @param pageModel
     * @return
     */
    List<Role> getRoleByPage(PageModel pageModel);

    /**
     * 添加角色
     * @param role
     */
    void addRole(Role role);

    /**
     * 批量删除角色
     * @param ids
     */
    void deleteRole(String ids);

    /**
     * 根据id查询角色
     * @param id
     * @return
     */
    Role getRoleById(Long id);

    /**
     * 修改角色
     * @param role
     */
    void updateRole(Role role);

    /**
     * 分页查询属于这个角色下的用户信息 
     * @param role
     * @param pageModel
     * @return
     */
    List<User> selectRoleUser(Role role, PageModel pageModel);

    /**
     * 查询不属于某个角色下的用户
     * @param role
     * @param pageModel
     * @return
     */
    List<User> selectNotRoleUser(Role role, PageModel pageModel);

    /**
     * 给用户绑定角色
     * @param role
     * @param ids
     */
    void bindUser(Role role, String ids);

    /**
             * 给用户解绑角色
     * @param role
     * @param ids
     */
    void unBindUser(Role role, String ids);

    /**
     * 查询当前角色在当前模块下拥有的操作权限编号。
     * @param role
     * @param parentCode
     * @return
     */
    List<String> getRoleModuleOperasCodes(Role role, String parentCode);

    /**
     * 给角色绑定某个模块下的操作权限 
     * @param codes
     * @param role
     * @param parentCode
     */
    void bindPopedom(String codes, Role role, String parentCode);

    /**
     * 查询当前用户的权限模块 
     * @return
     */
    List<UserModule> getUserPopedomModules();

}

实现类:

package org.oa.sys.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.JoinType;
import javax.persistence.criteria.Path;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import javax.servlet.http.HttpSession;

import org.common.service.BaseService;
import org.common.util.CommonContants;
import org.common.util.page.PageModel;
import org.oa.sys.domain.Dept;
import org.oa.sys.domain.Module;
import org.oa.sys.domain.Popedom;
import org.oa.sys.domain.Role;
import org.oa.sys.domain.User;
import org.oa.sys.dto.UserModule;
import org.oa.sys.repository.DeptRepository;
import org.oa.sys.repository.JobRepository;
import org.oa.sys.repository.ModuleRepository;
import org.oa.sys.repository.PopedomRepository;
import org.oa.sys.repository.RoleRepository;
import org.oa.sys.repository.UserRepository;
import org.oa.sys.service.SysService;
import org.oa.sys.vo.TreeData;
import org.oa.util.OaContants;
import org.oa.util.OaException;
import org.oa.util.UserHolder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

@Service
@Transactional
public class SysServiceImpl extends BaseService implements SysService {
    
    @Autowired
    private DeptRepository deptRepository;

    @Autowired
    private JobRepository jobRepository;

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private ModuleRepository moduleRepository;

    @Autowired 
    private RoleRepository roleRepository;

    @Autowired
    private PopedomRepository popedomRepository;

    @Transactional(readOnly = true)
    @Override
    public List<Dept> getAllDepts() {
        try {
            List<Dept> depts = deptRepository.findAll();
            // 取延迟加载的属性 ,会话此时并没有关闭
            for (Dept dept : depts) {
                if (dept.getCreater() != null)
                    dept.getCreater().getName();
                if (dept.getModifier() != null)
                    dept.getModifier().getName();
            }

            return depts;
        } catch (Exception e) {
            throw new OaException("查询部门失败了", e);
        }
    }

    @Override
    public Map<String, Object> login(Map<String, Object> params) {
        Map<String, Object> result = new HashMap<>();
        try {
            /** 处理登录的业务逻辑   */
            /** 1.参数非空校验  */
           Long id = (Long) params.get("id");
            String passWord = (String) params.get("passWord");
            String vcode = (String) params.get("vcode");
            HttpSession session = (HttpSession) params.get("session");
            // userId!=null&&!userId.equals("")
            if (id == null || StringUtils.isEmpty(passWord) || StringUtils.isEmpty(vcode)) {
                /** 参数有为空的 */
                result.put("status", 0);
                result.put("tip", "参数有为空的");
            } else {
                /** 参数不为空  */
                /** 校验验证码是否正确 
                 *  获取session中当前用户对应的验证码 
                 * */
                String sysCode = (String) session.getAttribute(CommonContants.VERIFY_SESSION);
                if (vcode.equalsIgnoreCase(sysCode)) {
                    /** 验证码正确了  */
                    /** 根据登录的用户名去查询用户: 判断登录名是否存在  */
                    User user = getUserById(id);
                    if (user != null) {
                        /** 登录名存在  */
                        /** 判断密码 */
                        if (user.getPassword().equals(passWord)) {
                            /** 判断用户是否已经被激活了 */
                            if (user.getStatus() == 1) {
                                /** 登录成功  */
                                /** 1.把登录成功的用户放入当前用户的session会话中  */
                                session.setAttribute(OaContants.USER_SESSION, user);
                                System.out.println("设置用户 ---------------->:" + user);
                                result.put("status", 1);
                                result.put("tip", "登录成功");
                                /** 把登录成功的用户存入到UserHolder*/
                                UserHolder.addCurrentUser(user);
                                /** 2.当用户一登录进入系统的时候,就应该立即去查询该用户所拥有
                                            的全部操作权限 --> 存入到当前用户的Session会话中  */
                                Map<String, List<String>> userAllOperasPopedomUrls = getUserAllOperasPopedomUrls();
                                session.setAttribute(OaContants.USER_ALL_OPERAS_POPEDOM_URLS, userAllOperasPopedomUrls);

                            } else {
                                result.put("status", 5);
                                result.put("tip", "您的账号未被激活,请联系管理员激活!");
                            }
                        } else {
                            /** 密码错误     */
                            result.put("status", 2);
                            result.put("tip", "密码错误了");
                        }
                    } else {
                        /** 登录名不存在  */
                        result.put("status", 3);
                        result.put("tip", "没有该账户");
                    }
                } else {
                    /** 验证码不正确 */
                    result.put("status", 4);
                    result.put("tip", "验证码不正确");
                }
            }
            return result;
        } catch (Exception e) {
            throw new OaException("异步登录业务层抛出异常了", e);
        }

    }

    private Map<String, List<String>> getUserAllOperasPopedomUrls() {
        try {
            /** 查询用户所拥有的所有操作权限编号 
             * */
            List<String> userAllPopedomOperasCodes = popedomRepository
                    .getUserPopedomOperasCodes(UserHolder.getCurrentUser().getId());

            if (userAllPopedomOperasCodes != null && userAllPopedomOperasCodes.size() > 0) {
                Map<String, List<String>> userAllOperasPopedomUrls = new HashMap<>();
                String moduleUrl = "";
                List<String> moduleOperaUrls = null;
                for (String operaCode : userAllPopedomOperasCodes) {
                    /** 先得到模块的编号   */
                    String parentModuleCode = operaCode.substring(0, operaCode.length() - OaContants.CODE_LEN);
                    /** 父模块地址 */
                    moduleUrl = getModuleByCode(parentModuleCode).getUrl();
                    /** 判断map集合中是否已经存在该父模块地址 */
                    if (!userAllOperasPopedomUrls.containsKey(moduleUrl)) {
                        moduleOperaUrls = new ArrayList<String>();
                        userAllOperasPopedomUrls.put(moduleUrl, moduleOperaUrls);
                    }
                    moduleOperaUrls.add(getModuleByCode(operaCode).getUrl());
                }
                return userAllOperasPopedomUrls;
            }
            return null;
        } catch (Exception e) {
            throw new OaException("登录查询用户的操作权限出现异常", e);
        }

    }

    public User getUserById(Long id) {
        try {
            User user = userRepository.findById(id).get();
            if (user != null) {
                // 获取延迟加载的属性
                if (user.getDept() != null)
                    user.getDept().getName();
                if (user.getJob() != null)
                    user.getJob().getName();
                if (user.getCreater() != null)
                    user.getCreater().getName();
                if (user.getModifier() != null)
                    user.getModifier().getName();
                if (user.getChecker() != null)
                    user.getChecker().getName();
                return user;
            }
            return null;
        } catch (Exception e) {
            throw new OaException("查询用户失败了", e);
        }
    }

    @Transactional
    @Override
    public void updateSelf(User user, HttpSession session) {
        try {
            /** 1.持久化修改   */
            User sessionUser = userRepository.findById(user.getId()).get();
            sessionUser.setModifier(user);
            sessionUser.setName(user.getName());
            // get一下就可以加载延迟加载的属性
            if (sessionUser.getDept() != null)
                sessionUser.getDept().getName();
            if (sessionUser.getJob() != null)
                sessionUser.getJob().getName();
            session.setAttribute(OaContants.USER_SESSION, sessionUser);
        } catch (Exception e) {
            throw new OaException("修改用户失败了", e);
        }

    }

    @Override
    public Map<String, Object> getAllDeptsAndJobsAjax() {
        try {
            /** 1.定义一个Map对象封装最终查询出来的部门信息和职位信息 */
            Map<String, Object> deptJobDatas = new HashMap<>();
            /** 查询部门 : id name  */
            List<HashMap<String, Object>> deptsList = deptRepository.findDepts();

            /** 查询部门 : id name  */
            List<Map<String, Object>> jobLists = jobRepository.findJobs();

            deptJobDatas.put("depts", deptsList);
            deptJobDatas.put("jobs", jobLists);

            return deptJobDatas;
        } catch (Exception e) {
            throw new OaException("查 询部门与职位信息异常了", e);
        }
    }

    @SuppressWarnings("serial")
    @Override
    public List<User> getUsersByPage(User user, PageModel pageModel) {
        try {
            Page<User> usersPager = userRepository.findAll(new Specification<User>() {
                @Override
                public Predicate toPredicate(Root<User> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                    // 本集合用于封装查询条件
                    List<Predicate> predicates = new ArrayList<Predicate>();
                    if (user != null) {
                        /** 是否传入了姓名来查询  */
                        if (!StringUtils.isEmpty(user.getName())) {
                            predicates.add(cb.like(root.<String> get("name"), "%" + user.getName() + "%"));
                        }
                        /** 是否传入手机号码了来查询  */
                        if (!StringUtils.isEmpty(user.getMobile())) {
                            predicates.add(cb.like(root.<String> get("mobile"), "%" + user.getMobile() + "%"));
                        }
                        /** 是否传入部门来查询  */
                        if (user.getDept() != null && user.getDept().getId() != null && user.getDept().getId() != 0) {
                            root.join("dept", JoinType.INNER);
                            Path<Long> d_id = root.get("dept").get("id");
                            predicates.add(cb.equal(d_id, user.getDept().getId()));

                        }
                        if (user.getJob() != null && !StringUtils.isEmpty(user.getJob().getCode())
                                && !user.getJob().getCode().equals("0")) {
                            root.join("job", JoinType.INNER);
                            Path<String> j_id = root.get("job").get("code");
                            predicates.add(cb.equal(j_id, user.getJob().getCode()));
                        }
                    }
                    return query.where(predicates.toArray(new Predicate[predicates.size()])).getRestriction();
                }
            }, PageRequest.of(pageModel.getPageIndex() - 1, pageModel.getPageSize()));
            pageModel.setRecordCount(usersPager.getTotalElements());
            /** 取每个用户的延迟加载属性 */
            List<User> users = usersPager.getContent();
            for (User u : users) {
                if (u.getDept() != null)
                    u.getDept().getName();
                if (u.getJob() != null)
                    u.getJob().getName();
                if (u.getChecker() != null)
                    u.getChecker().getName();
            }
            return users;
        } catch (Exception e) {
            throw new OaException("查询用户信息异常了", e);
        }
    }

    @Transactional
    @Override
    public void deleteUserByUserIds(String ids) {
        try {
            List<User> users = new ArrayList<User>();
            for (String id : ids.split(",")) {
                User user = new User();
                user.setId(Long.parseLong(id));
                users.add(user);
            }
            userRepository.deleteInBatch(users);
        } catch (Exception e) {
            throw new OaException("删除用户信息异常了", e);
        }
    }

    @Override
    public String isUserValidAjax(Long id) {
        try {
            User user = userRepository.findById(id).get();
            return user == null ? "success" : "error";
        } catch (Exception e) {
            throw new OaException("校验用户登录名是否注册异常了", e);
        }
    }

    @Transactional
    @Override
    public void addUser(User user) {
        try {
            user.setCreater(UserHolder.getCurrentUser());
            userRepository.save(user);
        } catch (Exception e) {
            throw new OaException("添加用户信息异常了", e);
        }

    }

    @Transactional
    @Override
    public void updateUser(User user) {
        try {
            /** 1.持久化修改   */
            User sessionUser = userRepository.findById(user.getId()).get();
            sessionUser.setModifyDate(new Date());
            sessionUser.setModifier(UserHolder.getCurrentUser());
            sessionUser.setPassword(user.getPassword());
            sessionUser.setName(user.getName());
            sessionUser.setDept(user.getDept());
            sessionUser.setJob(user.getJob());
            sessionUser.setSex(user.getSex());
        } catch (Exception e) {
            throw new OaException("修改用户失败了", e);
        }
    }

    @Transactional
    @Override
    public void activeUser(User user) {
        try {
            User sessionUser = userRepository.findById(user.getId()).get();
            sessionUser.setCheckDate(new Date());
            sessionUser.setChecker(UserHolder.getCurrentUser());
            sessionUser.setStatus(user.getStatus());
        } catch (Exception e) {
            throw new OaException("激活用户失败了", e);
        }

    }

    @Override
    public List<TreeData> loadAllModuleTrees() {
        try {
            /** 查询所有的模块信息   */
            List<Module> modules = moduleRepository.findAll();
            /** 拼装成dtree需要的树节点  */
            List<TreeData> treeDatas = new ArrayList<>();
            for (Module m : modules) {
                TreeData data = new TreeData();
                data.setId(m.getCode());
                data.setName(m.getName());
                // 长度为4的编号的父节点是0
                // 其余节点的父节点是从开始位置一直截取到总长度减去步长的位置。 00010001的父节点是0001
                String pid = m.getCode().length() == OaContants.CODE_LEN ? "0"
                        : m.getCode().substring(0, m.getCode().length() - OaContants.CODE_LEN);
                data.setPid(pid);
                treeDatas.add(data);
            }
            return treeDatas;
        } catch (Exception e) {
            throw new OaException("加载模块树异常", e);
        }
    }

    @SuppressWarnings("serial")
    @Override
    public List<Module> getModulesByParent(String parentCode, PageModel pageModel) {
        try {
            parentCode = parentCode == null ? "" : parentCode;
            List<Object> values = new ArrayList<>();
            values.add(parentCode + "%");
            values.add(parentCode.length() + OaContants.CODE_LEN);
            // // 子节点的编号的长度是父节点编号长度+步长
            // // 子节点前几位的编号必须与父节点编码一致
            Page<Module> modulesPager = moduleRepository.findAll(new Specification<Module>() {

                @Override
                public Predicate toPredicate(Root<Module> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                    // 本集合用于封装查询条件
                    List<Predicate> predicates = new ArrayList<Predicate>();
                    predicates.add(cb.like(root.<String> get("code"), values.get(0) + ""));
                    predicates.add(cb.equal(cb.length(root.<String> get("code")), values.get(1)));
                    return query.where(predicates.toArray(new Predicate[predicates.size()])).getRestriction();
                }
            }, PageRequest.of(pageModel.getPageIndex() - 1, pageModel.getPageSize()));
            pageModel.setRecordCount(modulesPager.getTotalElements());
            /** 取每个用户的延迟加载属性 */
            List<Module> sonModules = modulesPager.getContent();
            for (Module m : sonModules) {
                if (m.getCreater() != null)
                    m.getCreater().getName();
                if (m.getModifier() != null)
                    m.getModifier().getName();
            }
            return sonModules;
        } catch (Exception e) {
            throw new OaException("查询子模块异常", e);

        }
    }

    @Override
    public List<Module> getModulesByParent(String parentCode) {
        try {
            parentCode = parentCode == null ? "" : parentCode;
            List<Module> sonModules = moduleRepository.findModules(parentCode + "%",
                    parentCode.length() + OaContants.CODE_LEN);
            for (Module m : sonModules) {
                if (m.getCreater() != null)
                    m.getCreater().getName();
                if (m.getModifier() != null)
                    m.getModifier().getName();
            }
            return sonModules;
        } catch (Exception e) {
            throw new OaException("查询子模块异常", e);
        }
    }

    @Transactional
    @Override
    public void deleteModules(String ids) {
        try {
            for (String id : ids.split(",")) {
                moduleRepository.deleteById(Long.valueOf(id));
            }
        } catch (Exception e) {
            throw new OaException("批量删除菜单异常", e);
        }

    }

    @Transactional
    @Override
    public void addModule(String parentCode, Module module) {
        try {

            /** 维护编号:通用工具类(给你一个父节点,给你一张表,给你那个字段,
             *  找出该字段该父节点下的下一个儿子节点的编号 ) */
            module.setCode(getNextSonCode(parentCode, OaContants.CODE_LEN));
            module.setCreater(UserHolder.getCurrentUser());
            moduleRepository.save(module);
        } catch (Exception e) {
            throw new OaException("添加子菜单异常", e);
        }

    }

    public String getNextSonCode(String parentCode, int codeLen) throws Exception {
        /** 判断父节点是否为null */
        parentCode = parentCode == null ? "" : parentCode;
        /** 1.查询出当前父节点下的最大儿子节点编号 */
        String maxSonCode = moduleRepository.findUniqueEntity(parentCode + "%", parentCode.length() + codeLen);
        String nextSonCode = ""; // 保存最终的下一个儿子节点编号
        /** 4.判断最大儿子节点编号是否存在 ,因为极有可能父节点此时一个子节点都没有 */
        if (StringUtils.isEmpty(maxSonCode)) {
            /** 儿子节点编号不存在 */
            String preSuffix = ""; // 0 需要拼接多少个0
            for (int i = 0; i < codeLen - 1; i++) {
                preSuffix += "0";
            }
            nextSonCode = parentCode + preSuffix + 1;
        } else {
            /** 儿子节点编号存在  */
            /** 截取出当前儿子节点编号的步长出来  */
            String currentMaxSonCode = maxSonCode.substring(parentCode.length());
            /** 得到儿子节点步长编号的整形形式   */
            int maxSonCodeInt = Integer.valueOf(currentMaxSonCode);
            maxSonCodeInt++;
            /** 判断编号是否越界了 */
            if ((maxSonCodeInt + "").length() > codeLen) {
                throw new OaException("编号越界了!");
            } else {
                /** 没有越界 */
                String preSuffix = ""; // 0 需要拼接多少个0
                for (int i = 0; i < codeLen - (maxSonCodeInt + "").length(); i++) {
                    preSuffix += "0";
                }

                nextSonCode = parentCode + preSuffix + maxSonCodeInt;
            }
        }
        return nextSonCode;
    }

    @Override
    public Module getModuleByCode(String code) {
        try {
            return moduleRepository.findByCode(code);
        } catch (Exception e) {
            throw new OaException("查询模块异常", e);
        }
    }

    @Transactional
    @Override
    public void updateModule(Module module) {
        try {
            Module sessionModule = moduleRepository.findById(module.getId()).get();
            sessionModule.setModifier(UserHolder.getCurrentUser());
            sessionModule.setName(module.getName());
            sessionModule.setRemark(module.getRemark());
            sessionModule.setUrl(module.getUrl());
        } catch (Exception e) {
            throw new OaException("修改模块异常", e);
        }

    }

    @Override
    public List<Role> getRoleByPage(PageModel pageModel) {
        try {
            // 指定排序参数对象:根据id,进行降序查询
            Sort sort = new Sort(Sort.Direction.ASC, "id");
            /**
            * 封装分页实体 
            * 参数一:pageIndex表示当前查询的第几页(默认从0开始,0表示第一页) 
            * 参数二:表示每页展示多少数据,现在设置每页展示2条数据
            * 参数三:封装排序对象,根据该对象的参数指定根据id降序查询
            */
            Pageable page = PageRequest.of(pageModel.getPageIndex() - 1, pageModel.getPageSize(), sort);
            Page<Role> rolePager = roleRepository.findAll(page);
            pageModel.setRecordCount(rolePager.getTotalElements());
            /** 取每个用户的延迟加载属性 */
            List<Role> roles = rolePager.getContent();
            for (Role r : roles) {
                if (r.getModifier() != null)
                    r.getModifier().getName();
                if (r.getCreater() != null)
                    r.getCreater().getName();
            }
            return roles;
        } catch (Exception e) {
            throw new OaException("查询角色异常", e);
        }
    }

    @Transactional
    @Override
    public void addRole(Role role) {
        try {
            role.setCreateDate(new Date());
            role.setCreater(UserHolder.getCurrentUser());
            roleRepository.save(role);
        } catch (Exception e) {
            throw new OaException("添加角色异常", e);
        }

    }

    @Transactional
    @Override
    public void deleteRole(String ids) {
        try {
            List<Role> roles = new ArrayList<Role>();
            for (String id : ids.split(",")) {
                Role role = new Role();
                role.setId(Long.valueOf(id));
            }
            roleRepository.deleteInBatch(roles);

        } catch (Exception e) {
            throw new OaException("批量删除角色异常", e);
        }
    }

    @Override
    public Role getRoleById(Long id) {
        try {
            return roleRepository.findById(id).get();
        } catch (Exception e) {
            throw new OaException("根据id查询角色异常", e);
        }
    }

    @Transactional
    @Override
    public void updateRole(Role role) {
        try {
            Role r = roleRepository.findById(role.getId()).get();
            r.setName(role.getName());
            r.setRemark(role.getRemark());
            r.setModifier(UserHolder.getCurrentUser());
        } catch (Exception e) {
            throw new OaException("根据id修改角色异常", e);
        }

    }

    @SuppressWarnings("serial")
    @Override
    public List<User> selectRoleUser(Role role, PageModel pageModel) {
        try {
            Page<User> usersPager = userRepository.findAll(new Specification<User>() {
                @Override
                public Predicate toPredicate(Root<User> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                    // 本集合用于封装查询条件
                    List<Predicate> predicates = new ArrayList<>();
                    List<String> userIds = userRepository.findRoleUsers(role.getId());
                    predicates.add(root.<String> get("userId").in(userIds));
                    return query.where(predicates.toArray(new Predicate[predicates.size()])).getRestriction();
                }
            }, PageRequest.of(pageModel.getPageIndex() - 1, pageModel.getPageSize()));
            pageModel.setRecordCount(usersPager.getTotalElements());
            List<User> users = usersPager.getContent();
            for (User u : users) {
                if (u.getDept() != null)
                    u.getDept().getName();
                if (u.getJob() != null)
                    u.getJob().getName();
                if (u.getChecker() != null)
                    u.getChecker().getName();
            }
            return users;
        } catch (Exception e) {
            throw new OaException("查询属于角色下的用户信息异常", e);
        }

    }

    @SuppressWarnings("serial")
    @Override
    public List<User> selectNotRoleUser(Role role, PageModel pageModel) {
        try {

            Page<User> usersPager = userRepository.findAll(new Specification<User>() {
                @Override
                public Predicate toPredicate(Root<User> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                    // 本集合用于封装查询条件
                    List<Predicate> predicates = new ArrayList<Predicate>();
                    // 先查询出不属于这个角色下的用户
                    List<String> userId = userRepository.getRolesUsers(role.getId());
                    predicates.add(root.<String> get("userId").in(userId));
                    return query.where(predicates.toArray(new Predicate[predicates.size()])).getRestriction();
                }
            }, PageRequest.of(pageModel.getPageIndex() - 1, pageModel.getPageSize()));
            pageModel.setRecordCount(usersPager.getTotalElements());
            List<User> users = usersPager.getContent();

            for (User u : users) {
                if (u.getDept() != null)
                    u.getDept().getName();
                if (u.getJob() != null)
                    u.getJob().getName();
                if (u.getChecker() != null)
                    u.getChecker().getName();
            }
            return users;
        } catch (Exception e) {
            throw new OaException("查询不属于角色下的用户信息异常", e);
        }
    }

    @Transactional
    @Override
    public void bindUser(Role role, String ids) {
        try {
            /** 给角色绑定一批用户 */
            /** 1.先查询出该角色 */
            Role session = roleRepository.findById(role.getId()).get();
            /** 2.给角色的users添加需要绑定的用户 */
            for (String id : ids.split(",")) {
                User user = userRepository.findById(Long.valueOf(id)).get();
                session.getUsers().add(user);
            }

        } catch (Exception e) {
            throw new OaException("绑定角色下的用户异常", e);
        }

    }

    @Transactional
    @Override
    public void unBindUser(Role role, String ids) {
        try {
            /** 给角色绑定一批用户 */
            /** 1.先查询出该角色 */
            Role session = roleRepository.findById(role.getId()).get();
            /** 2.给角色的users添加需要绑定的用户 */
            for (String id : ids.split(",")) {
                User user = userRepository.findById(Long.valueOf(id)).get();
                session.getUsers().remove(user);
            }

        } catch (Exception e) {
            throw new OaException("绑定角色下的用户异常", e);
        }

    }

    @Override
    public List<String> getRoleModuleOperasCodes(Role role, String parentCode) {
        try {
            List<String> roleModuleOperasCodes = popedomRepository.findByIdAndParentCode(role.getId(), parentCode);
            return roleModuleOperasCodes;
        } catch (Exception e) {
            throw new OaException("查询当前角色在当前模块下拥有的操作权限编号异常", e);
        }
    }

    @Transactional
    @Override
    public void bindPopedom(String codes, Role role, String parentCode) {
        try {
            /** 1.先清空此角色在此模块下的所有操作权限 */
            popedomRepository.setByIdAndParentCode(role.getId(), parentCode);
            /** 2.更新新的角色模块权限 */
            if (!StringUtils.isEmpty(codes)) {
                Module parent = getModuleByCode(parentCode);
                /** 添加一些更新的权限 */
                for (String code : codes.split(",")) {
                    /** 创建一个权限对象 */
                    Popedom popedom = new Popedom();
                    popedom.setRole(role);
                    popedom.setModule(parent);
                    popedom.setOpera(getModuleByCode(code));
                    popedom.setCreateDate(new Date());
                    popedom.setCreater(UserHolder.getCurrentUser());
                    popedomRepository.save(popedom);
                }
            }
        } catch (Exception e) {
            throw new OaException("给角色绑定某个模块的操作权限异常", e);
        }

    }

    @Override
    public List<UserModule> getUserPopedomModules() {
        try {
            /**查询当前用户的权限模块 :先查用户所有的角色,再查这些角色拥有的所有权限模块  */
            List<String> popedomModuleCodes = popedomRepository
                    .getUserPopedomModuleCodes(UserHolder.getCurrentUser().getId());
            if (popedomModuleCodes != null && popedomModuleCodes.size() > 0) {

                /** 定义一个Map集合用于保存用户的权限模块 
                 *  Map<Module,List<Module>> 
                 *  {系统管理=[用户管理,角色管理] , 假期模块=[查询信息,用户请假]}
                 *  */
                Map<Module, List<Module>> userModulesMap = new LinkedHashMap<>();
                Module fistModule = null;
                List<Module> secondModules = null;
                for (String moduleCode : popedomModuleCodes) {
                    /** 截取当前模块的一级模块编号 */
                    String fistCode = moduleCode.substring(0, OaContants.CODE_LEN);
                    /** 查询出一级模块对象 */
                    fistModule = getModuleByCode(fistCode);
                    fistModule.setName(fistModule.getName().replaceAll("-", ""));
                    /**如果map集合中没有包含当前一级模块的key,说明是第一次添加一级模块 */
                    if (!userModulesMap.containsKey(fistModule)) {
                        secondModules = new ArrayList<Module>();
                        userModulesMap.put(fistModule, secondModules);
                    }
                    Module secondModule = getModuleByCode(moduleCode);
                    secondModule.setName(secondModule.getName().replaceAll("-", ""));
                    secondModules.add(secondModule);
                }

                List<UserModule> userModules = new ArrayList<>();
                for (Entry<Module, List<Module>> entry : userModulesMap.entrySet()) {
                    Module key = entry.getKey();
                    List<Module> value = entry.getValue();
                    UserModule userModule = new UserModule();
                    userModule.setFirstModule(key);
                    userModule.setSecondModules(value);
                    userModules.add(userModule);
                }
                return userModules;

            }
            return null;

        } catch (Exception e) {
            throw new OaException("查询当前用户的权限模块", e);
        }
    }

}

4. Web层

4.1 LoginController 登录

package org.my.oa.sys.controller;

import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpSession;

import org.my.oa.sys.service.SysService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class LoginController {

    /** 1.定义业务层对象 */
    @Autowired
    private SysService sysService;

    @ResponseBody // 异步请求的响应结果
    @RequestMapping(value = "/loginAjax", produces = "application/json; charset=UTF-8")
    public Map<String, Object> login(@RequestParam("mobile") String mobile, @RequestParam("password") String password,
            @RequestParam("vcode") String vcode, HttpSession session) {
        try {
            Map<String, Object> params = new HashMap<>();
            params.put("mobile", mobile);
            params.put("password", password);
            params.put("vcode", vcode);
            params.put("session", session);
            // 响应数据啊,写回去数据
            Map<String, Object> result = sysService.login(params);
            return result;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

}

4.2 RequestController 登录跳转

package org.my.oa.sys.controller;

import java.util.List;

import org.my.oa.sys.dto.UserModule;
import org.my.oa.sys.service.SysService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
@RequestMapping("/oa")
public class RequestController {
	
	/** 1.定义业务层对象 */
	@Autowired
	private SysService sysService;
	
	@RequestMapping(value="/login")
	public String requestLogin(){
		return "login";
	}
	
	@RequestMapping(value="/main")
	public String requestMain(Model model){
		try {
			//查询出当前用户拥有的所有模块权限
			List<UserModule> userModules = sysService.getUserPopedomModules();
			model.addAttribute("userPopedomModules", userModules);
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		return "main";
	}
	
	@RequestMapping(value="/home")
	public String requestHome(){
		return "home";
	}
}

简单列举这两个控制层,业务逻辑层里面的实现已经很详细了,JSP页面不再展示。

附上目前完成的部分:
https://github.com/gavinL93/oa

本工程参考《Spring Boot2 企业应用实战》一书

负责业务逻辑都必须实现这个接口业务逻辑BusinessImpl实现接口Business,BusinessImpl.java的示例代码如下: //******* Business.java************** public class BusinessImpl implement Business { private SaveData db; public void DiSaveDate (SaveData db) { this.db = db; } … //根据注入的存储,存储数据 public void saveData() { … db.saveData(); … } } 编写测试TestBusiness,TestBusiness.java的示例代码如下: //******* TestBusiness.java************** public class TestBusiness { private Business business = new BusinessImpl(); … //根据注入的存储,存储数据 public void opraData() { … business. DiSaveDate (new XMLData()); business. saveData (); … } } 如果要完成依赖关系注入的对象,必须实现Business接口。 构造注入 构造注入是指在接受注入的中定义一个构造方法,并在参数中定义需要注入的。 (1)为了让Business接受XMLData的注入,需要为它定义一个构造方法,来接受XMLData的注入。Business.java的示例代码如下: //******* Business.java************** public class Business { private SaveData db; public Business (SaveData db) { this.db = db; } … //根据注入的存储,存储数据 public void saveData() { … db.saveData(); … } } (2)编写测试TestBusiness,TestBusiness.java的示例代码如下: //******* TestBusiness.java************** public class TestBusiness { private Business business = new Business(new XMLData()); … //根据注入的存储,存储数据 public void opraData() { … business. saveData (); … } } 即通过构造函数来完成依赖注入。 从前面对这三种依赖注入的方式中可以看出:其实所有的依赖注入都离不开抽象的支持,也就是说只有"面向接口编程",才能够实现依赖注入。 读者可能还会有疑惑:虽然具体的存储方式和业务逻辑无关了,可不是还要在调用业务逻辑里来改变具体的存储方式吗?这样一来,不是还要改代码吗?看起来面向接口编程也挺简单的,那Spring又为开发人员提供了哪些帮助呢?其实,Spring为开发人员提供了调用业务逻辑的具体方式,也就是说,Spring不再需要开发人员编写调用具体调用业务逻辑,而是通过配置文档来实现业务逻辑的调用,如果具体的存储方式发生了变化,开发人员只需要改变相应的配置文档即可。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值