SpringBoot demo(一) 一 项目搭建

新建一个springBoot项目

  1. 使用IDEA新建一个项目
    在这里插入图片描述
    在这里插入图片描述
    创建的项目结构如下
    在这里插入图片描述
  2. 配置application.yml
server:
  # 服务器的HTTP端口,默认为80 need
  port: 8081
  servlet:
    # 应用的访问路径
    context-path: /
  tomcat:
    # tomcat的URI编码
    uri-encoding: UTF-8
  1. 创建一个控制类
package com.boo.spring_boot_demo.web.controller.test;

@Controller
@RequestMapping("/test")
public class TestController {
    
    

    private final String prefix = "test/";

    // 返回json数据
    @PostMapping("/test")
    @ResponseBody
    public String test(){
    
    
        return "test";
    }

    // 返回一个页面
    @GetMapping("/hello")
    public String hello(){
    
    
        return prefix + "hello";
    }

}

在这里插入图片描述

3.1 测试访问服务
3.1.1 启动项目,访问/test/test(这里用的postman),如图:
在这里插入图片描述
3.1.2 访问/test/hello
在这里插入图片描述
如图,访问报404错误
原因:没有配置后台模板引擎

  1. 配置后台模板引擎,这里用的是 thymeleaf
    4.1 引入依赖
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

4.2 在application.yml中添加模板引擎相关配置

# spring 配置
spring:
  # 模板引擎 need
  thymeleaf:
    prefix:
      classpath: /templates   # 访问template下的html文件需要配置模板,映射
    # 禁用缓存
    cache: false

4.3 重启服务后访问/test/hello
在这里插入图片描述
5. 在项目中使用日志
springBoot web默认支持 slf4j,在项目中的使用
5.1 代码声明

private static final Logger log = LoggerFactory.getLogger(SysLoginController.class);

5.2 注解方式
在这里插入图片描述
使用

log.error();
log.warn();
log.info();
...

整合shiro

shiro 主要有三大功能模块:

1. Subject:主体,一般指用户。
2. SecurityManager:安全管理器,管理所有Subject,可以配合内部安全组件。(类似于SpringMVC中的DispatcherServlet)
3. Realms:用于进行权限信息的验证,一般需要自己实现

  1. 引入相关依赖
<dependency>
    <groupId>org.apache.shiro</groupId>
    <artifactId>shiro-spring-boot-web-starter</artifactId>
    <version>1.7.0</version>
</dependency>
  1. 创建权限控制相关实体类(参考)
    2.1 用户实体类
    @Data
    @AllArgsConstructor // 添加一个构造函数,该构造函数含有所有已声明字段属性参数
    public class SysUser {
          
          
        private String id;
        private String userName;
        private String password;
        
        /** 用户对应的角色集合 */
        private Set<SysRole> roles;
    }
    
    2.2 角色
    @Data
    @AllArgsConstructor
    public class SysRole {
          
          
        private String id;
        private String roleName;
    
        /** 角色对应权限集合 */
        private Set<SysPermissions> permissions;
    }
    
    2.3 权限
    @Data
    @AllArgsConstructor
    public class SysPermissions {
          
          
        private String id;
        private String permissionsName;
    }
    
  2. 用户信息管理(模拟查询用户数据)
@Service
public class SysLoginServiceImpl implements ISysLoginService {
    
    

    @Override
    public SysUser getSysUserByUserName(String getMapByName) {
    
    
        return getUserByUserName(getMapByName);
    }

    /**
     * 模拟数据库查询
     * @param userName 用户名
     * @return SysUser
     */
    private SysUser getUserByUserName(String userName) {
    
    
        SysPermissions permissions1 = new SysPermissions("1", "data:query");
        SysPermissions permissions2 = new SysPermissions("2", "data:add");
        Set<SysPermissions> permissionsSet = new HashSet<>();
        permissionsSet.add(permissions1);
        permissionsSet.add(permissions2);
        SysRole role = new SysRole("1", "admin", permissionsSet);
        Set<SysRole> roleSet = new HashSet<>();
        roleSet.add(role);
        SysUser user = new SysUser("1", "boo", "123456", roleSet);
        Map<String, SysUser> map = new HashMap<>();
        map.put(user.getUserName(), user);

        Set<SysPermissions> permissionsSet1 = new HashSet<>();
        permissionsSet1.add(permissions1);
        SysRole role1 = new SysRole("2", "user", permissionsSet1);
        Set<SysRole> roleSet1 = new HashSet<>();
        roleSet1.add(role1);
        SysUser user1 = new SysUser("2", "wangwu", "123456", roleSet1);
        map.put(user1.getUserName(), user1);
        return map.get(userName);
    }
}
  1. 自定义Realm
    用于查询用户的角色和权限信息并保存到权限管理器
