封装Springboot基础框架功能-03

在些模块中汇总了一些web开发常用的配置和功能。

模块源码结构

在这里插入图片描述

Restful API常用定义

QueryParam请求参数

@Data
public class QueryParam {

    private String key;

    private String value;
}

RestfulController实现

RestfulController.java,主要汇总一些常用的restful的写法

@Slf4j
@RestController
@RequestMapping("/api/load")
public class RestfulController {

    /*默认 required = true*/
    @GetMapping("/v1/getMapping")
    public BaseResponse<String> getMapping( @RequestParam(value="username", required = false)  String name){
        log.info("getMapping:{}", name);
        return BaseResponse.success(name);
    }

    /*这处必须用 @PathVariable 注解*/
    @GetMapping("/v1/pathVariable/{name}")
    public BaseResponse pathVariable(@PathVariable("name") String name){
        log.info("getMapping:{}", name);
        return BaseResponse.success(name);
    }

    /*默认 required = true*/
    @PostMapping(value = "/v1/postMapping")
    public BaseResponse postMapping(@RequestBody QueryParam queryParam){
        log.info("getMapping:{}", queryParam);
        return BaseResponse.success(queryParam);
    }

    @RequestMapping(value = "/v1/allRequestMapping/{name}")
    public BaseResponse allRequestMapping(@PathVariable("name") String name){
        log.info("getMapping:{}", name);
        return BaseResponse.success(name);
    }
}

RestTemplate客户端

pom.xml

        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <version>4.5.14</version>
        </dependency>

        <dependency>
            <groupId>org.apache.httpcomponents.client5</groupId>
            <artifactId>httpclient5</artifactId>
            <version>5.2.3</version>
        </dependency>

RestTemplate Bean实现

配置java-ben

@Configuration
public class RestTemplateConfig {

    @Bean
    public RestTemplate restTemplate() {
        RestTemplate restTemplate = new RestTemplate();
        restTemplate.getMessageConverters().set(1, new StringHttpMessageConverter(StandardCharsets.UTF_8));
        return restTemplate;
    }
}

application.properties配置

spring.profiles.active = dev
spring.application.name=springbootCommonConfig
server.port=17000

#自定义配置服务端
service-url.service = http://www.baidu.com

调用http接口

定义一个Controller来测试Rest调用

@Slf4j
@RestController
@RequestMapping("/api/rmihttp")
public class TemplateController {

    @Autowired
    private RestTemplate restTemplate;

    @Value("${service-url.service}")
    private String serviceUrl;

    @GetMapping("/v1/hello-content")
    public BaseResponse<String> loadHelloContent(String uuid){
        String result =  restTemplate.getForObject(serviceUrl + "/s?wd=springboot", String.class, uuid);

        return BaseResponse.success(result);
    }

}

RestTemplate实现GET调用

//getForObject: 返回对象为响应体中数据转化成的对象
@GetMapping("/{id}")
public Result getUser(@PathVariable Long id) {
    return restTemplate.getForObject(userServiceUrl + "/user/{1}", Result.class, id);
}

//getForEntity: 返回对象为ResponseEntity对象,包含了响应中的一些重要信息,比如响应头、响应状态码、响应体等,举例如下:
@GetMapping("/getEntityByUsername")
public Result getEntityByUsername(@RequestParam String username) {
    ResponseEntity<Result> entity = restTemplate.getForEntity(userServiceUrl +"/user/getByUsername?username={1}", Result.class, username);
    if (entity.getStatusCode().is2xxSuccessful()) {
        return entity.getBody();
    } else {
        return new Result("操作失败", 500);
    }
}

RestTemplate实现POST调用

// postForObject
@PostMapping("/insert")
public Result insert(@RequestBody User user) {
    return restTemplate.postForObject(userServiceUrl + "/user/insert", user, Result.class);
}

//postForEntity
@PostMapping("/insert")
public Result insert(@RequestBody User user) {
    return restTemplate.postForEntity(userServiceUrl + "/user/insert", user, Result.class).getBody();
}

Swagger-UI测试Restful API

application-dev.properties配置

