写在前面
这篇博文跟我之前的没有绝对的连续性哈——MD5加密认证看这里
很多地方是cv别的贴子,也有很多原理性的地方没搞明白,只是知道了个“这里这样那里就会那样”,所以欢迎来访的大佬们指教(轻喷),3Q!
直接上代码
数据库五表设计(也就是现在流行的权限设计模型RBAC),设计的比较简单
CREATE TABLE `user` (
`id` int NOT NULL,
`username` varchar(25) NOT NULL,
`password` varchar(25) NOT NULL,
`ban` int DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `role` (
`role_id` int NOT NULL,
`role_name` varchar(255) DEFAULT NULL,
PRIMARY KEY (`role_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `permission` (
`permission_id` int NOT NULL,
`permission` varchar(255) DEFAULT NULL,
`permission_name` varchar(255) DEFAULT NULL,
PRIMARY KEY (`permission_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `role_permission` (
`role_id` int NOT NULL,
`permission_id` int NOT NULL,
PRIMARY KEY (`role_id`,`permission_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `user_role` (
`user_id` int NOT NULL,
`role_id` int NOT NULL,
PRIMARY KEY (`user_id`,`role_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
pom与xml
就简单的依赖和其他配置,简单!
这里的依赖有些没用上啊,但是也没错
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- 集成swagger接口文档 -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.7.0</version>
</dependency>
<!-- swagger-ui -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.7.0</version>
</dependency>
<!-- shiro-->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring-boot-web-starter</artifactId>
<version>1.4.0</version>
</dependency>
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.2.0</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.5</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.7</version>
</dependency>
<!--mybatis-plus -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.3.1</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.4.0</version>
</dependency>
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-engine-core</artifactId>
<version>2.0</version>
</dependency>
<!--mysql-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- Druid数据源 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.10</version>
</dependency>
<!-- 引入redis -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!--热部署-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<!--lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
yaml我也copy过来,说不定以后自个儿用得着
server:
port: 8084
tomcat:
uri-encoding: UTF-8
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
druid:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/shirodemo?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
username: root
password: 123456
initial-size: 10
max-active: 100
min-idle: 10
max-wait: 60000
pool-prepared-statements: true
max-pool-prepared-statement-per-connection-size: 20
time-between-eviction-runs-millis: 60000
min-evictable-idle-time-millis: 300000
test-while-idle: true
test-on-borrow: false
test-on-return: false
stat-view-servlet:
enabled: true
url-pattern: /druid/*
filter:
stat:
log-slow-sql: false
slow-sql-millis: 1000
merge-sql: false
wall:
config:
multi-statement-allow: true
redis:
host: 127.0.0.1
port: 6379
database: 1
mybatis-plus:
mapper-locations: classpath*:/mapper/**/*.xml
typeAliasesPackage: com.ztxue.shirostudy.entity
然后是“四兄弟”
controller
package com.example.shirostudy.controller;
import com.example.shirostudy.result.Msg;
import com.example.shirostudy.result.R;
import com.example.shirostudy.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.subject.Subject;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
@RestController
@Validated
@Slf4j
public class LoginController {
@Resource
UserService userService;
/**
* 登录方法
*
* @param
* @return
*/
@PostMapping("/login")
public Msg login(@RequestParam("username") String username,
@RequestParam("password") String password) {
Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken token = new UsernamePasswordToken(username, password);
try {
subject.login(token);
return Msg.success().add("JSESSIONID", subject.getSession().getId());
} catch (IncorrectCredentialsException e) {
return Msg.fail().add("msg", "密码有误");
} catch (LockedAccountException e) {
return Msg.fail().add("msg", "用户冻结");
} catch (AuthenticationException e) {
return Msg.fail().add("msg", "该用户不存在");
} catch (Exception e) {
return Msg.fail().add("msg", "未知错误");
}
}
@RequestMapping("/logout")
public R logOut() {
SecurityUtils.getSubject().logout();
return R.ok("登出成功!");
}
}
这也是controller
import com.example.shirostudy.result.Msg;
import org.apache.shiro.authz.annotation.Logical;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
/**
* <p>
* 前端控制器
* </p>
*
* @author 张童学
* @since 2021-08-04
*/
@RestController
@RequestMapping("/user")
public class UserController {
@PostMapping("/getMessage")
@RequiresRoles(logical = Logical.OR, value = {"p", "svip"})
public Msg getMessage() {
return Msg.success().add("info", "成功获得p/svip信息!");
}
@PostMapping("/getVipMessage")
@RequiresRoles(logical = Logical.OR, value = {"vip", "svip"})
public Msg getVipMessage() {
return Msg.success().add("info", "成功获得vip/svip信息!");
}
service–好像就用上两个
RoleService
import com.example.shirostudy.entity.Role;
import com.baomidou.mybatisplus.extension.service.IService;
import org.apache.ibatis.annotations.Select;
import java.util.List;
/**
* <p>
* 服务类
* </p>
*
* @author 张童学
* @since 2021-08-04
*/
public interface RoleService extends IService<Role> {
//根据用户id获取role
Role getRoleByUid(Integer uid);
//获得所有role
List<Role> getAllRoles();
}
UserService
import com.example.shirostudy.entity.User;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* <p>
* 服务类
* </p>
*
* @author 张童学
* @since 2021-08-04
*/
public interface UserService extends IService<User> {
User findUserByName(String userName);
String getPassword(String userName);
}
serviceImpl
import com.example.shirostudy.entity.Role;
import com.example.shirostudy.mapper.RoleMapper;
import com.example.shirostudy.service.RoleService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.swagger.models.auth.In;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.io.Serializable;
import java.util.List;
/**
* <p>
* 服务实现类
* </p>
*
* @author 张童学
* @since 2021-08-04
*/
@Service
public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements RoleService {
@Autowired
RoleMapper roleMapper;
//根据用户id获取role
@Override
public Role getRoleByUid(Integer uid) {
return roleMapper.getRoleByUid(uid);
}
//获得所有role
@Override
public List<Role> getAllRoles() {
return roleMapper.getAllRoles();
}
}
import com.example.shirostudy.entity.User;
import com.example.shirostudy.mapper.UserMapper;
import com.example.shirostudy.service.UserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* <p>
* 服务实现类
* </p>
*
* @author 张童学
* @since 2021-08-04
*/
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
@Autowired
UserMapper userMapper;
@Override
public User findUserByName(String userName) {
return userMapper.findUserByName(userName);
}
@Override
public String getPassword(String userName) {
return userMapper.getPassword(userName);
}
}
mapper–user、role、permission三个mapper(有些方法没用上)
import com.example.shirostudy.entity.Role;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import java.util.List;
/**
* <p>
* Mapper 接口
* </p>
*
* @author 张童学
* @since 2021-08-04
*/
@Mapper
public interface RoleMapper extends BaseMapper<Role> {
//根据用户id获取role
@Select("select r.role_name \n" +
"from role r,user u,user_role ur \n" +
"where ur.role_id = r.role_id \n" +
"and u.user_id = ur.user_id\n" +
"and u.user_id = #{userId}")
Role getRoleByUid(Integer uid);
//获得所有role
@Select("select role_name from role")
List<Role> getAllRoles();
}
import com.example.shirostudy.entity.Permission;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import java.util.List;
/**
* <p>
* Mapper 接口
* </p>
*
* @author 张童学
* @since 2021-08-04
*/
@Mapper
public interface PermissionMapper extends BaseMapper<Permission> {
//roleName获取权限List
@Select("SELECT p.permission FROM permission p, role r, role_permission rp WHERE rp.permission_id = p.permission_id AND rp.role_id = r.role_id AND r.role_name =#{roleName}")
List<Permission> getPerByRName(String roleName);
//获得所有权限
@Select("select permission.permission from permission")
List<Permission> getAllPer();
}
import com.example.shirostudy.entity.Role;
import com.example.shirostudy.entity.User;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
/**
* <p>
* Mapper 接口
* </p>
*
* @author 张童学
* @since 2021-08-04
*/
@Mapper
public interface UserMapper extends BaseMapper<User> {
@Select("select * from user where username = #{username}")
User findUserByName(String userName);
@Select("select user.password from user where username = #{username}")
String getPassword(String userName);
//根据用户id获取role
@Select("select r.role_name \n" +
"from role r,user u,user_role ur \n" +
"where ur.role_id = r.role_id \n" +
"and u.user_id = ur.user_id\n" +
"and u.user_id = #{userId}")
Role getRoleByUid(Integer uid);
}
实体类的话,也只用了三个
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import java.io.Serializable;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* <p>
*
* </p>
*
* @author 张童学
* @since 2021-08-04
*/
@Data
@EqualsAndHashCode(callSuper = false)
public class Permission implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(value = "permission_id", type = IdType.ID_WORKER)
private Integer permissionId;
private String permission;
private String permissionName;
}
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import java.io.Serializable;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* <p>
*
* </p>
*
* @author 张童学
* @since 2021-08-04
*/
@Data
@EqualsAndHashCode(callSuper = false)
public class Role implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(value = "role_id", type = IdType.ID_WORKER)
private Integer roleId;
private String roleName;
}
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import java.io.Serializable;
import java.util.List;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* <p>
*
* </p>
*
* @author 张童学
* @since 2021-08-04
*/
@Data
@EqualsAndHashCode(callSuper = false)
public class User implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(value = "user_id", type = IdType.ID_WORKER)
private Integer userId;
private String password;
private String username;
// private List<Role> roleList;
}
接着是shiro配置
ShiroConfig
import com.example.shirostudy.config.cache.RedisCacheManager;
import org.apache.shiro.cache.ehcache.EhCacheManager;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.LinkedHashMap;
@Configuration
public class ShiroConfig {
@Bean(name = "shiroFilter")
public ShiroFilterFactoryBean shiroFilter(@Qualifier("securityManager") SecurityManager securityManager) {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
//必须设置 SecurityManager,Shiro的核心安全接口
shiroFilterFactoryBean.setSecurityManager(securityManager);
//这里的/login是后台的接口名,非页面,如果不设置默认会自动寻找Web工程根目录下的"/login.jsp"页面
shiroFilterFactoryBean.setLoginUrl("/login");
LinkedHashMap<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
//配置不登录可以访问的资源,anon 表示资源都可以匿名访问
filterChainDefinitionMap.put("/css/**", "anon");
filterChainDefinitionMap.put("/js/**", "anon");
filterChainDefinitionMap.put("/img/**", "anon");
filterChainDefinitionMap.put("/druid/**", "anon");
filterChainDefinitionMap.put("/login", "anon");
filterChainDefinitionMap.put("/logout", "logout");
//对应的url访问权限可以在过滤器上禁用
//filterChainDefinitionMap.put("/user/getMessage/**","roles[svip]");
//其他资源都需要认证 authc 表示需要认证才能进行访问
filterChainDefinitionMap.put("/**", "authc");
//user表示配置记住我或认证通过可以访问的地址
//filterChainDefinitionMap.put("/**", "user");
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
return shiroFilterFactoryBean;
}
/**
* 配置核心安全事务管理器
*
* @param shiroRealm
* @return
*/
@Bean(name = "securityManager")
public SecurityManager securityManager(@Qualifier("shiroRealm") ShiroRealm shiroRealm) {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
//设置自定义realm.
securityManager.setRealm(shiroRealm);
return securityManager;
}
/**
* 身份认证realm
* @return
*/
@Bean
public ShiroRealm shiroRealm() {
ShiroRealm shiroRealm = new ShiroRealm();
//存在内存中,断电即失(重启亦失)
shiroRealm.setCacheManager(new RedisCacheManager());
// shiroRealm.setCacheManager(new EhCacheManager());
//全局缓存开启
// shiroRealm.setCachingEnabled(true);
// //授权缓存开启
// shiroRealm.setAuthorizationCachingEnabled(true);
// shiroRealm.setAuthorizationCacheName("authorizationCache");
// //认证缓存开启
// shiroRealm.setAuthenticationCachingEnabled(true);
// shiroRealm.setAuthenticationCacheName("authenticationCache");
return shiroRealm;
}
/**
* 配置Shiro生命周期处理器
*
* @return
*/
@Bean(name = "lifecycleBeanPostProcessor")
public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
return new LifecycleBeanPostProcessor();
}
/**
* 开启aop注解支持
*
* @param securityManager
* @return
*/
@Bean
public DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator() {
DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
advisorAutoProxyCreator.setProxyTargetClass(true);
return advisorAutoProxyCreator;
}
@Bean
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
return authorizationAttributeSourceAdvisor;
}
}
这里注意一下后面这两个bean,开启注解支持。
如果无,那么userController里的 @RequiresRoles(logical = Logical.OR, value = {"p", "svip"})
就无用了!
可以在ShiroConfig的shiroFilter用filterChainDefinitionMap.put("/user/getMessage/**","roles[svip]");
,即用它自定义的过滤器——roles[ ]
ShiroRealm --这里有些地方处理的挺大聪明的,大家自行优化吧
import com.example.shirostudy.entity.Permission;
import com.example.shirostudy.entity.Role;
import com.example.shirostudy.entity.User;
import com.example.shirostudy.mapper.*;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.List;
public class ShiroRealm extends AuthorizingRealm {
@Autowired
UserMapper userMapper;
@Autowired
RoleMapper roleMapper;
@Autowired
PermissionMapper permissionsMapper;
/**
* 验证用户身份
*
* @param authenticationToken 用户信息
* @return AuthenticationInfo
* @throws AuthenticationException
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
//获取用户名密码 第一种方式
String username = (String) authenticationToken.getPrincipal();
User user = userMapper.findUserByName(username);
return new SimpleAuthenticationInfo(user, user.getPassword(), getName());
}
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principal) {
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
//获取登录用户名
User user = (User) principal.getPrimaryPrincipal();
System.out.println("principal=======>" + user);
//根据用户id查role(一个用户只有一个角色)
Role role = roleMapper.getRoleByUid(user.getUserId());
info.addRole(role.getRoleName());
System.out.println("role=======>" + role);
//根据roleName查权限(一个角色可能有不止一个权限)
List<Permission> permissionList = permissionsMapper.getPerByRName(role.getRoleName());
for (Permission permission : permissionList) {
info.addStringPermission(permission.getPermission());
}
System.out.println("permissionList=======>" + permissionList);
return info;
}
}
这里取的角色和权限得跟你登录的信息有关联。
无权限类
import com.example.shirostudy.result.R;
import org.apache.shiro.authz.AuthorizationException;
import org.apache.shiro.authz.UnauthorizedException;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
@ControllerAdvice
public class NoPermissionException {
@ResponseBody
@ExceptionHandler(UnauthorizedException.class)
public R handleShiroException(Exception ex) {
return R.fail("无权限");
}
@ResponseBody
@ExceptionHandler(AuthorizationException.class)
public R AuthorizationException(Exception ex) {
return R.fail("权限认证失败");
}
}
前面controller用了两个不同的结果集,完全可以优化
import java.util.HashMap;
import java.util.Map;
public class Msg {
// 状态码
private int status;
// 提示信息
private String message;
// 封装有效数据
private Map<String, Object> data = new HashMap<String, Object>();
public static Msg success() {
Msg result = new Msg();
result.setStatus(200);
result.setMessage("success");
return result;
}
public static Msg fail() {
Msg result = new Msg();
result.setStatus(400);
result.setMessage("fail");
return result;
}
public static Msg noPermission() {
Msg result = new Msg();
result.setStatus(401);
result.setMessage("no permission");
return result;
}
public static Msg error() {
Msg result = new Msg();
result.setStatus(500);
result.setMessage("error");
return result;
}
public static Msg code(int code) {
Msg result = new Msg();
result.setStatus(code);
result.setMessage("exception");
return result;
}
public Msg add(String key, Object value) {
this.data.put(key, value);
return this;
}
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public Map<String, Object> getData() {
return data;
}
public void setData(Map<String, Object> data) {
this.data = data;
}
}
import lombok.Data;
import java.io.Serializable;
/**
* 返回前端 数据封闭类
*/
@Data
public class R implements Serializable {
private static final long serialVersionUID = 1L;
private Integer code;
private String msg;
private Object data;
public R() {
}
private R(int code, String msg, Object data) {
this.code = code;
this.msg = msg;
this.data = data;
}
//不返回数据
public static R ok() {
return new R(Constants.OK_CODE, Constants.OK_MSG, null);
}
//返回数据
public static R ok(Object data) {
return new R(Constants.OK_CODE, Constants.OK_MSG, data);
}
//返回自定义消息和数据
public static R ok(String msg, Object data) {
return new R(Constants.OK_CODE, msg, data);
}
//返回自定义-失败消息
public static R fail(String msg) {
return new R(Constants.FAIL_CODE, msg, null);
}
//返回自定义-code和失败消息
public static R fail(int errorCode, String msg) {
return new R(errorCode, msg, null);
}
}
常量类(这操作可以学)
/**
* 常量类
*/
public class Constants {
public final static int OK_CODE = 200;
public final static int FAIL_CODE = 400;
public final static int OTHER_FAIL_CODE = 333; // 其它错误
public final static String OK_MSG = "请求成功";
public final static String FAIL_MSG = "请求失败";
public final static int STATUS_0 = 0; // 可用状态
public final static int STATUS_1 = 1; // 禁用状态
}
启动类也给你们康康
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@MapperScan(value = "com.example.shirostudy.mapper")
@SpringBootApplication
public class ShiroStudyApplication {
public static void main(String[] args) {
SpringApplication.run(ShiroStudyApplication.class, args);
System.out.println("------------------端口:8084---------------");
}
}
mybatis-plus配置文件–其他更细致操作以官网为准
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.core.exceptions.MybatisPlusException;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.GlobalConfig;
import com.baomidou.mybatisplus.generator.config.PackageConfig;
import com.baomidou.mybatisplus.generator.config.StrategyConfig;
import com.baomidou.mybatisplus.generator.config.po.TableFill;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import java.util.ArrayList;
import java.util.Scanner;
// 演示例子,执行 main 方法控制台输入模块表名回车自动生成对应项目目录中
public class CodeGenerator {
/**
* <p>
* 读取控制台内容
* </p>
*/
public static String scanner(String tip) {
Scanner scanner = new Scanner(System.in);
StringBuilder help = new StringBuilder();
help.append("请输入" + tip + ":");
System.out.println(help.toString());
if (scanner.hasNext()) {
String ipt = scanner.next();
if (StringUtils.isNotBlank(ipt)) {
return ipt;
}
}
throw new MybatisPlusException("请输入正确的" + tip + "!");
}
public static void main(String[] args) {
// 代码生成器
AutoGenerator mpg = new AutoGenerator();
// 全局配置(别导错包)
GlobalConfig gc = new GlobalConfig();
String projectPath = System.getProperty("user.dir");
gc.setOutputDir(projectPath + "/ShiroStudy/src/main/java");
gc.setAuthor("张童学");
gc.setOpen(false);
gc.setFileOverride(false);
gc.setServiceName("%sService");
gc.setIdType(IdType.ID_WORKER);
gc.setDateType(DateType.ONLY_DATE);
mpg.setGlobalConfig(gc);
// 数据源配置
DataSourceConfig dsc = new DataSourceConfig();
dsc.setUrl("jdbc:mysql://localhost:3306/shirodemo?useUnicode=true&useSSL=false&characterEncoding=utf8");
dsc.setDriverName("com.mysql.cj.jdbc.Driver");
dsc.setDbType(DbType.MYSQL);
dsc.setUsername("root");
dsc.setPassword("123456");
mpg.setDataSource(dsc);
// 包配置
PackageConfig pc = new PackageConfig();
pc.setParent("com.example.shirostudy");
pc.setEntity("entity");
pc.setController("controller");
pc.setMapper("mapper");
pc.setService("service");
pc.setServiceImpl("service.Impl");
mpg.setPackageInfo(pc);
// 策略配置
StrategyConfig strategy = new StrategyConfig();
strategy.setInclude("user","role","permission","role_permission","sys_token","user_role");// 映射的表名
strategy.setNaming(NamingStrategy.underline_to_camel);
strategy.setColumnNaming(NamingStrategy.underline_to_camel);
strategy.setEntityLombokModel(true);// 自动lombok
strategy.setLogicDeleteFieldName("is_deleted");// 乐观锁
strategy.setRestControllerStyle(true);// rest风格
strategy.setControllerMappingHyphenStyle(true);// 下划线风格
// 自动填充配置
ArrayList<TableFill> tableFills = new ArrayList<>();
tableFills.add(new TableFill("gmt_create", FieldFill.INSERT));
tableFills.add(new TableFill("gmt_modified", FieldFill.INSERT_UPDATE));
// 配置完成,执行
mpg.setStrategy(strategy);
mpg.execute();
}
}
写在后面
shiro的认证与鉴权网上还有很多非常奶思的博文教程,本文仅做本人的学习记录(狗头)
欢迎大佬指教!3Q!