08 SSM整合案例(企业权限管理系统):09.用户和角色操作

04.AdminLTE的基本介绍

05.SSM整合案例的基本介绍

06.产品操作

07.订单操作

08.权限控制

09.用户和角色操作

10.权限关联

11.AOP日志

09.用户和角色操作 

 


 

 1. 用户操作-查询所有用户

 1.用户操作-查询所有用户操作

 3.3.1.用户查询页面 user-list.jsp
 请在资料中查看具体代码

                            <!--数据列表-->
                            <table id="dataList"
                                class="table table-bordered table-striped table-hover dataTable">
                                <thead>
                                    <tr>
                                        <th class="" style="padding-right: 0px"><input
                                            id="selall" type="checkbox" class="icheckbox_square-blue">
                                        </th>
                                        <th class="sorting_asc">ID</th>
                                        <th class="sorting_desc">用户名</th>
                                        <th class="sorting_asc sorting_asc_disabled">邮箱</th>
                                        <th class="sorting_desc sorting_desc_disabled">联系电话</th>
                                        <th class="sorting">状态</th>
                                        <th class="text-center">操作</th>
                                    </tr>
                                </thead>
                                <tbody>

                                    <c:forEach items="${userList}" var="user" varStatus="s">
                                        <tr>
                                            <td><input name="ids" type="checkbox" id="${s.index}" value="${user.id}"></td>
                                            <td>${user.id }</td>
                                            <td>${user.username }</td>
                                            <td>${user.email }</td>
                                            <td>${user.phoneNum }</td>
                                            <td>${user.statusStr }</td>                                            
                                            <td class="text-center">
                                                <a href="${pageContext.request.contextPath}/user/findById.do?id=${user.id}" class="btn bg-olive btn-xs">详情</a>
                                                <a href="${pageContext.request.contextPath}/user/findUserByIdAndAllRole.do?id=${user.id}" class="btn bg-olive btn-xs">添加角色</a>
                                            </td>
                                        </tr>
                                    </c:forEach>
                                </tbody>

视图层  UserController  

 

@Controller
@RequestMapping(value = "/user")
public class UsersController {

    @Autowired
    private IUserService userService;

    @RequestMapping("/findAll.do")
    public ModelAndView findAll() throws Exception{

        ModelAndView mv = new ModelAndView("user-list2");
        //获取一个添加对象
        List<UserInfo> userList = userService.findAll();
        //attributeName取决于jsp页面上的EL表达式{}里面的字符串
        mv.addObject("userList",userList);
        return mv;
    }

}

 

 UserServiceImpl

 新添加的部分代码:

 

    // 查询所有用户
    @Override
    public List<UserInfo> findAll() throws Exception {
        return userDao.findAll();
    }

 持久层 IUserDao

 新添加的部分代码:

    /**
     * 查询所有用户
     * @return
     * @throws Exception
     */
    @Select("select * from USERS")
    public List<UserInfo> findAll() throws Exception;

 

 user-list.jsp里面的一个按钮控件通过onclick 实现跳转请求  

                            <!--工具栏-->
                            <div class="pull-left">
                                <div class="form-group form-inline">
                                    <div class="btn-group">
                                        <button type="button" class="btn btn-default" title="新建" onclick="location.href='${pageContext.request.contextPath}/pages/user-add.jsp'">
                                            <i class="fa fa-file-o"></i> 新建
                                        </button>
                                        
                                        <button type="button" class="btn btn-default" title="刷新">
                                            <i class="fa fa-refresh"></i> 刷新
                                        </button>
                                    </div>
                                </div>
                            </div>

 

  user-add.jsp里面关键信息如下:

  form表单的action属性

            <!-- 内容头部 /-->

            <form action="${pageContext.request.contextPath}/user/save.do"
                method="post">
                <!-- 正文区域 -->

 

  3.4 用户添加  

 DAO层

 

    /**
     *  添加一个新用户
     * @param userInfo
     */
    @Insert({"insert into USERS(username,email,password,phoneNum,status)",
            "values(#{username},#{email},#{password},#{phoneNum},#{status})"})
    public void save(UserInfo userInfo) throws Exception;

 

