boot2.x
复制代码 隐藏代码 <dependency>
<groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>2.7.17</version>
<type>pom</type> <scope>import</scope> </dependency>
boot3.5.8x
复制代码 隐藏代码 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>3.5.8</version> <type>pom</type> <scope>import</scope> </dependency>
这里并没有采用 spring-boot-parent的方式
注释掉原来的SecurityConfig类,新增SecurityConfiguration类
SecurityConfiguration类
复制代码 隐藏代码 mport com.zgl.framework.config.properties.PermitAllUrlProperties; import com.zgl.framework.security.filter.JwtAuthenticationTokenFilter; import com.zgl.framework.security.handle.AuthenticationEntryPointImpl; import com.zgl.framework.security.handle.LogoutSuccessHandlerImpl; import org.springframework.beans.factory.annotation.Autowired; 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.configuration.AuthenticationConfiguration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; import org.springframework.security.config.annotation.web.configurers.HeadersConfigurer; 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.web.SecurityFilterChain; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; import org.springframework.security.web.authentication.logout.LogoutFilter; import org.springframework.web.filter.CorsFilter; /**
* 配置类
* @author jjy
*/ @Configuration public class SecurityConfiguration {
/**
* 自定义用户认证逻辑
*/ @Autowired private UserDetailsService userDetailsService;
/**
* 认证失败处理类
*/ @Autowired private AuthenticationEntryPointImpl unauthorizedHandler;
/**
* 退出处理类
*/ @Autowired private LogoutSuccessHandlerImpl logoutSuccessHandler;
/**
* token认证过滤器
*/ @Autowired private JwtAuthenticationTokenFilter authenticationTokenFilter;
/**
* 跨域过滤器
*/ @Autowired private CorsFilter corsFilter;
/**
* 允许匿名访问的地址
*/ @Autowired private PermitAllUrlProperties permitAllUrl;
@Bean public SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Exception {
httpSecurity.authorizeHttpRequests((authz) -> permitAllUrl.getUrls().forEach(url -> authz.requestMatchers(url).permitAll())
);
httpSecurity
.csrf(AbstractHttpConfigurer::disable)
// CSRF禁用,因为不使用session .csrf(AbstractHttpConfigurer::disable)
// 禁用HTTP响应标头 .headers((hd)->hd.cacheControl(HeadersConfigurer.CacheControlConfig::disable))
// 认证失败处理类 .exceptionHandling(at->at.authenticationEntryPoint(unauthorizedHandler))
// 基于token,所以不需要session .sessionManagement(se->se.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
// 过滤请求 .authorizeHttpRequests(auth->
auth.requestMatchers("/login","/register","/captchaImage","/online/ksOAuthCallback/oauthCallback").permitAll()
)
// 静态资源,可匿名访问 .authorizeHttpRequests(auth->
auth.requestMatchers(HttpMethod.GET,"/", "/*.html", "/**/*.html", "/**/*.css", "/**/*.js", "/profile/**").permitAll()
.requestMatchers("/swagger-ui.html", "/swagger-resources/**", "/webjars/**", "/v3/**","/*/api-docs", "/druid/**").permitAll()
// 除上面外的所有请求全部需要鉴权认证 .anyRequest().authenticated()
)
// 除上面外的所有请求全部需要鉴权认证 .headers(hd->hd.frameOptions(HeadersConfigurer.FrameOptionsConfig::disable));
// 添加Logout filter httpSecurity.logout(lot->lot.logoutUrl("/logout").logoutSuccessHandler(logoutSuccessHandler));
// 添加JWT filter httpSecurity.addFilterBefore(authenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);
// 添加CORS filter httpSecurity.addFilterBefore(corsFilter, JwtAuthenticationTokenFilter.class);
httpSecurity.addFilterBefore(corsFilter, LogoutFilter.class);
// 认证用户时用户信息加载配置,注入springAuthUserService httpSecurity.userDetailsService(userDetailsService);
return httpSecurity.build();
}
/**
* 强散列哈希加密实现
*/ @Bean public BCryptPasswordEncoder bCryptPasswordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean public AuthenticationManager authenticationManager(AuthenticationConfiguration authConfig) throws Exception {
return authConfig.getAuthenticationManager();
}
关于SecurityConfig中WebSecurityConfigurerAdapter的升级,可参考官方给的案例WebSecurityConfigurerAdapter废除升级案例
boot2.x
复制代码 隐藏代码 <dependency>
<groupId>com.baomidou</groupId>
<artifactId>druid-spring-boot-starter</artifactId> </dependency>
boot3.5.x
复制代码 隐藏代码 <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-3-starter</artifactId> <version>1.2.27</version> </dependency>
boot2.x
复制代码 隐藏代码 <dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId> </dependency>
boot3.5.x
复制代码 隐藏代码 <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.5.5</version> <!-- 需要排除mybatis-spring 再重新映入更高版本 --> <exclusions> <exclusion> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> </exclusion> </exclusions> </dependency> <!--重新引入 mybatis-spring--> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>3.0.3</version> </dependency>
boot2.x
复制代码 隐藏代码 <dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId> </dependency>
boot3.5.x
复制代码 隐藏代码 <dependency> <groupId>jakarta.servlet</groupId> <artifactId>jakarta.servlet-api</artifactId> </dependency>
boot2.x
复制代码 隐藏代码 <dependency> <groupId>javax.xml.bind</groupId> <artifactId>jaxb-api</artifactId> </dependency>
boot3.5.x
复制代码 隐藏代码 <dependency> <groupId>jakarta.xml.bind</groupId> <artifactId>jakarta.xml.bind-api</artifactId> </dependency>
swagger依赖升级版本后确保只有升级后所引入的jar。也可以参考knife4j给出的案例knife4j-spring-boot3-demo
boot2.x
复制代码 隐藏代码 <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-boot-starte</artifactId> </dependency>
boot3.5x
复制代码 隐藏代码 <!--引入新的knife4j--> <dependency> <groupId>com.github.xiaoymin</groupId> <artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId> <version>4.5.0</version> </dependency>
复制代码 隐藏代码 import io.swagger.v3.oas.models.Components; import io.swagger.v3.oas.models.OpenAPI; import io.swagger.v3.oas.models.info.Contact; import io.swagger.v3.oas.models.info.Info; import io.swagger.v3.oas.models.security.SecurityRequirement; import io.swagger.v3.oas.models.security.SecurityScheme; import org.springdoc.core.customizers.GlobalOpenApiCustomizer; import org.springdoc.core.models.GroupedOpenApi; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import java.util.ArrayList; import java.util.List; /**
* Swagger2的接口配置
*
* @author jjy
*/ @Configuration public class SwaggerConfig {
/**
* 系统基础配置
*/ @Autowired private ZglConfig zglConfig;
/**
* 创建API
*/ @Bean public GroupedOpenApi createRestApi() {
return GroupedOpenApi.builder()
.group("OA业务")
// 扫描指定包中的swagger注解 .packagesToScan("com.zgl.web.controller.business")
.build();
}
/**
* 安全模式,这里指定token通过Authorization头请求头传递
*/ private List<SecurityRequirement> securitySchemes() {
List<SecurityRequirement> apiKeyList = new ArrayList<>();
apiKeyList.add(new SecurityRequirement().addList("bearer-key"));
return apiKeyList;
}
/**
* 添加摘要信息
*/ @Bean public OpenAPI springShopOpenAPI() {
return new OpenAPI()
.info(new Info()
// 设置标题 .title("标题:财务管理系统_接口文档")
// 描述 .description("描述:用于管理集团旗下公司的人员信息,具体包括XXX,XXX模块...")
// 作者信息 .contact(new Contact().name(“xxj”))
// 版本 .version("版本号:" + "1.01"))
// SecurityScheme 定义 .components(new Components()
.addSecuritySchemes("Authorization",
new SecurityScheme()
.type(SecurityScheme.Type.HTTP)
.bearerFormat("JWT")
.in(SecurityScheme.In.HEADER)
.name("Authorization"))
)
// 2. 再在这里添加上Swagger要使用的安全策略 // addList()中写上对应的key .addSecurityItem(new SecurityRequirement().addList("Authorization"));
} /**
* 添加全局请求头设置
*/ @Bean public GlobalOpenApiCustomizer orderGlobalOpenApiCustomizer() {
return openApi -> {
// 全局添加鉴权参数 if(openApi.getPaths()!=null){
openApi.getPaths().forEach((s, pathItem) -> {
// 为所有接口添加鉴权 pathItem.readOperations().forEach(operation -> {
operation.addSecurityItem(new SecurityRequirement().addList("Authorization"));
});
});
}
};
}
| springboot2 | springboot3 |
|---|---|
| @Api(tags = "示例模块") | @Tag(name = "示例模块", description = "示例模块 API") |
| @ApiOperation(value = "示例接口", notes = "返回一个简单的问候语") | @Operation(summary = "示例接口", description = "返回一个简单的问候语") |
| @ApiParam(name = "name", value = "用户名称", required = true) | @Parameter(name = "name", description = "用户名称", required = true) |
| @ApiModelProperty(value = "id多个逗号拼接") | @Schema(type = "id") |
| @ApiModel("账户管理") | @Schema(description ="账户管理") |
Name for argument of type [java.lang.String] not specified, and parameter name information not available via reflection. Ensure that the compiler uses the ‘-parameters’ flag.
复制代码 隐藏代码 <build> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.12.0</version> <configuration> <!--添加parameters标签--> <parameters>true</parameters> </configuration> </plugin> </build>
@RequestParam("name")
复制代码 隐藏代码 @GetMapping("/hello")
public RespPack<?> hello(@RequestParam("name") String name) {
return null;
}
这是Spring新版本导致的。为什么会出现这个问题呢?原来是Spring 6.1之后,官方加强了很多错误校验和报错提示,本文这个错也是其中之一。
如果不使用spring-boot-starter-parent作为父工程,那么接口中必须显式声明@RequestParam("name"),缺了其中的name也会报错。多数人在旧版本的 Springboot 中经常省略 @RequestParam(“name”) 这种写法。
但如果不使用spring-boot-starter-parent作为父工程,好像@RequestParam变成了不可省略注解。大家搭建微服务和多模块时候,通常不会使用spring-boot-starter-parent作为父工程吧?
void org.springframework.web.method.ControllerAdviceBean.<init>(java.lang.Object)
复制代码 隐藏代码 import io.swagger.v3.oas.annotations.Hidden; @Hidden @ControllerAdvice public class GlobalExceptionHandler {}
Fontconfig head is null, check your fonts or fonts configurat
意味当前系统环境中,无法正确读取字体配置文件,或者根本缺少字体支持包。这在一些精简 Linux 系统(例如 CentOS、Alpine、Docker 镜像中)尤为常见。
应用在渲染字体或图形时,会依赖系统字体和字体配置库(如 fontconfig 和 freetype)。如果这些组件缺失或配置错误,就会导致:字体无法加载、图形界面渲染异常、Fontconfig 报错信息打印等。