package com.boo.spring_boot_demo.framework.shiro.realm;

import cn.hutool.core.util.StrUtil;
import com.boo.spring_boot_demo.domain.system.SysPermissions;
import com.boo.spring_boot_demo.domain.system.SysRole;
import com.boo.spring_boot_demo.domain.system.SysUser;
import com.boo.spring_boot_demo.service.system.ISysLoginService;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
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;

/** 自定义Realm用于查询用户的角色和权限信息并保存到权限管理器
 * description: CustomRealm <br>
 * date: 2021/3/23 11:24 <br>
 * author: boo <br>
 * version: 1.0 <br>
 */
public class CustomRealm extends AuthorizingRealm {
    
    

    @Autowired
    private ISysLoginService loginService;

    /** 功能描述: 权限配置
     * @param principalCollection
    * @return: org.apache.shiro.authz.AuthorizationInfo
    * @Author: boo
    * @Date: 2021/3/23 11:25
    */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
    
    
        //获取登录用户名
        String name = (String) principalCollection.getPrimaryPrincipal();
        //查询用户名称
        SysUser user = loginService.getSysUserByUserName(name);
        //添加角色和权限  SimpleAuthorizationInfo: 授权信息
        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
        for (SysRole role : user.getRoles()) {
    
    
            //添加角色
            simpleAuthorizationInfo.addRole(role.getRoleName());
            //添加权限
            for (SysPermissions permissions : role.getPermissions()) {
    
    
                simpleAuthorizationInfo.addStringPermission(permissions.getPermissionsName());
            }
        }
        return simpleAuthorizationInfo;
    }

    /** 功能描述: 认证配置
     * @param authenticationToken  认证令牌
    * @return: org.apache.shiro.authc.AuthenticationInfo
    * @Author: boo
    * @Date: 2021/3/23 11:25
    */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
    
    
        if (StrUtil.isEmptyIfStr(authenticationToken.getPrincipal())) {
    
    
            return null;
        }
        //获取用户信息
        String name = authenticationToken.getPrincipal().toString();
        SysUser user = loginService.getSysUserByUserName(name);
        if (user == null) {
    
    
            //这里返回后会报出对应异常
            return null;
        } else {
    
    
            //这里验证authenticationToken和simpleAuthenticationInfo的信息
            SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(name, user.getPassword().toString(), getName());
            return simpleAuthenticationInfo;
        }
    }
}
  1. ShiroConfig配置类
    把CustomRealm和SecurityManager等注入到spring容器中
package com.boo.spring_boot_demo.framework.config;

import com.boo.spring_boot_demo.framework.shiro.realm.CustomRealm;
import org.apache.shiro.mgt.SessionsSecurityManager;
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.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

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

/**
 * description: ShiroConfig <br>
 * date: 2021/3/23 11:39 <br>
 * author: boo <br>
 * version: 1.0 <br>
 */
@Configuration
public class ShiroConfig {
    
    