Utils工具类

 

package cn.bjut.ssm.utils;

import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

public class BCryptPasswordEncoderUtils {

    private static BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
    //工具类的方法最好用static关键字修饰
    //明文转换成密文工具类
    public static String encodePassword(String password){

        return bCryptPasswordEncoder.encode(password);
    }
}

 

Service层

    //添加一个新用户
    @Override
    public void save(UserInfo userInfo) throws Exception {
        //对密码进行加密处理
        userInfo.setPassword(bCryptPasswordEncoder.encode(userInfo.getPassword()));
        userDao.save(userInfo);
        //返回void
        return ;
    }

 

 Controller层

 

    //添加用户(后自动请求查询所有用户)
    @RequestMapping("/save.do")
    public String save(UserInfo userInfo)throws Exception{
        userService.save(userInfo);
        //返回字符串为当前控制类的注解@RequestMapping后面小括号里的内容
        return "redirect:findAll.do";
    }

 

 

 

 修改oracle数据库中表的varchar2字段类型长度 

 

  

package cn.bjut.ssm.utils;

import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

public class BCryptPasswordEncoderUtils {

    private static BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
    //工具类的方法最好用static关键字修饰
    //明文转换成密文工具类
    public static String encodePassword(String password){

        return bCryptPasswordEncoder.encode(password);
    }

    //构造一个主方法用于转换之前明文密码获得加密后的字符串
    public static void main(String[] args) {

        //之前明文密码:itheima
        //$2a$10$ylUiLsD7W.hqjGIsND9/CeuKRxz4.4oHsyZulKtfErHzL5WAkOqtW
        String code = BCryptPasswordEncoderUtils.encodePassword("itheima");
        //打印到控制台
        System.out.println(code);

    }
}

 

-- 查询表users的数据
select * from users t;
-- 插入之前的明文密码的转换字符串密文
update USERS set PASSWORD ='$2a$10$ylUiLsD7W.hqjGIsND9/CeuKRxz4.4oHsyZulKtfErHzL5WAkOqtW' 
where USERNAME = 'ssm08';
-- 提交事务
commit;

  spring-security.xml

  

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:security="http://www.springframework.org/schema/security"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans          
    http://www.springframework.org/schema/beans/spring-beans.xsd          
    http://www.springframework.org/schema/security          
    http://www.springframework.org/schema/security/spring-security.xsd">


    <!-- 配置不拦截的静态资源和登录相关页面 -->
    <security:http pattern="/login.jsp" security="none"/>
    <security:http pattern="/failer.jsp" security="none"/>
    <security:http pattern="/css/**" security="none"/>
    <security:http pattern="/img/**" security="none"/>
    <security:http pattern="/images/**" security="none"/>
    <security:http pattern="/plugins/**" security="none"/>
    
    <!-- 
        配置具体的规则 
        auto-config="false"    选用自己编写登录的页面,不用框架提供的默认登录页面
        use-expressions="false"    是否使用SPEL表达式(还没学习过)
    -->
    <security:http auto-config="false" use-expressions="true" >
        <!-- 配置具体的拦截的规则 pattern="请求路径的规则" access="访问系统的人,必须有ROLE_USER的角色" -->
        <security:intercept-url pattern="/**" access="hasAnyRole('ROLE_USER','ROLE_ADMIN')"/>
        <!--<security:intercept-url pattern="/**" access="ROLE_USER,ROLE_ADMIN"/>-->

        <!--如果没有login-processing-url这一属性,那么登录表单的action,必须为j_spring_secutity_check-->
        <!-- 定义跳转的具体的页面 -->
        <security:form-login  
            login-page="/login.jsp"
            login-processing-url="/login"
            username-parameter="username" password-parameter="password"
            default-target-url="/index.jsp"
            authentication-failure-url="/failer.jsp"
            authentication-success-forward-url="/index.jsp"
        />
        
        <!-- 关闭跨域请求 -->
        <security:csrf disabled="true"/>
        <!-- 退出 -->
        <security:logout invalidate-session="true" logout-url="/logout.do" logout-success-url="/login.jsp" />
        
    </security:http>
    
    <!-- 切换成数据库中的用户名和密码 -->
    <security:authentication-manager>
        <security:authentication-provider user-service-ref="userService">
            <!-- 配置加密的方式 -->
            <security:password-encoder ref="passwordEncoder"/>
        </security:authentication-provider>
    </security:authentication-manager>
    
    <!-- 配置加密类 -->
    <bean id="passwordEncoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"/>
    
    <!-- 提供了入门的方式,在内存中存入用户名和密码 
    <security:authentication-manager>
        <security:authentication-provider>
            <security:user-service>
                <security:user name="admin" password="{noop}admin" authorities="ROLE_USER"/>
            </security:user-service>
        </security:authentication-provider>
    </security:authentication-manager>
    -->

    
 </beans>

 

  Service层的 实现了接口UserDetailsService的实现类

  cn.bjut.ssm.service.impl.UserServiceImpl

