SpringBoot集成shiro框架
一 介绍:
主要用到SpringBoot、hibernate、swagger、mybatis、shiro、maven等技术。
项目使用idea、mysql数据库开发,idea要安装lombok插件否则会报错。
二 依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!-- <!– spring security 安全认证 –>-->
<!-- <dependency>-->
<!-- <groupId>org.springframework.boot</groupId>-->
<!-- <artifactId>spring-boot-starter-security</artifactId>-->
<!-- </dependency>-->
<!-- shiro依赖配置 -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.4.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</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-thymeleaf</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/log4j/log4j -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.7.0</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.7.0</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<!-- pagehelper分页-->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.2.10</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-data-redis -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<version>2.2.2.RELEASE</version>
</dependency>
<!-- jstl标签库-->
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.1.2</version>
</dependency>
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/redis.clients/jedis -->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20160810</version>
</dependency>
<!--日志-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<!--热部署-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>net.sf.json-lib</groupId>
<artifactId>json-lib</artifactId>
<version>2.4</version>
<classifier>jdk15</classifier>
</dependency>
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.7.0</version>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.1.3</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
<!--jsoup爬取-->
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.12.1</version>
</dependency>
三 SpringBoot yml配置文件编写:
server:
# 修改端口
port: 8888
spring:
datasource:
url: jdbc:mysql://localhost:3306/shiro?serverTimezone=UTC&characterEncoding=utf8
driver-class-name: com.mysql.cj.jdbc.Driver
username: root
password: .
# hikari 数据源转专用配置
hikari:
maximum-pool-size: 20
minimum-idle: 5
redis:
host: 127.0.0.1
port: 6379
timeout: 5000
password:
database: 0
jpa:
# 切换存储引擎
database-platform: org.hibernate.dialect.MySQL5InnoDBDialect
# 日志打印sql语句
show-sql: true
# 检查表是否存在 是否与实体类匹配 !!!
hibernate:
ddl-auto: update #指定为update,每次启动项目检测表结构有变化的时候会新增字段,表不存在时会新建,如果指定create,则每次启动项目都会清空数据并删除表,再新建
naming:
implicit-strategy: org.hibernate.boot.model.naming.ImplicitNamingStrategyLegacyJpaImpl #指定jpa的自动表生成策略,驼峰自动映射为下划线格式
#physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
thymeleaf:
cache: false
# mvc:
# view:
# prefix: /static/jsp/
# suffix: .jsp
mybatis:
mapper-locations: classpath:mapper/*.xml
type-aliases-package: com.inspur.pojo
# 配置pagehelper
pagehelper:
helper-dialect: mysql #配置方言 底层是什么数据库
# 日志配置
logging:
level:
com.ruoyi: debug
org.springframework: warn
四 实体类编写:
package com.heyu.pojo;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import javax.persistence.*;
import java.util.List;
/**
* Author heyu
* Date: 2020/7/28 17:02
* Description: 用户类
*/
@Getter
@Setter
@Entity
@ToString
@Table(name = "sys_user")
public class SysUser {
@Id
@Column(name = "ID", unique = true, nullable = false)
@SequenceGenerator(name = "RBBTJ_SEQ", sequenceName = "RBBTJ_SEQ", allocationSize = 1)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "RBBTJ_SEQ")
private Integer id;
@Column(unique = true,length = 32)
private String name;
@Column(length = 32)
private String password;
@OneToMany(cascade = CascadeType.ALL,mappedBy = "user")
private List<SysRole> roles;
}
package com.heyu.pojo;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import javax.persistence.*;
import java.util.List;
/**
* Author heyu
* Date: 2020/7/28 17:26
* Description: 角色类
*/
@Getter
@Setter
@Entity
@ToString
@Table(name = "sys_role")
public class SysRole {
@Id
@Column(name = "ID", unique = true, nullable = false)
@SequenceGenerator(name = "RBBTJ_SEQ", sequenceName = "RBBTJ_SEQ", allocationSize = 1)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "RBBTJ_SEQ")
private Integer id;
@Column(length = 32)
private String roleName;
@ManyToOne(fetch = FetchType.EAGER)
private SysUser user;
@OneToMany(cascade = CascadeType.ALL,mappedBy = "role")
private List<SysPermission> permissions;
}
package com.heyu.pojo;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import javax.persistence.*;
/**
* Author heyu
* Date: 2020/7/28 17:26
* Description: 权限类
*/
@Getter
@Setter
@Entity
@ToString
@Table(name = "sys_permission")
public class SysPermission{
@Id
@Column(name = "ID", unique = true, nullable = false)
@SequenceGenerator(name = "RBBTJ_SEQ", sequenceName = "RBBTJ_SEQ", allocationSize = 1)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "RBBTJ_SEQ")
private Integer id;
private String permission;
@ManyToOne(fetch = FetchType.EAGER)
private SysRole role;
}
五 API文档展示配置
package com.heyu.config;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
/**
* Author heyu
* Date: 2020/7/28 19:45
* Description: 系统接口 在控制层添加注释 起名 @Api(tags = "系统登陆")
*/
@Slf4j
@Configuration
@EnableSwagger2
public class SwaggerConfig {
@Bean
public Docket createRestApi(){
return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo())
.select()
.apis(RequestHandlerSelectors.any())
.paths(PathSelectors.any()).build();
}
private ApiInfo apiInfo(){
return new ApiInfoBuilder()
.title("HeYu API Doc")
.description("何其所幸,得以相遇!")
.version("1.0")
.build();
}
}
六 Dao层代码编写:
package com.heyu.dao;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.repository.NoRepositoryBean;
import org.springframework.data.repository.PagingAndSortingRepository;
import java.io.Serializable;
/**
* Author heyu
* Date: 2020/7/28 19:53
* Description: 作为父类 被其他dao层继承
*/
@NoRepositoryBean
public interface BaseDao<T, I extends Serializable>
extends PagingAndSortingRepository<T, I>, JpaSpecificationExecutor<T> {
}
package com.heyu.dao;
import com.heyu.pojo.SysUser;
/**
* Author: heyu
* <p>
* Date: 2020/5/1 21:42
* <p>
* Description:
*/
public interface UserDao extends BaseDao<SysUser, Integer> {
SysUser findByName(String name);
}
package com.heyu.dao;
import com.heyu.pojo.SysRole;
/**
* Author heyu
* Date: 2020/7/28 19:58
* Description:
*/
public interface RoleDao extends BaseDao<SysRole,Integer> {
}
七 业务逻辑层编写
package com.heyu.service;
import com.heyu.pojo.SysRole;
import com.heyu.pojo.SysUser;
/**
* Author 程鹏
* Date: 2020/7/28 19:59
* Description:
*/
public interface LoginService {
SysUser addUser(SysUser user);
SysRole addRole(SysRole role);
SysUser findByName(String name);
}
package com.heyu.service.serviceImpl;
import com.heyu.dao.RoleDao;
import com.heyu.dao.UserDao;
import com.heyu.pojo.SysPermission;
import com.heyu.pojo.SysRole;
import com.heyu.pojo.SysUser;
import javax.transaction.Transactional;
import com.heyu.service.LoginService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
/**
* Author heyu
* Date: 2020/7/28 20:01
* Description:
*/
@Service
@Transactional
public class LoginServiceImpl implements LoginService {
@Autowired
private UserDao userDao;
@Autowired
private RoleDao roleDao;
@Override
public SysUser addUser(SysUser sysUser) {
userDao.save(sysUser);
return sysUser;
}
@Override
public SysRole addRole(SysRole sysRole) {
SysUser sysUser = userDao.findByName(sysRole.getUser().getName());
sysRole.setUser(sysUser);
SysPermission permission1 = new SysPermission();
permission1.setPermission("create");
permission1.setRole(sysRole);
SysPermission permission2 = new SysPermission();
permission2.setPermission("update");
permission2.setRole(sysRole);
List<SysPermission> permissions = new ArrayList<SysPermission>();
permissions.add(permission1);
permissions.add(permission2);
sysRole.setPermissions(permissions);
roleDao.save(sysRole);
return sysRole;
}
@Override
public SysUser findByName(String name) {
return userDao.findByName(name);
}
}
八 控制层编写
package com.heyu.controller;
import com.heyu.pojo.SysRole;
import com.heyu.pojo.SysUser;
import com.heyu.service.LoginService;
import io.swagger.annotations.Api;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@RequestMapping("/system")
@RestController
@Api(tags = "系统登陆")
public class LoginController {
@Autowired
private LoginService loginService;
/**
* POST登录
* @param sysUser
* @return
*/
@PostMapping(value = "/login")
public String login(@RequestBody SysUser sysUser) {
UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(sysUser.getName(), sysUser.getPassword());
SecurityUtils.getSubject().login(usernamePasswordToken);
return "login ok!";
}
/**
* 添加用户
* @param sysUser
* @return
*/
@PostMapping(value = "/addUser")
public String addUser(@RequestBody SysUser sysUser) {
sysUser = loginService.addUser(sysUser);
return "addUser is ok! \n" + sysUser;
}
/**
* 添加角色
* @param sysRole
* @return
*/
@PostMapping(value = "/addRole")
public String addRole(@RequestBody SysRole sysRole) {
sysRole = loginService.addRole(sysRole);
return "addRole is ok! \n" + sysRole;
}
/**
* 注解的使用
* @return
*/
@RequiresRoles("admin")
@RequiresPermissions("create")
@GetMapping(value = "/create")
public String create() {
return "Create success!";
}
@GetMapping(value = "/index")
public String index() {
return "index page!";
}
@GetMapping(value = "/error")
public String error() {
return "error page!";
}
/**
* 退出的时候是get请求,主要是用于退出
* @return
*/
@GetMapping(value = "/login")
public String login() {
return "login";
}
@GetMapping(value = "/logout")
public String logout() {
return "logout";
}
}