以下全是自定义的属性,需要有一个相应的配置类,如下:

#swagger
springdoc.api-docs.enabled=true
springdoc.api-docs.path=/api-schema

swagger-config.group = default-group
swagger-config.description= The following is a restful-api list of {} application, and you can browse or test them to determine if they are working as you expect.
swagger-config.version=V1.0
swagger-config.urlPattern=/**
swagger-config.base-package=com.korgs
swagger-config.authorization-key-name=token
swagger-config.wiki = https://korgs.blog.csdn.net/

关键配置只有swagger-config.base-packageswagger-config.urlPattern,开发时最常修改的是swagger-config.base-package用来扫描API类。如果想关闭swagger功能,可以设置springdoc.api-docs.enabled=false

OpenAPIConfig Bean实现

在OpenAPIConfig类中包含了一个内部类SwaggerProperties,SwaggerProperties和上述application-dev.properties中相应的配置相对应。

@Configuration
public class OpenAPIConfig {

    @Autowired
    private SwaggerProperties swaggerProperties;

    @Value("${spring.application.name}")
    private String applicationName;

    @Bean
    public OpenAPI openAPI() {

        return new OpenAPI()
                .info(new Info()
                        .title(applicationName)
                        .description(StrUtil.format(swaggerProperties.getDescription(), applicationName))
                        .version(swaggerProperties.getVersion()))
                .externalDocs(new ExternalDocumentation()
                        .description("See details documentation, please click here!")
                        .url(swaggerProperties.getWiki()));
    }

    @Bean
    public GroupedOpenApi applicationRestfulApi() {
        return GroupedOpenApi.builder()
                .group(swaggerProperties.getGroup())
                .packagesToScan(swaggerProperties.getBasePackage().split(","))
                .pathsToMatch(swaggerProperties.getUrlPattern())
                .build();
    }

    @Data
    @Component
    @ConfigurationProperties(prefix = "swagger-config")
    public static class SwaggerProperties{

        private String group;

        private String description;

        private String version;

        private String basePackage;

        private String authorizationKeyName;

        private String urlPattern;

        private String wiki;
    }
}

Log4j配置实现

定义一个名为log4j2.xml的文件,并在application.properties中做如下配置

# log4j
logging.config=classpath:log4j2.xml
logging.level.root=INFO
logging.level.org.springframework.web=ERROR

log4j2.xml

<?xml version="1.0" encoding="UTF-8"?>

<!--scan:当此属性设置为true时,配置文件如果发生改变,将会被重新加载,默认值为true-->
<configuration scan="false">
	<!--日志文件存储路径,默认为项目根目录下,默认值为logs-->
	<property name="LOG_PATH" value="logs"/>
	<!-- 定义日志文件名称 -->
	<property name="appName" value="springbootBase"></property>

	<!--控制台日志格式定义-->
	<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
		<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
			<pattern>%d{yyyy-MM-dd HH:mm:ss}  [%thread] [%level] [%c] %M %L - %msg%n</pattern>
		</encoder>
	</appender>

	<!--所有日志-->
	<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
		<file>${LOG_PATH}/${appName}.info.log</file>
		<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
			<pattern>%d{yyyy-MM-dd HH:mm:ss}  [%thread] [%level] [%c] %M %L - %msg%n</pattern>
		</encoder>
		<!--按天存档日志,最多存储30天-->
		<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
			<FileNamePattern>${LOG_PATH}/${appName}.info.%d{yyyy-MM-dd}.log.gz</FileNamePattern>
			<MaxHistory>30</MaxHistory>
		</rollingPolicy>
	</appender>

	<!--error日志-->
	<appender name="ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender">
		<filter class="ch.qos.logback.classic.filter.LevelFilter">
			<level>ERROR</level>
			<onMatch>ACCEPT</onMatch>
			<onMismatch>DENY</onMismatch>
		</filter>
		<file>${LOG_PATH}/${appName}.err.log</file>
		<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
			<fileNamePattern>${LOG_PATH}/${appName}.err.%d{yyyy-MM-dd}.log.gz</fileNamePattern>
			<maxHistory>30</maxHistory>
		</rollingPolicy>
		<encoder>
			<pattern>%d{yyyy-MM-dd HH:mm:ss}  [%thread] [%level] [%c] %M %L - %msg%n</pattern>
		</encoder>
	</appender>

	<!--设置哪些日志会生效-->
	<root level="INFO">
		<appender-ref ref="STDOUT"/>
		<appender-ref ref="FILE" />
		<appender-ref ref="ERROR" />
	</root>
</configuration>

<!--1   %d{yyyy-MM-dd HH:mm:ss, SSS}	日志产生时间,输出到毫秒的时间-->
<!--2	%level	输出日志级别-->
<!--3	%logger 或 %c	logger 的名称,通常为包名+类名-->
<!--4	%thread 或 %t	输出当前线程名称-->
<!--5	%p	日志输出格式-->
<!--6	%message 或 %msg 或 %m	日志内容,即 http://logger.info("message")-->
<!--7	%n	换行符-->
<!--8	%class 或 %C	输出 Java 类名-->
<!--9	%file 或 %F	输出文件名-->
<!--10	%L	输出错误行号-->
<!--11	%method 或 %M	输出方法名-->
<!--12	%l	输出语句所在的行数, 包括类名、方法名、文件名、行数-->
<!--13	hostName	本地机器名-->
<!--14	hostAddress	本地 ip 地址-->

线程跟踪日志

这个日志跟踪功能只能在本应用中适用,如果想在分布式环境中需要更高级的设计或是采用类似ELK之间的中间件。不过这个跟踪功能在分析问题时也非常有用。其输出格式如下:

2024-05-07 23:54:22  [http-nio-18081-exec-8] [INFO] [com.korgs.framework.logger.AccessLogInterceptor] accessLog 119 - tid=179864225215371860 appId=noSet ip=0:0:0:0:0:0:0:1 uri=/helloworld method=com.korgs.SpringbootWebApplication.helloWorld param={} inTime=1715097262676 
2024-05-07 23:54:22  [http-nio-18081-exec-8] [INFO] [com.korgs.SpringbootWebApplication] helloWorld 28 - tid=179864225215371860 msg=I am busy to handle this request.
2024-05-07 23:54:22  [http-nio-18081-exec-8] [INFO] [com.korgs.framework.logger.AccessLogInterceptor] accessLog 119 - tid=179864225215371860 uri=/helloworld exec=14
  • tid:随机生成的事务ID,每次请求唯一,并在同一线程内有效;
  • inTime:表示接收请求的时间
  • exec:表示当前请法响应的总时间
  • appId:表示调用的客户端标识
  • ip:表示调用的客户端IP
  • uri:表示客户端调用的API
  • method:表示客户端调用的API实现的java方法

源码下载

涉及模块:

  • springboot-common-config:17000

源码下载:

源码运行方法:

相关推荐

  1. SpringBoot-03

    2024-05-10 20:40:06       37 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-05-10 20:40:06       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-05-10 20:40:06       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-05-10 20:40:06       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-05-10 20:40:06       18 阅读

热门阅读

  1. MySQL变量的定义与使用

    2024-05-10 20:40:06       10 阅读
  2. mysql 按字段查询重复的数据

    2024-05-10 20:40:06       14 阅读
  3. CentOS常见的命令

    2024-05-10 20:40:06       7 阅读
  4. 【无标题】

    2024-05-10 20:40:06       13 阅读
  5. AI写代码:请帮我写一段kmeans算法的python代码

    2024-05-10 20:40:06       10 阅读
  6. 【面试干货】HTTP和HTTPS之间的主要区别

    2024-05-10 20:40:06       9 阅读
  7. Leetcode 第396场周赛 问题和解法

    2024-05-10 20:40:06       10 阅读
  8. Openssl X509证书从HexStream中解析

    2024-05-10 20:40:06       11 阅读
  9. node.js中 cluster 模块和 worker_threads 模块

    2024-05-10 20:40:06       8 阅读
  10. Git的常见面试题

    2024-05-10 20:40:06       9 阅读
  11. FastDDS编译安装说明

    2024-05-10 20:40:06       8 阅读