@Service(value = "userService")
@Transactional  //注解的方式使用spring事务管理
public class UserServiceImpl implements IUserService {
    @Autowired
    private IUserDao userDao;

    @Autowired  //注入加密类
    private BCryptPasswordEncoder bCryptPasswordEncoder;



    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        //UserInfo是domain包下的实体类
        UserInfo userInfo = null;

        try{
            userInfo = userDao.findByUsername(username);
        } catch(Exception e){
            e.printStackTrace();
        }

        //把自己查询到的实体类中的认证信息封装成UserDetails
        //"{noop}"使用密码明文的必要前缀

        // User user = new User(userInfo.getUsername(),"{noop}"+userInfo.getPassword(),getAuthority(userInfo.getRoles()));
        User user = new User(userInfo.getUsername(),userInfo.getPassword(),userInfo.getStatus() ==0 ?false:true,true,true,true,getAuthority(userInfo.getRoles()));

        return user;

    }

    //这个成员方法作用就是返回一个List集合,集合中装入的是角色描述。
    //实际项目中应该是从数据库中获取role描述后封装到这个方法体里面。
    public List<SimpleGrantedAuthority> getAuthority(List<Role> roles){

        List<SimpleGrantedAuthority> list = new ArrayList<>();


        //增强for循环
        for (Role role :roles){
                     // new 匿名对象
            list.add(new SimpleGrantedAuthority("ROLE_"+role.getRoleName()));
        }

        return list;
    }

    // 查询所有用户
    @Override
    public List<UserInfo> findAll() throws Exception {
        return userDao.findAll();
    }

    //添加一个新用户
    @Override
    public void save(UserInfo userInfo) throws Exception {
        //对密码进行加密处理
        userInfo.setPassword(bCryptPasswordEncoder.encode(userInfo.getPassword()));
        userDao.save(userInfo);
        //返回void
        return ;
    }


}

  6.用户操作-用户详情服务器端代码实现

3.用户操作-用户详情查询流程分析

  user-list.jsp

                                                <a href="${pageContext.request.contextPath}/user/findById.do?id=${user.id}" class="btn bg-olive btn-xs">详情</a>
                                                <a href="${pageContext.request.contextPath}/user/findUserByIdAndAllRole.do?id=${user.id}" class="btn bg-olive btn-xs">添加角色</a>
                                            </td>

  详情 按钮可以向服务器提交一个GET方式的请求。

  


 

 视图层

@Controller
@RequestMapping(value = "/user")
public class UsersController {

    @Autowired
    private IUserService userService;

    @RequestMapping("/findById.do")
        public ModelAndView findById(String id)throws Exception{

        ModelAndView mv = new ModelAndView();
        //获取一个Object
        UserInfo userInfo = userService.findById(id);
        mv.addObject("user",userInfo);
        mv.setViewName("user-show2");
        return mv;
    }

 

Service层

 

@Service(value = "userService")
@Transactional  //注解的方式使用spring事务管理
public class UserServiceImpl implements IUserService {
    @Autowired
    private IUserDao userDao;

