首页 > 编程语言 > 详细

前后端分离的Web应用程序中使用Spring Security+Mybatis+JWT非对称加密+动态权限管理(二):配置参数、创建实体和接口

时间:2021-05-25 12:29:09      阅读:17      评论:0      收藏:0      [点我收藏+]

1、修改pom.xml文件,引入相关依赖。主要的依赖有mybatis、数据库驱动(我这里用的是access数据库,所以引入ucanaccess依赖,其他数据库应相应修改)、Spring security、fastjson(用于操作json)。所有依赖如下:

技术分享图片
<dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>net.sf.ucanaccess</groupId>
        <artifactId>ucanaccess</artifactId>
           <version>5.0.1</version>
    </dependency>
    <dependency>    
        <groupId>org.mybatis.spring.boot</groupId>
        <artifactId>mybatis-spring-boot-starter</artifactId>
        <version>2.1.0</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-security</artifactId>
    </dependency>
    <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt</artifactId>
            <version>0.7.0</version>
    </dependency>
    <dependency>
        <groupId>javax.xml.bind</groupId>
        <artifactId>jaxb-api</artifactId>
        </dependency>
    <dependency>
           <groupId>com.google.code.gson</groupId>
           <artifactId>gson</artifactId>
           </dependency>
    <dependency>
        <groupId>com.alibaba</groupId>  
        <artifactId>fastjson</artifactId>  
        <version>1.2.41</version>  
    </dependency>
  </dependencies>
所有依赖