    @Bean
    @ConditionalOnMissingBean  // 基于@bean 动态加载bean
    public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
    
    
        DefaultAdvisorAutoProxyCreator defaultAAP = new DefaultAdvisorAutoProxyCreator();
        defaultAAP.setProxyTargetClass(true);
        return defaultAAP;
    }

    //将自己的验证方式加入容器
    @Bean
    public CustomRealm myShiroRealm() {
    
    
        CustomRealm customRealm = new CustomRealm();
        return customRealm;
    }

    //权限管理,配置主要是Realm的管理认证
    @Bean
    public SessionsSecurityManager securityManager() {
    
    
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setRealm(myShiroRealm());
        return securityManager;
    }

    //Filter工厂,设置对应的过滤条件和跳转条件
    @Bean
    public ShiroFilterFactoryBean shiroFilterFactoryBean(SessionsSecurityManager securityManager) {
    
    
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        Map<String, String> map = new HashMap<>();
        //登出
        map.put("/logout", "logout");
        //对所有用户认证
        map.put("/**", "authc");
        //登录
        shiroFilterFactoryBean.setLoginUrl("/login");
        //首页
        shiroFilterFactoryBean.setSuccessUrl("/index");
        //错误页面,认证不通过跳转
        shiroFilterFactoryBean.setUnauthorizedUrl("/error");
        shiroFilterFactoryBean.setFilterChainDefinitionMap(map);
        return shiroFilterFactoryBean;
    }


    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SessionsSecurityManager securityManager) {
    
    
        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
        authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
        return authorizationAttributeSourceAdvisor;
    }

}
  1. 登录接口,及几个不同权限控制的测试接口
@RestController
@Slf4j
public class SysLoginController {
    
    

    @GetMapping("/login")
    public String login(SysUser user) {
    
    
        if (StrUtil.isEmpty(user.getUserName()) || StrUtil.isEmpty(user.getPassword())) {
    
    
            return "请输入用户名和密码!";
        }
        //用户认证信息
        Subject subject = SecurityUtils.getSubject();
        UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(
                user.getUserName(),
                user.getPassword()
        );
        try {
    
    
            //进行验证,这里可以捕获异常,然后返回对应信息
            subject.login(usernamePasswordToken);
//            subject.checkRole("admin");
//            subject.checkPermissions("query", "add");
        } catch (UnknownAccountException e) {
    
    
            log.error("用户名不存在!", e);
            return "用户名不存在!";
        } catch (AuthenticationException e) {
    
    
            log.error("账号或密码错误!", e);
            return "账号或密码错误!";
        } catch (AuthorizationException e) {
    
    
            log.error("没有权限!", e);
            return "没有权限";
        }
        return "login success";
    }

    @RequiresRoles("admin") // 角色拦截
    @GetMapping("/admin")
    public String admin() {
    
    
        return "admin success!";
    }

    @RequiresPermissions("data:query")
    @GetMapping("/index")
    public String index() {
    
    
        return "index success!";
    }

    @RequiresPermissions("data:add") // 权限拦截
    @GetMapping("/add")
    public String add() {
    
    
        return "add success!";
    }

}

注解验证角色和权限的话无法捕捉异常,从而无法正确的返回给前端错误信息,所以这里加了一个类用于拦截异常,具体代码如下

package com.boo.spring_boot_demo.framework.config;

import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authz.AuthorizationException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

/** 统一异常处理
 * description: MyExceptionHandler <br>
 * author: boo <br>
 */
@ControllerAdvice  // 它是一个Controller增强器,可对controller中被 @RequestMapping注解的方法加一些逻辑处理。最常用的就是异常处理
@Slf4j
public class MyExceptionHandler {
    
    
    
    @ExceptionHandler
    @ResponseBody
    public String ErrorHandler(AuthorizationException e) {
    
    
        log.error("没有通过权限验证!", e);
        return "没有通过权限验证!";
    }
}
  1. 启动项目,登录并访问接口,验证权限;登录账户参考上SysLoginServiceImpl.java中信息

整合mybatis

  1. 引入依赖
<!-- mybatis   start -->
<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>1.3.2</version>
</dependency>
<!-- mybatis   end -->

<!-- mysql 数据库连接  start -->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <scope>runtime</scope>
</dependency>
<!-- mysql 数据库连接  end -->
  1. 配置
spring:
  # 数据库配置
  datasource:
      driver-class-name: com.mysql.cj.jdbc.Driver
      url: jdbc:mysql://localhost:3306/springboot?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=UTC
      username: xxxxxxxx
      password: xxxxxxxx

