学习sb
目录
三、application.yml与bootstrap.yml的区别



修改使用版本
- <parent>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-parent</artifactId>
- <version>2.1.7.RELEASE</version>
- <relativePath/><!--lookupparentfromrepository-->
- </parent>
二、启动项目
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.7.3)
2022-09-02 14:30:34.633 INFO 21044 --- [ main] c.l.demo.SpringLoggingDemoApplication : Starting SpringLoggingDemoApplication using Java 1.8.0_192 on LAPTOP-EPEBDNL1 with PID 21044 (D:\IDEAWorkSpace\2022_process\spring-logging-demo\target\classes started by xhm in D:\IDEAWorkSpace\2022_process)
2022-09-02 14:30:34.635 INFO 21044 --- [ main] c.l.demo.SpringLoggingDemoApplication : No active profile set, falling back to 1 default profile: "default"
2022-09-02 14:30:34.985 INFO 21044 --- [ main] c.l.demo.SpringLoggingDemoApplication : Started SpringLoggingDemoApplication in 0.6 seconds (JVM running for 1.482)
Disconnected from the target VM, address: '127.0.0.1:63428', transport: 'socket'
将生成的spring-boot-starter修改为spring-boot-starter-web
org.springframework.boot
spring-boot-starter
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-web</artifactId>
- </dependency>
修改依赖之后依然不生效,重新配置maven,sync项目,重新启动成功

删除原有properties,创建yml文件