2、配置application.properties,在main/resources文件夹中创建或修改application.properties文件,写入数据库配置和mybatis配置,如下。第一行是数据库驱动。第二行是数据库地址。第三行是数据库密码,根据数据库类型,可能还需要配置数据库用户名。第四行是mybatis的mapper位置,其中的mappers/*.xml需要按照自己需要配置,此处我是在main/resources文件夹下建了一个mappers文件夹,所有与mybatis相关的.xml文件都放在这个文件夹里,程序编译后会在target/classes文件下生成mappers文件夹,这些xml文件也被导入,因此这里的路径写classpath:mappers/*.xml。最后一行是防止数据空值时出错,可以删除该行。

spring.datasource.driver-class-name = net.ucanaccess.jdbc.UcanaccessDriver  
spring.datasource.url = jdbc:ucanaccess://D:/mybatis/test.mdb;openExclusive=false;ignoreCase
spring.datasource.password = 123456
mybatis.mapper-locations=classpath:mappers/*.xml
mybatis.configuration.call-setters-on-nulls=true

3、创建实体,按照上一篇的数据库结构设计,设计了五个数据表,但这里只需要建三个实体即可,即User、Role、Menu。代码分别如下。

技术分享图片
public class User implements UserDetails{
    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    private String id;
    private String username;
    private String realname;
    private String email;
    private String password;
    private Boolean enabled;
    private Boolean accountNonExpired;
    private Boolean accountNonLocked;
    private Boolean credentialsNonExpired;
    List <Role> roles=new ArrayList<> ();
    
    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", username=‘" + username + ‘\‘‘ +
                ", password=‘" + password + ‘\‘‘ +
                ", enabled=" + enabled +
                ", accountNonExpired=" + accountNonExpired +
                ", accountNonLocked=" + accountNonLocked +
                ", credentialsNonExpired=" + credentialsNonExpired +
                ", roles=" + roles +
                ‘}‘;
    }
    
    @Override
    public Collection <? extends GrantedAuthority> getAuthorities(){
        List <SimpleGrantedAuthority> authorities = new ArrayList<> ();
        for(Role role : roles) {
            authorities.add(new SimpleGrantedAuthority(role.getNameEn()));
        }
        return authorities;
    }

    @Override
    public boolean isAccountNonExpired() {
        return accountNonExpired;
    }

    @Override
    public boolean isAccountNonLocked() {
        return accountNonLocked;
    }
    @Override
    public boolean isCredentialsNonExpired() {
        return credentialsNonExpired;
    }
    @Override
    public boolean isEnabled() {
        return enabled;
    }

    public String getRealname() {
        return realname;
    }

    public void setRealname(String realname) {
        this.realname = realname;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public void setEnabled(Boolean enabled) {
        this.enabled = enabled;
    }

    public void setAccountNonExpired(Boolean accountNonExpired) {
        this.accountNonExpired = accountNonExpired;
    }

    public void setAccountNonLocked(Boolean accountNonLocked) {
        this.accountNonLocked = accountNonLocked;
    }

    public void setCredentialsNonExpired(Boolean credentialsNonExpired) {
        this.credentialsNonExpired = credentialsNonExpired;
    }

    public List<Role> getRoles() {
        return roles;
    }

    public void setRoles(List<Role> roles) {
        this.roles = roles;
    }
    
    
    @Override
    public boolean equals(Object obj) {
        if (obj instanceof User) {
            return this.username.equals(((User) obj).username);
        }
        return false;
    }
    
    @Override
    public int hashCode() {
        return this.username.hashCode();
    }
}
User
技术分享图片
public class Menu {
    private Integer id;
    private String pattern;
    private List<Role> roles;
    
    public List<Role> getRoles() {
        return roles;
    }
    public void setRoles(List<Role> roles) {
        this.roles = roles;
    }
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getPattern() {
        return pattern;
    }
    public void setPattern(String pattern) {
        this.pattern = pattern;
    }
    
}
Menu
技术分享图片
public class Role {
    private String id;
    private String nameEn;
    private String nameZh;
    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }
    public String getNameEn() {
        return nameEn;
    }
    public void setNameEn(String nameEn) {
        this.nameEn = nameEn;
    }
    public String getNameZh() {
        return nameZh;
    }
    public void setNameZh(String nameZh) {
        this.nameZh = nameZh;
    }
}
Role

这里面Role和Menu都很容易理解,在User实体中有两处代码需要注意:下面这段代码是指根据Role的英文名得到用户的权限信息,因为我在这里把权限和角色统一了,不再区分,所以增加了这段代码:

    @Override
    public Collection <? extends GrantedAuthority> getAuthorities(){
        List <SimpleGrantedAuthority> authorities = new ArrayList<> ();
        for(Role role : roles) {
            authorities.add(new SimpleGrantedAuthority(role.getNameEn()));
        }
        return authorities;
    }

在User实体中还需要注意,其中的enabled、accountNonExpired、accountNonLocked、credentialsNonExpired这几个字段使用isXXX()这样的方法,而不是用getXXX()这样的方法。

4、创建两个接口UserRepository和MenuRepository。代码如下:

@Mapper
public interface UserRepository {
    public List <User> getAllUser();
    public User getUserByUsername(String username);
    public List<Role> getRolesByUid(String id);
}
@Mapper
public interface MenuRepository {
    List <Menu> getAllMenu();
}

5、在mappers文件夹里创建MenuMapper.xml和UserMapper.xml,当然也可以只创建一个,把代码都写在一起。

技术分享图片
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.repository.MenuRepository">
    <resultMap id="MenuResultMap" type="com.entity.Menu">
        <id property="id" column="id" />
        <result property="pattern" column="pattern"></result>
        <collection property="roles" ofType="com.entity.Role">
            <id column="rid" property="id"/>
            <result column="rnameEn" property="nameEn" />
            <result column="rnameZh" property="nameZh" />
        </collection>
    </resultMap>
    <select id="getAllMenu" resultMap="MenuResultMap">
        select m.*, r.id as rid, r.nameEn as rnameEn, r.nameZh as rnameZh from [menu] m left join [menu_role] mr on m.`ID`=mr.`mid` left join [role] r on r.`id`=mr.`rid`
    </select>
</mapper>
MenuMapper
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.repository.UserRepository">    
    <!-- 获取所有用户 -->
    <select id="getAllUser" resultType="com.entity.User">
        select * from [user]
    </select>    
    <!-- 根据用户名查找用户 -->
    <select id="getUserByUsername" resultType="com.entity.User">
        select * from [user] where username=#{username}
    </select>  
    <!-- 根据id选择角色 -->
    <select id="getRolesByUid" resultType="com.entity.Role">
        select r.* from [role]r,[user_role]ur where (ur.`uid`=#{id} and r.`id`=ur.`rid`)
    </select>
</mapper>

MenuMapper.xml里的代码较难理解,主要是要理解两次用left join,多表联合查询,得到的结果为一个resultMap,在这个resultMap中,部分数据来自Menu实体,部分数据来自Role实体,其中的column是指实体中的字段(不是指数据库),property是指查询语句中select和from之间的字段名称,有as的按照as后的名称,没有as的话就按照数据库中的原字段名称。

前后端分离的Web应用程序中使用Spring Security+Mybatis+JWT非对称加密+动态权限管理(二):配置参数、创建实体和接口

原文:https://www.cnblogs.com/wwwzgy/p/14808022.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!