    @Autowired  //注入加密类
    private BCryptPasswordEncoder bCryptPasswordEncoder;



    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        //UserInfo是domain包下的实体类
        UserInfo userInfo = null;

        try{
            userInfo = userDao.findByUsername(username);
        } catch(Exception e){
            e.printStackTrace();
        }

        //把自己查询到的实体类中的认证信息封装成UserDetails
        //"{noop}"使用密码明文的必要前缀

        // User user = new User(userInfo.getUsername(),"{noop}"+userInfo.getPassword(),getAuthority(userInfo.getRoles()));
        User user = new User(userInfo.getUsername(),userInfo.getPassword(),userInfo.getStatus() ==0 ?false:true,true,true,true,getAuthority(userInfo.getRoles()));

        return user;

    }

    //这个成员方法作用就是返回一个List集合,集合中装入的是角色描述。
    //实际项目中应该是从数据库中获取role描述后封装到这个方法体里面。
    public List<SimpleGrantedAuthority> getAuthority(List<Role> roles){

        List<SimpleGrantedAuthority> list = new ArrayList<>();


        //增强for循环
        for (Role role :roles){
                     // new 匿名对象
            list.add(new SimpleGrantedAuthority("ROLE_"+role.getRoleName()));
        }

        return list;
    }

    // 查询所有用户
    @Override
    public List<UserInfo> findAll() throws Exception {
        return userDao.findAll();
    }

    //添加一个新用户
    @Override
    public void save(UserInfo userInfo) throws Exception {
        //对密码进行加密处理
        userInfo.setPassword(bCryptPasswordEncoder.encode(userInfo.getPassword()));
        userDao.save(userInfo);
        //返回void
        return ;
    }

    //通过ID查询用户详情
    @Override
    public UserInfo findById(String id) throws Exception{

        return userDao.findByUserId(id);
    }


}

 

 IUserDAO 

 

    //通过用户ID查询Role的详情
    @Select("select id,username,phoneNum,status from USERS where id = #{ UserId }")
    @Results({
            @Result(property = "id",column = "id",id = true),
            @Result(property = "username",column = "username"),
            @Result(property = "phoneNum",column = "phoneNum"),
            @Result(property = "status",column = "status"),
            //通过中间表查询多对多关系,返回一个其它实体类的List集合
            @Result(property = "roles",column = "id",javaType =java.util.List.class,many = @Many(select = "cn.bjut.ssm.dao.IRoleDao.findRoleByUserId"))
    })
    public UserInfo findByUserId(String UserId) throws Exception;

 IRoleDao

 

public interface IRoleDao {
    //根据用户ID查询出所有对应的角色
    @Select("select * from ROLE where id in( select ROLEID from USERS_ROLE where USERID  = #{userId})")
    @Results({
            @Result(id = true,property = "id",column = "id"),
            @Result(property = "roleName",column = "roleName"),
            @Result(property = "roleDesc",column = "roleDesc"),

            @Result(property = "permissions",column = "id",javaType = java.util.List.class,many = @Many(select = "cn.bjut.ssm.dao.IPermissionDao.findPermissionByRoleId"))
    })

    public List<Role> findRoleByUserId(String userId) throws Exception;


}

 

 IPermissionDao

 

public interface IPermissionDao {