mybatis:
  # 配置mapper的扫描,找到所有的mapper.xml映射文件
  mapper-locations: classpath*:mapper/system/*Mapper.xml
  # 搜索指定包内的实体
  typeAliasesPackage: com.boo.domain

# 配置不同包下的日志打印级别
logging:
  level:
    com:
      boo:
        # 打印sql语句
        mapper: debug
  1. 一个简单的数据库查询例子 (查询用户列表)
    创建一张表,随便添加几条数据
    -- 创建表sql
    CREATE TABLE `sys_user` (
      `id` varchar(32) NOT NULL,
      `user_name` varchar(30) NOT NULL,
      `password` varchar(100) NOT NULL,
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='系统用户表';
    
    INSERT INTO `springboot`.`sys_user` (`id`, `user_name`, `password`) VALUES ('cs001', 'zhangsan', '123456789');
    INSERT INTO `springboot`.`sys_user` (`id`, `user_name`, `password`) VALUES ('cs002', 'lisi', '123456789');
    INSERT INTO `springboot`.`sys_user` (`id`, `user_name`, `password`) VALUES ('cs003', 'wangwu', '123456789');
    INSERT INTO `springboot`.`sys_user` (`id`, `user_name`, `password`) VALUES ('cs004', 'zhaoliu', '123456789');
    

在这里插入图片描述
3.1 SysUser.java与上一致
3.2 SysLoginController.java新增一个查询用户列表的接口

```java
@RestController
@Slf4j
public class SysLoginController {
    @Autowired
    private ISysLoginService loginService;
    
    /* 功能描述: 查询用户列表
     * @param user
    * @return: java.util.List<com.boo.domain.system.SysUser>
    * @Author: boo
    * @Date: 2021/3/23 16:41
    */
    @RequiresPermissions("data:query")
    @GetMapping("/userList")
    public List<SysUser> userList(SysUser user) {
        return loginService.selectUserList(user);
    }

}
```

3.3 `SysLoginServiceImpl.java`新增一个查询用户列表的接口

```java
@Service
public class SysLoginServiceImpl implements ISysLoginService {
    @Autowired
    private SysUserMapper sysUserMapper;

    /** 查询用户列表 */
    @Override
    public List<SysUser> selectUserList(SysUser user) {
        return sysUserMapper.selectUserList(user);
    }
}
```

3.4 `SysUserMapper.java`

```java
package com.boo.mapper.system;

import com.boo.domain.system.SysUser;

import java.util.List;

/** 
 * description: SysUserMapper <br>
 * date: 2021/3/23 16:32 <br>
 * author: boo <br>
 * version: 1.0 <br>
 */
public interface SysUserMapper {
    List<SysUser> selectUserList(SysUser user);
}
```

3.5  `SysUserMapper.xml`

```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.boo.mapper.system.SysUserMapper">

	<resultMap type="com.boo.domain.system.SysUser" id="SysUserResult">
		<id     property="id" column="id" />
		<result property="userName" column="user_name" />
		<result property="password" column="password" />
	</resultMap>

	<select id="selectUserList" parameterType="com.boo.domain.system.SysUser" resultMap="SysUserResult">
		SELECT
			u.id,
			u.user_name,
			u.password
		FROM
			sys_user u
			<where>
				<if test="userName != null and userName != ''">
					AND r.user_name = #{userName}
				</if>
			</where>
	</select>
</mapper>
```
  1. 项目启动
    报错:org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.boo.mapper.system.SysUserMapper' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
    原因:mapper没有注册
    解决方式1: 在mapper接口上添加 @Mapper注解
    在这里插入图片描述
    解决方式2:配置全局的mapper扫描注册
    在启动类上加@MapperScan(*要扫描的包*)注解
    在这里插入图片描述
    解决方式3:写一个专门的注解配置的配置类ApplicationConfig.java
    方式同2,只不过把@MapperScan注解单独放在配置类中,保证SpringBootDemoApplication.java(启动类)的简介, 配置类内容如下:
package com.boo.framework.config;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Configuration;

/** 功能描述: 程序注解配置
 *      主要放一些注解配置
* @Author: boo
* @Date: 2021/3/24 8:53
*/
@Configuration
@MapperScan("com.boo.mapper") // 指定要扫描的Mapper类的包的路径
public class ApplicationConfig
{
    
    

}

整合activiti

参考 > springBoot整合activiti

猜你喜欢

转载自blog.csdn.net/HELLOMRP/article/details/115080871