bootstrap.yml用来程序引导时执行,应用于更加早期配置信息读取。可以理解成系统级别的一些参数配置,这些参数一般是不会变动的。application.yml可以用来定义应用级别的, 应用程序特有配置信息,可以用来配置后续各个模块中需使用的公共参数等- 若application.yml 和 bootstrap.yml 在同一目录下:bootstrap.yml 先加载,application.yml 后加载
- bootstrap.yml 用于application上下文的引导阶段。bootstrap.yml 由父Spring ApplicationContext加载
- 但是若
application.yml与bootstrap存在相同的配置项,还是会覆盖bootstrap,而application.yml里面的内容可以动态替换。- bootstrap.yml典型的应用场景
- 当使用 Spring Cloud Config Server (或者Spring Cloud Alibaba Nacos)配置中心时,这时必须将 spring.application.name 和 spring.cloud.config.server.git.uri(或者spring.cloud.nacos.config)配置在 bootstrap.yml 配置文件中,添加连接到配置中心的配置属性来加载外部配置中心的配置信息
- 一些固定不变的属性
- 一些加密/解密的场景
————————————————
版权声明:本文为CSDN博主「qq_三哥啊」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_27579471/article/details/123440601
-
-
- <dependency>
- <groupId>mysqlgroupId>
- <artifactId>mysql-connector-javaartifactId>
- <version>8.0.28version>
- dependency>
-
-
- <dependency>
- <groupId>com.baomidougroupId>
- <artifactId>mybatis-plus-boot-starterartifactId>
- <version>3.3.1version>
- dependency>
-
-
- <dependency>
- <groupId>com.baomidougroupId>
- <artifactId>mybatis-plus-generatorartifactId>
- <version>3.3.1version>
- dependency>
-
-
- <dependency>
- <groupId>com.alibabagroupId>
- <artifactId>druid-spring-boot-starterartifactId>
- <version>1.1.10version>
- dependency>
-
-
- <dependency>
- <groupId>org.apache.velocitygroupId>
- <artifactId>velocity-engine-coreartifactId>
- <version>2.3version>
- dependency>
- #application.yml 可以用来定义应用级别的, 应用程序特有配置信息,可以用来配置后续各个模块中需使用的公共参数等。如果搭配 spring-cloud-config 使用, application.yml里面定义的文件可以实现动态替换。
- spring:
- profiles:
- active: dev
- # mybatis- plus配置
- mybatis-plus:
- # xml扫描,多个目录用逗号或者分号隔开隔开
- mapper-locations: classpath:mapper/*.xml
- # 以下配置均有默认值,可以不设置
- global-config:
- db-config:
- #主键类型 AUTO:"数据库ID自增" INPUT:"用户输入ID",ID_WORKER:"全局唯一ID (数字类型唯一ID)", UUID:"全局唯一ID UUID";
- id-type: auto
- configuration:
- # 是否开启自动驼峰命名规则映射:从数据库列名到Java属性驼峰命名的类似映射
- map-underscore-to-camel-case: true
- # 返回map时true:当查询数据为空时字段返回为null,false:不加这个查询数据为空时,字段将被隐藏
- call-setters-on-nulls: true
- # 这个配置会将执行的sql打印出来,在开发或测试的时候可以用
- log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
- spring:
- datasource:
- druid:
- url: jdbc:mysql://127.0.0.1:3306/db_ceshi?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai&autoReconnect=true
- # url: jdbc:mysql://192.168.0.136:3306/csg_cloud_system?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai&autoReconnect=true
- username: root
- password: 123456
- driver-class-name: com.mysql.cj.jdbc.Driver
- 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: true
- slow-sql-millis: 1000
- merge-sql: false
- wall:
- config:
- multi-statement-allow: true
- package com.logging.demo.configuration;
-
- import com.baomidou.mybatisplus.core.toolkit.StringPool;
- import com.baomidou.mybatisplus.generator.AutoGenerator;
- import com.baomidou.mybatisplus.generator.InjectionConfig;
- import com.baomidou.mybatisplus.generator.config.*;
- import com.baomidou.mybatisplus.generator.config.po.TableInfo;
- import com.baomidou.mybatisplus.generator.config.rules.DateType;
- import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
- import org.springframework.beans.factory.annotation.Value;
- import org.springframework.stereotype.Component;
-
- import java.util.ArrayList;
- import java.util.List;
-
- /**
- * @author :Sur chemin
- * @date : 2022/9/2
- */
- @Component
- public class CodeGenerator {
-
- String author;
- String moduleName;
- String parentPackage;
- String tableNames;
- String tablePrefix;
-
- @Value("${spring.datasource.druid.url}")
- String url;
-
- @Value("${spring.datasource.druid.driver-class-name}")
- String driverName;
-
- @Value("${spring.datasource.druid.username}")
- String username;
-
- @Value("${spring.datasource.druid.password}")
- String password;
-
-
- // entiry 的父类
- private final String superEntity = "com.logging.demo.entity.SuperEntity";
-
- public void execute(){
- // 代码生成器
- AutoGenerator mpg = new AutoGenerator();
-
- // 全局配置
- GlobalConfig gc = new GlobalConfig();
- String projectPath = System.getProperty("user.dir");
- gc.setOutputDir(projectPath + "/src/main/java");
- gc.setAuthor(author);
- gc.setOpen(false);
- gc.setSwagger2(true);
- gc.setDateType(DateType.ONLY_DATE);
- mpg.setGlobalConfig(gc);
-
- // 数据源配置
- DataSourceConfig dc = new DataSourceConfig();
- dc.setUrl(url);
- dc.setDriverName(driverName);
- dc.setPassword(password);
- dc.setUsername(username);
- mpg.setDataSource(dc);
-
- // 包配置
- PackageConfig pc = new PackageConfig();
- pc.setModuleName(moduleName);
- pc.setParent(parentPackage);
- mpg.setPackageInfo(pc);
-
- // 自定义配置
- // 添加自定义配置 使得数据表映射已存在的情况下 更新entity
- InjectionConfig cfg = new InjectionConfig() {
- @Override
- public void initMap() {
- // to do nothing
- }
- };
-
- // 如果模板引擎是freemarker
- // String templatePath = "templates/mapper.xml.ftl";
- // 如果模板引擎是velocity
- String templatePath = "/templates/mapper.xml.vm";
-
- // 自定义输出配置
- List
focList = new ArrayList<>(); - // 自定义配置会被优先输出
- focList.add(new FileOutConfig(templatePath) {
- @Override
- public String outputFile(TableInfo tableInfo) {
- // 自定义输出文件名,如果Entity设置了前后缀、此处主要xml的名称会跟着发生变化
- String s = projectPath + "/src/main/resources/mapper/" + pc.getModuleName()
- + "/" + tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML;
- return s;
- }
- });
- /*ic.setFileCreate(new IFileCreate() {
- @Override
- public boolean isCreate(ConfigBuilder configBuilder, FileType fileType, String filePath) {
- // 判断自定义文件夹是否需要创建
- checkDir("调用默认方法创建的目录,自定义目录用");
- if (fileType == FileType.MAPPER) {
- // 已经生成 mapper文件判断存在,不想重新生成返回 false
- return !new File(filePath).exists();
- }
- // 允许生成模板文件
- return true;
- }
- });*/
-
- /*cfg.setFileCreate((configBuilder, fileType, filePath) -> {
- //如果是Entity则直接返回true表示写文件
- if (fileType == FileType.ENTITY) {
- return true;
- }
- //否则先判断文件是否存在
- File file = new File(filePath);
- boolean exist = file.exists();
- if (!exist) {
- file.getParentFile().mkdirs();
- }
- //文件不存在或者全局配置的fileOverride为true才写文件
- return !exist || configBuilder.getGlobalConfig().isFileOverride();
- });*/
-
- cfg.setFileOutConfigList(focList);
- mpg.setCfg(cfg);
-
- // 配置模板
- TemplateConfig templateConfig = new TemplateConfig();
-
- // 配置自定义输出模板
- // 指定自定义模板路径,主要不用带上.ftl/.vm,会根据使用的模板引擎自动识别
- // templateConfig.setEntity("templates/entity2.java");
- // templateConfig.setService();
- // templateConfig.setController();
-
- templateConfig.setXml(null);
- mpg.setTemplate(templateConfig);
-
- // 策略配置
- StrategyConfig strategy = new StrategyConfig();
- strategy.setNaming(NamingStrategy.underline_to_camel);
- strategy.setColumnNaming(NamingStrategy.underline_to_camel);
- strategy.setSuperEntityClass(superEntity);
- strategy.setEntityLombokModel(true);
- strategy.setRestControllerStyle(true);
-
- // 公共父类
- // strategy.setSuperControllerClass(superController);
- // 写于父类中的公共字段
- strategy.setSuperEntityColumns("id", "ID");
- strategy.setInclude(tableNames.split(","));
- strategy.setControllerMappingHyphenStyle(true);
- strategy.setTablePrefix(tablePrefix);
- mpg.setStrategy(strategy);
- // Velocity是默认模板引擎,不需要配置
- // mpg.setTemplateEngine(new FreemarkerTemplateEngine());
-
- mpg.execute();
- }
-
- public CodeGenerator setAuthor(String author) {
- this.author = author;
- return this;
- }
-
- public CodeGenerator setModuleName(String moduleName) {
- this.moduleName = moduleName;
- return this;
- }
-
- public CodeGenerator setParentPackage(String parentPackage) {
- this.parentPackage = parentPackage;
- return this;
- }
-
- public CodeGenerator setTableNames(String tableNames) {
- this.tableNames = tableNames;
- return this;
- }
-
- public CodeGenerator setTablePrefix(String tablePrefix) {
- this.tablePrefix = tablePrefix;
- return this;
- }
- }
测试类
- package com.logging.demo;
-
- import com.logging.demo.configuration.CodeGenerator;
- import org.junit.Test;
- import org.junit.runner.RunWith;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.boot.test.context.SpringBootTest;
- import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
-
- import java.util.Arrays;
- import java.util.List;
-
- /**
- * @author :Sur chemin
- * @date : 2022/9/2
- */
- @RunWith(SpringJUnit4ClassRunner.class)
- @SpringBootTest(classes = SpringLoggingDemoApplication.class)
- public class GenertorTest {
-
- @Autowired
- private CodeGenerator codeGenerator;
-
- @Test
- public void test() {
- List
asList = Arrays.asList(new String[]{"pro_change_order"}); - asList.forEach(e -> {
- codeGenerator.setAuthor("Sur chemin");
- codeGenerator.setModuleName("");
- codeGenerator.setParentPackage("com.logging.demo.project");
- codeGenerator.setTableNames(e);
- codeGenerator.setTablePrefix("pro_");
- codeGenerator.execute();
- });
- }
- }
- package com.logging.demo.configuration;
-
- import com.baomidou.mybatisplus.core.parser.ISqlParser;
- import com.baomidou.mybatisplus.extension.parsers.BlockAttackSqlParser;
- import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
- import com.baomidou.mybatisplus.extension.plugins.pagination.optimize.JsqlParserCountOptimize;
- import com.google.common.collect.Lists;
- import org.mybatis.spring.annotation.MapperScan;
- import org.springframework.context.annotation.Bean;
- import org.springframework.context.annotation.Configuration;
- import org.springframework.context.annotation.Primary;
- import org.springframework.core.annotation.Order;
-
- import java.util.List;
-
- /**
- * @author :Sur chemin
- * @date : 2022/9/2
- */
- @Configuration
- //@MapperScan(basePackageClasses = Mc.class)
- @MapperScan("com.logging.demo")
- public class MybatisPlusConfig {
-
- /**
- * 分页插件
- * @return
- */
- @Bean
- @Order(2)
- public PaginationInterceptor paginationInterceptor(){
- PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
- List
sqlParserList = Lists.newArrayList(); -
- // 攻击 SQL阻断解析器、加入解析链
- sqlParserList.add(new BlockAttackSqlParser());
- paginationInterceptor.setSqlParserList(sqlParserList);
-
- // 单页限制500条,小于0 如-1不受限制
- paginationInterceptor.setLimit(-1);
- paginationInterceptor.setCountSqlParser(new JsqlParserCountOptimize(true));
- // 设置方言
- paginationInterceptor.setDialectType("sqlite");
- return paginationInterceptor;
- }
-
- @Bean
- @Primary
- public CommonMetaObjectHandler commonMetaObjectHandler(){
- return new CommonMetaObjectHandler();
- }
- }
- package com.logging.demo.configuration;
-
- import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
- import org.apache.ibatis.reflection.MetaObject;
-
- import java.util.Date;
-
- /**
- * 通用填充类 适用于mybatis plus
- * @author :Sur chemin
- * @date : 2022/9/2
- */
- public class CommonMetaObjectHandler implements MetaObjectHandler {
-
- /**
- * 创建人
- */
- private final String createBy = "createBy";
-
- /**
- * 更新人
- */
- private final String updateBy = "updateBy";
-
- /**
- * 创建时间
- */
- private final String createDate = "createDate";
-
- /**
- * 更新时间
- */
- private final String updateDate = "updateDate";
-
- private final String delteFlag = "delteFlag";
-
- /**
- * 3.0.x新版自动填充api 判断实体类字段是否为null
- * 为null,才执行自动填充
- * 所以改回旧版过时api
- * @param metaObject
- */
- @Override
- public void insertFill(MetaObject metaObject) {
- setInsertFieldValByName(delteFlag, 0, metaObject);
- setInsertFieldValByName(createDate,new Date(System.currentTimeMillis()), metaObject);
- // 其他需要自动填充的字段在这里补充
- }
-
- @Override
- public void updateFill(MetaObject metaObject) {
- setInsertFieldValByName(delteFlag, 0, metaObject);
- setInsertFieldValByName(createDate,new Date(System.currentTimeMillis()), metaObject);
- }
- }
-
- <dependency>
- <groupId>io.springfoxgroupId>
- <artifactId>springfox-swagger2artifactId>
- <version>2.9.2version>
- dependency>
- <dependency>
- <groupId>io.springfoxgroupId>
- <artifactId>springfox-swagger-uiartifactId>
- <version>2.9.2version>
- dependency>
- package com.logging.demo.configuration;
-
- 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.service.ApiKey;
- import springfox.documentation.service.AuthorizationScope;
- import springfox.documentation.service.SecurityReference;
- import springfox.documentation.spi.DocumentationType;
- import springfox.documentation.spi.service.contexts.SecurityContext;
- import springfox.documentation.spring.web.plugins.Docket;
- import springfox.documentation.swagger2.annotations.EnableSwagger2;
-
- import java.util.ArrayList;
- import java.util.List;
-
- @Configuration
- @EnableSwagger2
- public class Swagger2Config {
- private Boolean enabled = true;
- @Bean
- public Docket createRestApi(){
- return new Docket(DocumentationType.SWAGGER_2)
- .enable(enabled)
- .apiInfo(apiInfo())
- .select()
- .apis(RequestHandlerSelectors.basePackage("com.logging.demo.controller"))
- .paths(PathSelectors.any())
- .build();
- // .securitySchemes(securitySchemes())
- // .securityContexts(securityContexts());
- }
-
- private ApiInfo apiInfo() {
- return new ApiInfoBuilder()
- .title("管理模块")
- .description("管理模块")
- .contact("")
- .version("1.0")
- .build();
- }
-
- private List
securitySchemes() { - //设置请求头信息
- List
result = new ArrayList<>(); - ApiKey apiKey = new ApiKey("Authorization", "Authorization", "header");
- result.add(apiKey);
- return result;
- }
-
- private List
securityContexts() { - //设置需要登录认证的路径
- List
result = new ArrayList<>(); - //result.add(getContextByPath("/brand/.*"));
- return result;
- }
-
- private SecurityContext getContextByPath(String pathRegex){
- return SecurityContext.builder()
- .securityReferences(defaultAuth())
- .forPaths(PathSelectors.regex(pathRegex))
- .build();
- }
-
- private List
defaultAuth() { - List
result = new ArrayList<>(); - AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything");
- AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
- authorizationScopes[0] = authorizationScope;
- result.add(new SecurityReference("Authorization", authorizationScopes));
- return result;
- }
- }
controller测试类
- package com.logging.demo.controller;
-
-
- import io.swagger.annotations.Api;
- import org.springframework.web.bind.annotation.RequestMapping;
- import org.springframework.web.bind.annotation.RestController;
-
- /**
- *
- * 项目变更工单表 前端控制器
- *
- *
- * @author Sur chemin
- * @since 2022-09-02
- */
- @RestController
- @Api(tags = "test")
- @RequestMapping("/test")
- public class TestController {
-
- }
-
测试,不显示controller,原因没有在测试类中写接口方法,GET/POST