    //多对多表的查询,先查询中间表作为结果集。
    @Select("select * from PERMISSION where id in(select permissionId from role_permission where roleId = #{ roleId})")
    public List<Permission> findPermissionByRoleId(String roleId) throws Exception;
}

 

  user-show.jsp

  

                        <!--数据列表-->
                        <div class="tab-pane" id="tab-treetable">
                            <table id="collapse-table"
                                class="table table-bordered table-hover dataTable">
                                <thead>
                                    <tr>
                                        <th>名称</th>
                                        <th>描述</th>
                                    </tr>
                                </thead>

                                <tr data-tt-id="0">
                                    <td colspan="2">${user.username}</td>
                                </tr>

                                <tbody>
                                    <c:forEach items="${user.roles}" var="role" varStatus="s">
                                        <tr data-tt-id="${s.index +1 }" data-tt-parent-id="0" >
                                            <td>${role.roleName }</td>
                                            <td>${role.roleDesc }</td>
                                        </tr>
                                        <c:forEach items="${role.permissions}" var="permission">
                                            <tr data-tt-id="1-1" data-tt-parent-id="${s.index +1 }">
                                                <td>${permission.permissionName}</td>
                                                <td>${permission.url}</td>
                                            </tr>

                                        </c:forEach>
                                    </c:forEach>
                                </tbody>
                            </table>
                        </div>
                        <!--数据列表/-->

 

 9.角色操作-查询所有角色

 4.角色操作-查询所有角色流程分析

 在aside.jsp文件内有侧边栏导航的链接地址,这些就是Controller层的@RequestMapping注解后面的value值。

 ssm_web子模块新建一个RoleController实现。

 DAO层  IRoleDao 

    @Select("select * from ROLE ")
    @Results({
            @Result(id = true,property = "id",column = "id"),
            @Result(property = "roleName",column = "roleName"),
            @Result(property = "roleDesc",column = "roleDesc"),
    })
    //查询所有的Role信息返回一个List集合
    public List<Role> findAll()throws Exception;

 Service层  RoleServiceImpl

 

@Service
@Transactional  //注解的方式使用spring事务管理
public class RoleServiceImpl implements IRoleService {

    @Autowired
    private IRoleDao roleDao;
    //查询所有Role的Service层实现
    @Override
    public List<Role> findAll() throws Exception {
        return roleDao.findAll();
    }
}

 

  视图层  RoleController

  

/**
 * 角色管理Controller
 */
@Controller
@RequestMapping(name ="/role")
public class RoleController {

    @Autowired
    private IRoleService roleService;
    //查询所有角色
    @RequestMapping ("/findAll.do")
    public ModelAndView findAll() throws Exception{
        ModelAndView mv = new ModelAndView();
        List<Role> roleList = roleService.findAll();
        mv.addObject("roleList",roleList);
        mv.setViewName("role-list2");
        return mv;

    }
}

 @RequestMapping (value="{

       } ")  可以支持通配符* 的请求路径的数组。

 

 Controller层  

/**
 * 角色管理Controller
 */
@Controller
@RequestMapping("/role")
public class RoleController {

    @Autowired
    private IRoleService roleService;
    //新建保存一个Role
    @RequestMapping(value = {
            "/save.do"
    })
    public String saveRole(Role role) throws Exception{

        roleService.saveRole( role);
        return "redirect:findAll.do";
    }

DAO层

 

public interface IRoleDao {

    //插入一条Role完整信息
    @Insert({"insert into ROLE (roleName,roleDesc) ",
             "values(#{roleName},#{roleDesc})"})
    public void saveRole(Role role)throws Exception;

 

PL/SQL Developer插入两条PERMISSION表的数据以供后续测试使用。

-- 查询PERMISSION表中所有数据
select * from permission t

-- 添加两条测试记录到PERMISSION表
insert into permission ( permissionname, URL ) values('user findAll','/user/findAll.do');
insert into permission ( permissionname, URL ) values('user findByID','/user/findById.do');
commit;

在WEB-INF/pages/目录下copy一份 permission-list.jsp作为前端显示的页面。

 

@Controller
@RequestMapping(value="/permission")
public class PermissionController {
    @Autowired
    private IPermissionService permissionService;

    @RequestMapping("/findAll.do")
    public ModelAndView findAll() throws Exception{

        ModelAndView mv = new ModelAndView();
        List<Permission> permissionList = permissionService.findAll();
        mv.addObject("permissionList",permissionList);
        mv.setViewName("permission-list2");
        return mv;
    }

}

 

 DAO层的接口 IPermissionDao

  

public interface IPermissionDao {

    //查询所有权限
    @Select("select * from PERMISSION")
    public List<Permission> findAll() throws Exception;

 

 

 

 

====================

end

posted @ 2019-09-24 17:05  Marlon康  阅读(1273)  评论(0编辑  收藏  举报