3.1什么是Logback,它和log4j2的区别
Java 开源日志框架,以继承改善 log4j 为目的而生,是 log4j 创始人 Ceki Gülcü 的开源产品。 它声称有极佳的性能,占用空间更小,且提供其他日志系统缺失但很有用的特性。 其一大特色是,在 logback-classic 中本地(native)实现了 SLF4J API(也表示依赖 slf4j-api)
3.2 为什么需要使用logback
Spring Boot 默认使用的是SLF4J 结合 LogBack
log4j2 性能已经远超logback,不过两者使用上没有什么特别大的区别,学会一个,学另一个不难。大部分情况下logback已经能满足要求。具体用什么,看公司的做法即可。
3.3 如何使用logback
3.3.1 书写logback.xml(注意存放位置为resources)
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<include resource="org/springframework/boot/logging/logback/defaults.xml"/>
<property name="LOG_FILE" value="${LOG_FILE:-${LOG_PATH:-${LOG_TEMP:-${java.io.tmpdir:-/tmp}}}/spring.log}"/>
<include resource="org/springframework/boot/logging/logback/console-appender.xml"/>
<!-- 日志文件存放路径(日志目录) -->
<property name="PATH" value="log"/>
<!-- 日志文件的相关配置 -->
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 正在记录的日志文件的路径及文件名 -->
<file>${PATH}/spring.log</file>
<append>true</append>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${PATH}/spring.log.%d{yyyy-MM-dd}.%i.gz</fileNamePattern>
<maxFileSize>100MB</maxFileSize><!-- 单个文件最大100MB -->
<maxHistory>30</maxHistory><!-- 最多保存30天的纪录-->
<totalSizeCap>3GB</totalSizeCap><!-- 日志最大总量3GB-->
</rollingPolicy>
<encoder>
<!--格式化输出:%d表示日期,%-5level:级别从左显示5个字符宽度,%msg:日志消息,%n是换行符-->
<pattern>[%date{yyyy-MM-dd HH:mm:ss}] [%-5level] [%logger:%line] --%mdc{client} %msg%n</pattern>
</encoder>
</appender>
<!-- 控制台输出的样式-->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>[%date{yyyy-MM-dd HH:mm:ss}] [%-5level] [%logger:%line] --%mdc{client} %msg%n</pattern>
</encoder>
</appender>
<!--这个表示指定某个包下的日志级别,需要改成自己的包 -->
<logger name="com.wanxi.redis.mapper" level="DEBUG"/>
<!-- 默认 -->
<root>
<level value="INFO" />
<appender-ref ref="FILE"/>
<appender-ref ref="STDOUT"/>
</root>
</configuration>
3.3.2 日志的优先级(重点)
Logback中支持7种日志级别,优先级从高到低分别是:OFF、ERROR、WARN、INFO、DEBUG、TRACE、ALL
TRACE 在线调试: 该级别日志,默认情况下,既不打印到终端也不输出到文件。此时,对程序运行效率几乎不产生影响
DEBUG 终端查看、在线调试: 该级别日志,默认情况下会打印到终端输出,但是不会归档到日志文件。因此,一般用于开发者在程序当前启动窗口上,查看日志流水信息。
INFO 报告程序进度和状态信息: 一般这种信息都是一过性的,不会大量反复输出。 例如:连接商用库成功后,可以打印一条连库成功的信息,便于跟踪程序进展信息。
WARNING 警告信息: 程序处理中遇到非法数据或者某种可能的错误。该错误是一过性的、可恢复的,不会影响程序继续运行,程序仍处在正常状态。
ERROR 状态错误: 该错误发生后程序仍然可以运行,但是极有可能运行在某种非正常的状态下,导致无法完成全部既定的功能。
Log4j建议只使用四个级别,优先级从高到低分别是 ERROR、WARN、INFO、DEBUG。通过在这里定义的级别,您可以控制到应用程序中相应级别的日志信息的开关。比如配置成了INFO级别,则应用程序中所有DEBUG级别的日志信息将不被打印出来,也是说大于等于的级别的日志才输出。
TRACE | DEBUG | INFO | WARN | ERROR | OFF | |
---|---|---|---|---|---|---|
TRACE | YES | NO | NO | NO | NO | NO |
DEBUG | YES | YES | NO | NO | NO | NO |
INFO | YES | YES | YES | NO | NO | NO |
WARN | YES | YES | YES | YES | NO | NO |
ERROR | YES | YES | YES | YES | YES | NO |
项目中设置的日志级别为:TRACE,包括 TRACE / DEBUG / INFO / WARN / ERROR 的日志级别都打印
项目中设置的日志级别为:DEBUG ,包括 DEBUG / INFO / WARN / ERROR 的日志级别都打印
项目中设置的日志级别为:INFO ,包括 INFO / WARN / ERROR 的日志级别都打印
项目中设置的日志级别为:WARN,包括 WARN / ERROR 的日志级别都打印
项目中设置的日志级别为:ERROR ,只打印 ERROR 的日志级别都打印
实际工作中,开发、测试环境我们会放开到debug级别,生产环境我们最多只放开到info级别。这样做的目的是减少生产环境的日志容量。
3.3.1测试
注意导包
import ch.qos.logback.classic.Logger;
import org.slf4j.LoggerFactory;
@SpringBootTest
class Springboot3ApplicationTests {
private static Logger logger = (Logger) LoggerFactory.getLogger(Springboot3ApplicationTests.class.getName());
@Test
void contextLoads() {
logger.trace("contextLoads trace");
logger.debug("contextLoads debug");
logger.info("contextLoads info");
logger.warn("contextLoads warn");
logger.error("contextLoads error");
}
运行后可以看出控制台只展示了info,warn,以及error三个内容,为什么?
这是因为我们在配置文件中设置了日志级别为info而从上表可以看出,日志级别比info高的是不会展示的
3.4 总结
我们要用日志只需要去配置好相关配置文件,设置好日志的级别就可以正常使用了
4.1什么是Swagger
Swagger是一款RESTFUL接口的文档在线自动生成+功能测试功能软件。Swagger是一个规范和完整的框架,用于生成、描述、调用和可视化RESTful风格的Web服务。目标是使客户端和文件系统作为服务器以同样的速度来更新文件的方法,参数和模型紧密集成到服务器。
这个解释简单点来讲就是说,swagger是一款可以根据resutful风格生成的生成的接口开发文档,并且支持做测试的一款中间软件。
4.2 为什么使用Swagger
对于后端开发
-
不用去维护API文档,方法参数名修改、增加、减少参数都可以直接生效,不用手动维护,随时能保证修改的同步,方便前后端进行沟通。
-
可以进行简单的测试,减轻了后端人员对api的测试工作(很多时候我们都用postmain来做api测试)
-
对代码侵入性低,采用全注解的方式,开发简单
对于前端开发来说
-
后端只需要定义好接口,会自动生成文档,接口功能、参数一目了然
-
联调方便,如果出问题,直接测试接口,实时检查参数和返回值,就可以快速定位是前端还是后端的问题
对于测试
-
对于某些没有前端界面UI的功能,可以用它来测试接口
-
操作简单,不用了解具体代码就可以操作
-
操作简单,不用了解具体代码就可以操作
-
对于前端来说后端只需要定义好接口,会自动生成文档,接口功能、参数一目了然
-
方便前后端联调,如果出问题,直接测试接口,实时检查参数和返回值,就可以快速定位是前端还是后端的问题
-
缺点:增加了开发成本,写接口还得再写一套参数配置
4.3 swagger的使用
4.3.1 导入依赖
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>net.minidev</groupId>
<artifactId>json-smart</artifactId>
</dependency>
4.3.2 编写配置类
@Configuration
@EnableSwagger2
public class SwaggerConfig {
private ApiInfo apiInfo(){
ApiInfoBuilder apiInfoBuilder = new ApiInfoBuilder();
apiInfoBuilder.title("Spring Boot Day 4 API 接口文档")
.version("1.0")
.description("演示授课内容使用");
return apiInfoBuilder.build();
}
@Bean
public Docket createRestApi() {
Docket docket = new Docket(DocumentationType.SWAGGER_2);
docket.apiInfo(apiInfo()).select() .apis(RequestHandlerSelectors.basePackage("com.cn.wanxi.controller"))
//为有@Api注解的Controller生成API文档
// .apis(RequestHandlerSelectors.withClassAnnotation(Api.class))
//为有@ApiOperation注解的方法生成API文档
// .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
.paths(PathSelectors.any())
.build();
return docket;
}
}
4.3.3 编写持久层
@Data //这个不能少,要不就用get,set方法代替
@ApiModel(value = "用户",description = "用于描述用户对象")
public class UserEntity {
@ApiModelProperty(value = "用户ID",example = "12")
private Long id;
@ApiModelProperty(value = "用户姓名",example = "张三")
private String name;
@ApiModelProperty(value = "用户年龄",example = "12")
private String age;
@ApiModelProperty(value = "用户描述",example = "四川广安人,清华大学毕业,现居北京")
private String description;
}
4.3.4 控制层
@RestController
@Api(tags = "用户管理",value = "用户Open api 入口")
public class UserController {
@PostMapping("/user")
@ApiOperation(value = "添加用户",response = UserEntity.class,httpMethod = "POST")
public UserEntity addUser(@RequestBody UserEntity user) {
return user;
}
}
4.3.5 启动类
@SpringBootApplication
@EnableSwagger2
public class Springboot3Application {
public static void main(String[] args) {
SpringApplication.run(Springboot3Application.class, args);
}
}
4.3.6 配置properties.yml
spring:
mvc:
pathmatch:
matching-strategy: ant_path_matcher
4.3.7 启动后访问网址
2.x:http://localhost:8080/swagger-ui.html
3.0:http://localhost:8080/swagger-ui/index.html
4.3.8 注解说明
Swagger2 和 3的注解说明
swagger2 | swagger3(openApi3) | 注解位置 |
---|---|---|
@Api | @Tag(name = “接口类名”,description = “接口类描述”) | Controller 类上 |
@ApiOperation | @Operation(summary =“接口方法描述”) | Controller 方法上 |
@ApiImplicitParams | @Parameters | Controller 方法上 |
@ApiImplicitParam | @Parameter(description=“参数描述”) | Controller 方法上 @Parameters 里 |
@ApiParam | @Parameter(description=“参数描述”) | Controller 方法的参数上 |
@ApiIgnore | @Parameter(hidden = true) | @Operation(hidden = true) |
@ApiModel | @Schema | DTO类上 |
@ApiModelProperty | @Schema | DTO属性上 |
4.4 补充
如果项目中整合了后面的Security,jwt等需要对页面进行放行
具体
http.cors().and().csrf().disable()
.authorizeRequests()
// 对某些特定的url不进行认证
.antMatchers("/newCode","/login","/swagger-ui.html/**","/swagger-resources/**","/v2/*","/webjars/**","/csrf","/back/company/*").permitAll()
// 其它请求要认证
.anyRequest().authenticated()
// 确保使用无状态会话(stateless session)
//Spring Security永远不会创建一个HttpSession,也永远不会使用它获取SecurityContext
.and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
// .and().cors().configurationSource(configurationSource());
// 这一步,告诉Security 框架,我们要用自己的UserDetailsService实现类
// 来传递UserDetails对象给框架,框架会把这些信息生成Authorization对象使用
.and().userDetailsService(userDetailsService);
// 在UsernamePasswordAuthenticationFilter过滤前,我们使用jwt进行过滤
http.addFilterBefore(jwtAuthenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);