修改
- package com.logging.demo.controller;
-
-
- import io.swagger.annotations.Api;
- import io.swagger.annotations.ApiOperation;
- import org.springframework.web.bind.annotation.GetMapping;
- import org.springframework.web.bind.annotation.RequestMapping;
- import org.springframework.web.bind.annotation.RestController;
-
- /**
- *
- * 项目变更工单表 前端控制器
- *
- *
- * @author Sur chemin
- * @since 2022-09-02
- */
- @RestController
- @Api(tags = "test")
- @RequestMapping("/test")
- public class TestController {
-
- @ApiOperation(value = "查询")
- @GetMapping("/test")
- public String test(){
- return "1";
- }
- }
-

学习参考文章连接:https://blog.csdn.net/LC_Liangchao/article/details/123425625
Spring Security提供有若干个过滤器,它们能够拦截Servlet请求,并将这些请求转给认证和访问决策管理器处理,从而增强安全性。根据自己的需要,可以使用适当的过滤器来保护自己的应用程序
1.认证
2.授权
- <dependency>
- <groupId>org.springframework.bootgroupId>
- <artifactId>spring-boot-starter-securityartifactId>
- dependency>
AuthenticationManager进行权限认证(最终走自定义的UserDetailsService的实现类的loadUserByUsername接口根据用户名查询数据库验证用户是否存在)
- package com.logging.demo.service.impl;
-
- import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
- import com.logging.demo.auth.AdminUserDetails;
- import com.logging.demo.entity.SysUser;
- import com.logging.demo.mapper.SysUserMapper;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.security.core.userdetails.UserDetails;
- import org.springframework.security.core.userdetails.UserDetailsService;
- import org.springframework.security.core.userdetails.UsernameNotFoundException;
- import org.springframework.stereotype.Service;
-
-
- /**
- * @author :Sur chemin
- * @date : 2022/9/6
- */
-
- /**
- * 加载用户特定数据的核心接口。里面定义了一个根据用户名查询用户信息的方法
- */
- /**
- * 实际开发中会把5.1这一步查询数据来判断用户名密码是否正确,所以我们需要改变的地方是:写一个UserDetailsService的实现类,
- * 让DaoAuthenticationProvider去调用这个实现类。
- * 自定义userDetailsService的实现类;查询数据库
- */
- @Service("userDetailsService")
- public class UserDetailsServiceImpl implements UserDetailsService{
- @Autowired
- private SysUserMapper sysUserMapper;
-
-
- /**
- * 登录请求 :1.查询根据用户名数据库用户是否存在
- *
- * @param username
- * @return
- * @throws UsernameNotFoundException
- */
- @Override
- public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
- // 校验用户名和密码
- LambdaQueryWrapper
queryWrapper = new LambdaQueryWrapper<>(); - queryWrapper.eq(SysUser::getUserName, username);
- SysUser sysUser = sysUserMapper.selectOne(queryWrapper);
- if(sysUser==null){
- throw new RuntimeException("用户名或密码不正确");
- }
- // TODO 2. 存储用户信息进入SecurityContextHolder(包括权限信息)
- return new AdminUserDetails(sysUser);
- }
- }
- package com.logging.demo.controller;
-
-
- import com.logging.demo.common.CommonResult;
- import com.logging.demo.entity.vo.SysUserReqVO;
- import com.logging.demo.service.ISysUserService;
- import io.swagger.annotations.ApiOperation;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.web.bind.annotation.*;
-
- import java.util.Map;
-
- /**
- *
- * 前端控制器
- *
- *
- * @author Sur chemin
- * @since 2022-09-06
- */
- @RestController
- @RequestMapping("/sys-user")
- public class SysUserController {
-
- @Autowired
- ISysUserService sysUserService;
-
- @ApiOperation("用户注册")
- @PostMapping("addUser")
- public CommonResult addUser(@RequestBody SysUserReqVO sysUserReqVO){
- return sysUserService.addUser(sysUserReqVO);
- }
-
- @ApiOperation("用户登录")
- @PostMapping("login")
- public Map
login(@RequestParam String username, - @RequestParam String password){
- return sysUserService.login(username, password);
- }
-
- /**
- * 根据手机号注册,手机号唯一
- * @param mobile
- * @param password
- * @return
- */
- @ApiOperation("修改/重置密码")
- @PostMapping("reset")
- public CommonResult reset(@RequestParam String mobile,
- @RequestParam(required = false) String password){
- return sysUserService.reset(mobile, password);
- }
- }
-
我们一般使用springsecurity为我们提供的BCryptPasswordEncoder(内部会生成一个随机的盐,保证每次加密的结果都不一样)
- package com.logging.demo.auth;
-
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
- import org.springframework.context.annotation.Bean;
- import org.springframework.context.annotation.Configuration;
- import org.springframework.http.HttpMethod;
- import org.springframework.security.authentication.AuthenticationManager;
- import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
- import org.springframework.security.config.annotation.web.builders.HttpSecurity;
- import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
- import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer;
- import org.springframework.security.config.http.SessionCreationPolicy;
- import org.springframework.security.core.userdetails.UserDetailsService;
- import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
- import org.springframework.security.crypto.password.PasswordEncoder;
- import org.springframework.security.web.access.intercept.FilterSecurityInterceptor;
- import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
-
- /**
- * @author :Sur chemin
- * @date : 2022/9/6
- */
-
- @Configuration
- public class SecurityConfig extends WebSecurityConfigurerAdapter {
- @Autowired(required = false)
- private DynamicSecurityService dynamicSecurityService;
-
- /**
- * 在SecurityConfig里面配置认证的配置
- *
- * @param httpSecurity
- * @throws Exception
- */
- @Autowired
- UserDetailsService userDetailsService;
-
- @Override
- protected void configure(HttpSecurity httpSecurity) throws Exception {
- /*// 所有请求必须认证通过
- httpSecurity
- .csrf().disable()
- .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
- .and()
- .authorizeRequests()
- //下边的路径放行
- .antMatchers("/sys-user/login","/v2/api-docs", "/swagger-resources/configuration/ui",
- "/swagger-resources","/swagger-resources/configuration/security",
- "/swagger-ui.html","/webjars/**","/sys-user/addUser").permitAll()
- .anyRequest().authenticated();*/
- // 不拦截任何请求
- /* httpSecurity
- .authorizeRequests().anyRequest().permitAll();*/
-
- /**
- * 配置 参考文章
- * https://blog.csdn.net/m0_56368068/article/details/125614281
- */
- ExpressionUrlAuthorizationConfigurer
.ExpressionInterceptUrlRegistry registry = httpSecurity.authorizeRequests(); - //不需要保护的资源路径允许访问
- for (String url : ignoreUrlsConfig().getUrls()) {
- registry.antMatchers(url).permitAll();
- }
- //允许跨域请求的OPTIONS请求
- registry.antMatchers(HttpMethod.OPTIONS).permitAll();
- // 任何请求需要身份认证
- registry.and().authorizeRequests()//对url访问控制授权
- .antMatchers("/actuator", "/actuator/*").authenticated()//需要进行认证
- .antMatchers("/*").permitAll()// 在实际项目中经常需要放行所有静态资源,需要放行的url。
- .anyRequest().authenticated()//anyRequest匹配所有请求,全部内容都需要认证
- // 关闭跨站请求防护及不使用session
- .and()
- .csrf()
- .disable()
- .sessionManagement()
- .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
- /**
- * 自定义权限拒绝处理类
- * spring Security 认证授权相关的异常进行统一的自定义处理
- */
- .and().exceptionHandling()
- .accessDeniedHandler(restfulAccessDeniedHandler()).authenticationEntryPoint(restAuthenticationEntryPoint())
- // 自定义权限拦截器JWT过滤器
- .and()
- //.addFilterBefore(verifyCodeFilter(), UsernamePasswordAuthenticationFilter.class)
- .addFilterBefore(jwtAuthenticationTokenFilter(), UsernamePasswordAuthenticationFilter.class);
- //有动态权限配置时添加动态权限校验过滤器
- if (dynamicSecurityService != null) {
- registry.and().addFilterBefore(dynamicSecurityFilter(), FilterSecurityInterceptor.class);
- }
- }
-
-
- /**
- * 解决错误:ERROR:Encoded password does not look like BCrypt
- * 原因:密码格式不匹配导致的
- * @param auth
- * @throws Exception
- *
- *
- */
- @Override
- protected void configure(AuthenticationManagerBuilder auth) throws Exception {
- /**
- * ERROR:WebSecurityConfigurerAdapter$UserDetailsServiceDelegator.loadUserByUsername(WebSecurityConfigurerAdapter.java:451)
- * java.lang.StackOverflowError: null
- * 没有执行UserDetailsService的实现类的loadUserByUsername方法,执行上面的loadUserByUsername方法递归调用导致栈溢出
- */
- // auth.userDetailsService(userDetailsService()).passwordEncoder(passwordEncoder());
- auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
-
-
- }
-
-
- /**
- * 登录接口
- * 开放这个接口的白名单,让用户访问这个接口的时候不用登录也能访问。
- * 在接口中我们通过AuthenticationManager的authenticate方法来进行用户认证,所以需要SecurityConfig中配置把AuthenticationManager注入容器。
- * 认证成功的话要生成一个jwt,放入响应中返回,并且为了让用户回请求时能通过jwt识别出具体的是哪个用户,我们需要把用户信息存储入redis,用户id作为key
- *
- * @return
- * @throws Exception 把AuthenticationManager注入容器中
- */
- @Bean
- @Override
- public AuthenticationManager authenticationManagerBean() throws Exception {
- return super.authenticationManagerBean();
- }
-
-
- // 替换掉默认的密码加密器
-
- /**
- * 我们一般使用springsecurity为我们提供的BCryptPasswordEncoder(内部会生成一个随机的盐,保证每次加密的结果都不一样)。
- * 我们只需要使用吧BCryptPasswordEncoder对象注入spring容器中,springsecurity就会使用该passwordEncoder来进行密码校验。
- *
- * 我们可以定义一个springsecurity的配置类,springsecurity要求这个配置类要继承WebSecurityConfigurerAdapter。然后在注册的时候,注入这个对象,给密码加密存储进数据库
- *
- * @return
- */
- @Bean
- public PasswordEncoder passwordEncoder() {
- return new BCryptPasswordEncoder();
- }
-
- @Bean
- public JwtTokenUtil jwtTokenUtil() {
- return new JwtTokenUtil();
- }
-
- /**
- * 配置不拦截的请求路径,放行
- * @return
- */
- @Bean
- public IgnoreUrlsConfig ignoreUrlsConfig() {
- return new IgnoreUrlsConfig();
- }
-
- /**
- * 自定义一个过滤器,这个过滤器会去获取请求头中的token,对token进行解析去除其中的userid
- * 使用userid去redis中获取对于的 AdminUserDetails 对象
- * 然后封装Authentication对象存入SecurityContextHolder
- * @return
- */
- @Bean
- public JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter() {
- return new JwtAuthenticationTokenFilter();
- }
-
- @Bean
- public RestfulAccessDeniedHandler restfulAccessDeniedHandler() {
- return new RestfulAccessDeniedHandler();
- }
-
- @Bean
- public RestAuthenticationEntryPoint restAuthenticationEntryPoint() {
- return new RestAuthenticationEntryPoint();
- }
-
- @ConditionalOnBean(name = "dynamicSecurityService")
- @Bean
- public DynamicAccessDecisionManager dynamicAccessDecisionManager() {
- return new DynamicAccessDecisionManager();
- }
-
- @ConditionalOnBean(name = "dynamicSecurityService")
- @Bean
- public DynamicSecurityFilter dynamicSecurityFilter() {
- return new DynamicSecurityFilter();
- }
-
- }
ERROR:Failed to start bean 'documentationPluginsBootstrapper'; nested exception is java.lang.NullPointerException
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2022-09-08 18:08:09.651 ERROR 20204 --- [ main] o.s.boot.SpringApplication : Application run failedorg.springframework.context.ApplicationContextException: Failed to start bean 'documentationPluginsBootstrapper'; nested exception is java.lang.NullPointerException
at org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:181)
at org.springframework.context.support.DefaultLifecycleProcessor.access$200(DefaultLifecycleProcessor.java:54)
at org.springframework.context.support.DefaultLifecycleProcessor$LifecycleGroup.start(DefaultLifecycleProcessor.java:356)
at java.lang.Iterable.forEach(Iterable.java:75)
at org.springframework.context.support.DefaultLifecycleProcessor.startBeans(DefaultLifecycleProcessor.java:155)
at org.springframework.context.support.DefaultLifecycleProcessor.onRefresh(DefaultLifecycleProcessor.java:123)
at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:935)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:586)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:145)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:745)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:420)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:307)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1317)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1306)
at com.logging.demo.SpringLoggingDemoApplication.main(SpringLoggingDemoApplication.java:13)
Caused by: java.lang.NullPointerException: null
at springfox.documentation.spi.service.contexts.Orderings$8.compare(Orderings.java:112)
at springfox.documentation.spi.service.contexts.Orderings$8.compare(Orderings.java:109)
at com.google.common.collect.ComparatorOrdering.compare(ComparatorOrdering.java:37)
at java.util.TimSort.countRunAndMakeAscending(TimSort.java:355)
at java.util.TimSort.sort(TimSort.java:220)
at java.util.Arrays.sort(Arrays.java:1438)
at com.google.common.collect.Ordering.sortedCopy(Ordering.java:855)
at springfox.documentation.spring.web.plugins.WebMvcRequestHandlerProvider.requestHandlers(WebMvcRequestHandlerProvider.java:57)
at springfox.documentation.spring.web.plugins.DocumentationPluginsBootstrapper$2.apply(DocumentationPluginsBootstrapper.java:138)
at springfox.documentation.spring.web.plugins.DocumentationPluginsBootstrapper$2.apply(DocumentationPluginsBootstrapper.java:135)
at com.google.common.collect.Iterators$7.transform(Iterators.java:750)
at com.google.common.collect.TransformedIterator.next(TransformedIterator.java:47)
at com.google.common.collect.TransformedIterator.next(TransformedIterator.java:47)
at com.google.common.collect.MultitransformedIterator.hasNext(MultitransformedIterator.java:52)
at com.google.common.collect.MultitransformedIterator.hasNext(MultitransformedIterator.java:50)
at com.google.common.collect.ImmutableList.copyOf(ImmutableList.java:249)
at com.google.common.collect.ImmutableList.copyOf(ImmutableList.java:209)
at com.google.common.collect.FluentIterable.toList(FluentIterable.java:614)
at springfox.documentation.spring.web.plugins.DocumentationPluginsBootstrapper.defaultContextBuilder(DocumentationPluginsBootstrapper.java:111)
at springfox.documentation.spring.web.plugins.DocumentationPluginsBootstrapper.buildContext(DocumentationPluginsBootstrapper.java:96)
at springfox.documentation.spring.web.plugins.DocumentationPluginsBootstrapper.start(DocumentationPluginsBootstrapper.java:167)
at org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:178)
... 14 common frames omittedDisconnected from the target VM, address: '127.0.0.1:52192', transport: 'socket'
原因:使用springboot2.6.0后,配置swagger,不论是2.9.2还是3.0.0都报错
解决方法:配置文件中加入 .yml 配置
- spring:
- mvc:
- pathmatch:
- matching-strategy: ant_path_matcher
提示:这里对文章进行总结:
例如:以上就是今天要讲的内容,本文仅仅简单介绍了pandas的使用,而pandas提供了大量能使我们快速便捷地处理数据的函数和方法。