阅读理解
- 命令之间空一行:表示前面的是配置
- 红色背景:表示待验证
- 蓝色背景:表示常用或推荐
- 绿色背景:注意/推荐
json 转 对象
import com.fasterxml.jackson.databind.ObjectMapper;
public DebangResp convertJsonToObject(String jsonString) {
ObjectMapper objectMapper = new ObjectMapper();
try {
return objectMapper.readValue(jsonString, DebangResp.class);
} catch (Exception e) {
e.printStackTrace();
// 处理异常,例如返回 null 或抛出自定义异常
return null;
}
}
jenkins
安装
- 添加yum 源仓库
wget -O /etc/yum.repos.d/jenkins.repo http://pkg.jenkins-ci.org/redhat/jenkins.repo
- 导入仓库源的key(秘钥)
rpm --import https://jenkins-ci.org/redhat/jenkins-ci.org.key
详细步骤
- 官网地址:Jenkins

-


- 启动:java -jar jenkins.war
稳定版本
Redhat提供安装Jenkins长期稳定版本的源,参考下面命令安装:
sudo wget -O /etc/yum.repos.d/jenkins.repo http://pkg.jenkins-ci.org/redhat-stable/jenkins.repo
sudo rpm --import https://jenkins-ci.org/redhat/jenkins-ci.org.key
sudo yum install jenkins
报错
解决方案
IDEA
idea快捷键
ctrl+h:查看继承关系
structure 查看该类的成员
idea自定义模板
自定义创建文件模板
- 在设置窗口中,选择 Editor > File and Code Templates > file
- 例如编辑class类容
#if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "")package ${PACKAGE_NAME};#end
#parse("File Header.java")
/**
* 客户身体报告(CustomerPhysicalReport)实体类
*
* @author zhg
* @since ${DATE} ${TIME}
*/
public class ${NAME} {
}
#if 和 #end 是模板引擎的语法,用来控制代码块的条件生成。
#parse("File Header.java") 从另一个模板文件 "File Header.java" 中解析并插入代码。
- 特殊变量:
${NAME}: 用于类名。
${PACKAGE_NAME}: 用于包名。
${USER}: 用户名。
${DATE}: 当前日期。:年/月/日
${TIME}: 当前时间。
${YEAR}: 当前年份。
${MONTH}: 当前月份。
${DAY_OF_MONTH}: 当前日期中的天数。
${HOUR}: 当前小时数。
${MINUTE}: 当前分钟数。
- 自定义变量: 如果您想添加更多自定义变量,可以在模板中使用 ${VAR_NAME} 的形式,并在创建类时 IDEA 会提示您输入这些变量的值。
自定义 方法 模板
- File -> Settings - > Editor -> Live Templates -> 点击"+"号 -> Template Group
新建组名


- 编辑类容
/** @Author zhg
@Description //TODO end
@Date time date
@Param param paramparam
@return return
**/
- 配置生效位置

- 应用
add
快捷键应用
- Windows/Linux: 按 Ctrl + Shift + Doc Comment (或 Ctrl + Shift + /)。
- macOS: 按 Cmd + Shift + Doc Comment (或 Cmd + Shift + /)。
IDEA 一键启动配置



获取时间
LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))
swagger
1.导入依赖
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.8.0</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.8.0</version>
</dependency>
2.配置类
import org.springframework.beans.factory.annotation.Value;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.Collections;
@Configuration
@EnableSwagger2
public class SwaggerConfig {
@Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.any())
.paths(PathSelectors.any())
.build()
.apiInfo(apiInfo());
}
private ApiInfo apiInfo() {
return new ApiInfo(
"My API",
"A sample API documentation generated using Springfox",
"API TOS",
"Terms of service",
new Contact("John Doe", "www.example.com", "myeaddress@company.com"),
"License of API", "API license URL", Collections.emptyList());
}
}
3.yml
spring:
mvc:
pathmatch:
matching-strategy: ANT_PATH_MAT
4.访问
http://localhost:端口/路径/swagger-ui.html
4.Knife4j增强
<dependency> <groupId>com.github.xiaoymin</groupId> <artifactId>knife4j-spring-boot-starter</artifactId> <version>2.0.4</version> </dependency>删除
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.8.0</version>
</dependency>
5.添加配置(可选)
knife4j: enable: true setting: enablePathMapping: true
5.访问
http://localhost:端口/路径/doc.html
6.使用
- @Api
用于类上,表示这是一个 Swagger 资源。
参数:
tags:描述该类的作用,参数是一个数组,可以填写多个标签。
description:描述该类的功能。
@Api(tags = "用户管理", description = "用户基本信息操作")
public class UserController {
// ...
}
- @ApiOperation
用于方法上,描述一个具体的 API 操作。
参数:
value:描述此操作的简短摘要。
notes:额外的注意事项。
response:指定响应对象的类型。
tags:与 @Api 类似,用于分类。
@ApiOperation(value = "获取用户列表", notes = "返回所有用户的列表", response = User.class)
public List<User> getUsers() {
// ...
}
- @ApiParam
用于方法参数上,描述一个参数。
参数:
value:描述此参数的意义。
required:是否必须。
defaultValue:默认值。
@ApiOperation(value = "获取用户详情", notes = "根据 ID 获取用户详情", response = User.class)
public User getUser(@ApiParam(value = "用户ID", required = true) @PathVariable Long id) {
// ...
}
- @ApiResponses
用于方法上,描述可能的 HTTP 响应状态码。
参数:
value:一个数组,每个元素都是一个 ApiResponse 对象。
@ApiResponses(value = {
@ApiResponse(code = 200, message = "成功"),
@ApiResponse(code = 404, message = "未找到"),
@ApiResponse(code = 500, message = "内部服务器错误")
})
public User getUser(@PathVariable Long id) {
// ...
}
@ApiResponse
描述一个 HTTP 响应的状态码及消息。
参数:
code:HTTP 状态码。
message:描述信息。
- @ApiModel
用于类上,描述一个模型对象。
参数:
description:描述此模型的作用。
@ApiModel(description = "用户信息")
public class User {
private Long id;
private String name;
// ...
}
- @ApiModelProperty
用于字段上,描述模型对象中的一个属性。
参数:
value:描述此属性的意义。
required:是否必须。
example:示例值。
@ApiModel(description = "用户信息")
public class User {
@ApiModelProperty(value = "用户ID", required = true, example = "1")
private Long id;
// ...
}
mvn 打包
- mvn install -DskipTests # 跳过测试,但不跳过编译
- mvn install -Dmaven.test.skip=true # 跳过测试和编译
- mvn install:install-file -Dfile=path/to/example.jar -DgroupId=com.example -DartifactId=example-jar -Dversion=1.0 -Dpackaging=jar 添加jar包到仓库
-Dfile .jar包路径
-DgroupId 组id
-DartifactId artifactId
-Dversion 版本
-Dpackaging 文件类型
pom.xml
jar包依赖导入
<groupId>com.bianque</groupId>
<artifactId>bianque-common-dop</artifactId>
<version>0.0.1-SNAPSHOT</version>
<scope>system</scope>
<systemPath>${project.basedir}/src/main/resources/libs/dop-sdk-0.0.1-SNAPSHOT.jar</systemPath>
服务调用
Feign
报错
- JSON parse error: Illegal character ((CTRL-CHAR, code 31)): only regular white space
- 若依框架没有权限。需要登录状态(才能通过Security)
解决方案
位置:调用项目
1、关闭请求数据压缩
feign.compression.request.enabled: false
feign.compression.response.enabled: false
2、设置请求压缩的最小请求大小
feign.compression.request.min-request-size: 8192
git
文件颜色的含义
蓝色:修改过的文件
红色:冲突文件
粉红:未追踪的文件
绿色:已经追踪文件
暂存
- 执行暂存
git stash
apply [stash_key] 不会丢失栈信息
sava ‘描述信息’ 有描述信息
push 压栈 没有描述信息
pop 弹栈 会丢失栈信息
- 查看暂存列表
git stash list
- 应用暂存
git stash apply [stash-key]
--index [n] windows平台替换 apply [stash-key]
分支
- 查看分支
git branch
-d 删除已经完成合并的分支
-D 强制删除分支
- 新建分支
git branch branch_name
- 切换分支
git swicth branch_name
- 合并分支
git merge brash_name
- 终止合并分支
git merge --abort
合并分支到当前分支
- 查看分支图
git log --graph --oneline --decorate --all
或
alias git-log='git log --graph --oneline --decorate --all'
git-log
-
提交
git commit -m "描述信息"
- 与上一个commit合并
git commit --amend -m "描述信息"
远端仓库
- 查看远端仓库
git remote
参数解析
- v 查看所有远端url
- get-url 查看特定远端的url
- set-url 设置远端仓库的url
- remove local_origion_branch_name
- 查看特定远端仓库地址
- 对接远端仓库
git remote add [local_origin_branch_name] [origin_url]
- 推送并合并
git push [local_origin_branch_name] [local_branch_name:origin_branch_name]
或
git push --set-upstream local_origin_branch_name [local_branch_name:origin_branch_name]
git push
-f 强制覆盖
远端分支与本地分支的关联关系
git branch -vv
- 远端克隆
git clone [origin_url] [loca_file_name]
- 远端抓取
git fetch [origin_name] [origin_branch_name]
或
git fetch
抓取远端分支,但不会合并
- 远端拉取
git pull local_origion_branch_name origion_branch_name:local_branch_name
或
git fetch
git merge branch_name
冲突
修改同一个文件,同一行
- 查看冲突列表
git status
both modified: main1.txt
both modified: main2.txt
- 查看冲突的具体内容
git diff
-
本地仓库冲突解决方案
1.提交:生成冲突文件
2.修改:冲突文件
3.添加:添加文件到暂存区
3.提交
-
远程仓库 冲突解决方案
1.pull :生成冲突文件
2.修改:冲突文件
3.添加:添加文件到暂存区
3.commit:提交文件(自动合并分支)
4.push :推送自己的最新修改
回退
- 回退版本
git reset id
--soft 保留工作区,暂存区: 可以重新修改,再提交
--mixed 保留工作区,清除暂存区:可以重新修改,再提交(需要重新添加暂存区)
--hard 清除工作区,暂存区
- 查看暂存区内容
git ls-files
- 查看操作记录
git reflog
- 查看提交记录
git log --oneline
查看版本信息
git log --graph
可以回退版本
CI/CD 还没完成
git安装
gitlab安装
jenkins安装之docker
1.pull 镜像
docker pull jenkins/jenkins:lts
2.启动
docker run \
--name jenkins \
--restart always \
-d \
-p 8080:8080 \
-p 50000:50000 \
-v jenkins_home:/var/jenkins_home \
-v /var/run/docker.sock:/var/run/docker.sock \
-v /usr/bin/docker:/usr/bin/docker \
jenkins/jenkins:lts
3.访问
http://ip:8080
3.查看密码
# Jenkins容器启动日志 保存密码后面登陆控制台使用。
docker logs -f 容器名
mybatis
mapper
- import org.apache.ibatis.annotations.Param; 参数包
mapper.xml
- classpath:只会到你的class路径中查找找文件。
- classpath*:不仅包含class路径,还包括jar文件中(class路径)进行查找。
-
<trim> 标签 prefix:需要在去除之前 添加的前缀。 suffix:需要在去除之后 添加的后缀。 prefixOverrides:需要 去除的前缀。 suffixOverrides:需要 去除的后缀。
- 条件生成sql
<set>特点:
用于生成 SQL 更新语句中的 SET 子句。
只有至少一个子元素的值不为 null 时才会输出整个 SET 子句。
常见于 UPDATE 语句中,用来动态构建需要更新的字段列表。
<update id="updateUser">
UPDATE user
<set>
<if test="username != null">username = #{username}, </if>
<if test="email != null">email = #{email}, </if>
<if test="age != null">age = #{age} </if>
</set>
WHERE id = #{id}
</update>
<trim>特点:
可以移除前导或尾随的文本(如逗号、括号等),这对于构建动态 SQL 很有用。
支持 prefix 和 suffix 属性来添加前缀和后缀。
支持 prefixOverrides 和 suffixOverrides 属性来移除多余的前缀和后缀。
<select id="selectUsers">
SELECT * FROM user
WHERE 1=1
<trim prefix="AND (" suffix=")" prefixOverrides="AND">
<if test="username != null"> username = #{username} </if>
<if test="email != null"> AND email = #{email} </if>
<if test="age != null"> AND age = #{age} </if>
</trim>
</select>
- 循环生成sql
<foreach collection="entities" item="entity" separator=",">
(#{entity.uid},#{entity.bannerSetUid}, #{entity.picUrl}, #{entity.linkType}, #{entity.jumpUrl},
#{entity.sortNum}, #{entity.status}, #{entity.createTime}, #{entity.updateTime})
</foreach>
这个XML函数是一个foreach循环,它的功能是对一个名为entities的集合进行迭代处理。每次迭代时,将集合中的每个元素作为entity进行处理,并用,作为分隔符将处理结果拼接在一起。在迭代过程中,将每个entity的uid、bannerSetUid、picUrl、linkType、jumpUrl、sortNum、status、createTime和updateTime属性按照给定的顺序输出。
- 类的属性映射
<resultMap type="com.apq.sdemo.common.dataobj.ManageDO" id="ManageMap">
<result property="uid" column="uid" jdbcType="VARCHAR"/>
</resultMap>
多数据源:动态数据源切换
- 1.配置多数据源yml
datasource:
mysql-db:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.jdbc.Driver
jdbc-url: jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&failOverReadOnly=false&allowMultiQueries=true&serverTimezone=GMT%2B8&useSSL=false
username: root
password: root
secondary:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.jdbc.Driver
jdbc-url: jdbc:mysql://localhost:3306/test1?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&failOverReadOnly=false&allowMultiQueries=true&serverTimezone=GMT%2B8&useSSL=false
username: root
password: root
- 2. DataSourceConfig 类配置
@Configuration
@MapperScan(basePackages = "com.test.mapper", sqlSessionTemplateRef = "mysqlDbSqlSessionTemplate")
public class DataSourceConfig {
@Bean(name = "datasource1")
@ConfigurationProperties(prefix = "spring.datasource.mysql-db")
public DataSource datasource1() {
return DataSourceBuilder.create().build();
}
@Bean(name = "datasource2")
@ConfigurationProperties(prefix = "spring.datasource.secondary")
public DataSource datasource2() {
return DataSourceBuilder.create().build();
}
@Bean(name = "dynamicDataSource")
@Primary
public DataSource dynamicDataSource(){
DynamicDataSource dynamicDataSource = new DynamicDataSource();
// 设置默认数据源 这个代码有点重复了,因为我们在DataSourceChange类中已经设定了默认数据库
dynamicDataSource.setDefaultTargetDataSource(datasource1());
HashMap<Object, Object> objectObjectHashMap = new HashMap<>();
objectObjectHashMap.put("datasource1", datasource1());
objectObjectHashMap.put("datasource2", datasource2());
dynamicDataSource.setTargetDataSources(objectObjectHashMap);
return dynamicDataSource;
}
@Bean
public SqlSessionFactory mysqlDbSqlSessionFactory(@Qualifier("dynamicDataSource") DataSource dataSource) throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(dataSource);
bean.setVfs(SpringBootVFS.class);
bean.setTypeAliasesPackage("com.test.dao");
bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath*:mapper/*.xml"));
return bean.getObject();
}
// @Bean
// public DataSourceTransactionManager mysqlDbTransactionManager(@Qualifier("dynamicDataSource") DataSource dataSource) {
// return new DataSourceTransactionManager(dataSource);
// }
@Bean
public PlatformTransactionManager transactionManager(){
return new DataSourceTransactionManager(dynamicDataSource());
}
@Bean
public SqlSessionTemplate mysqlDbSqlSessionTemplate(@Qualifier("mysqlDbSqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
return new SqlSessionTemplate(sqlSessionFactory);
}
}
- 3.编写DataSourceContextHolder
public class DataSourceContextHolder {
/**
* 默认数据源
*/
public static final String DEFAULT_DS = "datasource1";
private static final ThreadLocal<String> contextHolder = new ThreadLocal<>();
// 设置数据源名
public static void setDB(String dbType) {
System.out.println("切换到{"+dbType+"}数据源");
contextHolder.set(dbType);
}
// 获取数据源名
public static String getDB() {
return (contextHolder.get());
}
// 清除数据源名
public static void clearDB() {
contextHolder.remove();
}
}
- 3.编写DynamicDataSource
public class DynamicDataSource extends AbstractRoutingDataSource {
@Override
protected Object determineCurrentLookupKey() {
return DataSourceContextHolder.getDB();
}
}
- 4.自定义注解DS
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
@Documented
public @interface DS
{
String value() default "datasource1";
}
- 5.编写AOP:DynamicDataSourceAspect
@Aspect
@Component
public class DynamicDataSourceAspect {
@Before("@annotation(com.annotation.DS)")
public void beforeSwitchDS(JoinPoint point){
//获得当前访问的class
Class<?> className = point.getTarget().getClass();
//获得访问的方法名
String methodName = point.getSignature().getName();
//得到方法的参数的类型
Class[] argClass = ((MethodSignature)point.getSignature()).getParameterTypes();
String dataSource = DataSourceContextHolder.DEFAULT_DS;
try {
// 得到访问的方法对象
Method method = className.getMethod(methodName, argClass);
// 判断是否存在@DS注解
if (method.isAnnotationPresent(DS.class)) {
DS annotation = method.getAnnotation(DS.class);
// 取出注解中的数据源名
dataSource = annotation.value();
}
} catch (Exception e) {
e.printStackTrace();
}
// 切换数据源
DataSourceContextHolder.setDB(dataSource);
}
@After("@annotation(com.annotation.DS)")
public void afterSwitchDS(JoinPoint point){
DataSourceContextHolder.clearDB();
}
}
- 6.启动类添加
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
- 7.DS注解:应用再方法上
mybatis plus
1.pom.xml
<!-- mybatisplus--> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.5.3</version> <!-- 使用最新稳定版本 --> </dependency><!-- mysql--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.33</version> </dependency>
2.yml
# datasource
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/testdb?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC
username: root
password: 123456# mybatis-plus
mybatis-plus:
configuration:
# 显示 SQL 执行语句
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
global-config:
db-config:
# 主键类型
id-type: auto
# 逻辑删除字段
logic-delete-field: deleted
# 逻辑删除值
logic-not-delete-value: 0
logic-delete-value: 1
多数据源配置
1.添加DataSourceConfig配置类
@Configuration
public class DataSourceConfig {@Bean(name = "dataSource1")
@ConfigurationProperties(prefix = "spring.datasource1")
public DataSource dataSource1() {
return DataSourceBuilder.create().build();
}@Bean(name = "dataSource2")
@ConfigurationProperties(prefix = "spring.datasource2")
public DataSource dataSource2() {
return DataSourceBuilder.create().build();
}
}
2.事务管理器配置
@Configuration
@EnableTransactionManagement
public class TransactionConfig {@Bean(name = "transactionManager1")
public PlatformTransactionManager transactionManager1(@Qualifier("dataSource1") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}@Bean(name = "transactionManager2")
public PlatformTransactionManager transactionManager2(@Qualifier("dataSource2") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
}
3.mapper接口加注解
@Repository
@Mapper
@DataSource("dataSource1")
public interface UserMapper1 extends BaseMapper<User> {
}@Repository
@Mapper
@DataSource("dataSource2")
public interface UserMapper2 extends BaseMapper<User> {
}
事务管理
@Transactional(rollbackFor = DataAccessException.class)
注解
-
@PathVariable("storeName") 路径参数
常用lambda
List 或 Set遍历
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
// 使用Lambda表达式遍历List
names.stream().forEach(name -> System.out.println(name));
aspect
1.示例
@Aspect @Component public class ControllerAspect { @Around(value = "execution(* com.x.x.x.x.controller.*.*(..))") public Object handleControllerMethods(ProceedingJoinPoint joinPoint) throws Throwable { return joinPoint.proceed(); } }
- 通知
@Around 环绕通知
- 连接点方法
joinPoint.proceed() 执行方法
joinPoint.getArgs() 获取请求参数
异步
1 @EnableAsync 启用异步及config类
@Configuration
@EnableAsync
public class AsyncConfig implements AsyncConfigurer {
@Bean
public TaskScheduler taskScheduler() {
ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
scheduler.setPoolSize(10); // 设置线程池大小
scheduler.initialize();
return scheduler;
}
}
2.写异步类的@Async 异步方法
@Async
public void customerLogsAsyncTask() {
System.out.println("Executing async task on thread: " + Thread.currentThread().getName());
try {
Thread.sleep(2000); // 模拟耗时操作
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new RuntimeException(e);
}
}
}
3.调用异步方法
@Autowired
private MyService myService;
myService.performAsyncTask();
事务
1.配置类上添加@EnableTransactionManagement注解,以启用Spring的事务管理功能。
@Configuration
@EnableTransactionManagement
public class AppConfig {@Bean
public PlatformTransactionManager transactionManager(DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}// 配置类的其他内容...
}
2. 使用@Transactional注解
@Service
public class UserService {
@Transactional(rollbackFor = Exception.class)
public void updateUserAndRole(Long userId, Long roleId) {
// 业务
}
}
常用函数接口
boolean 一个参数泛型
@FunctionalInterface
public interface Predicate<T> {
boolean test(T t);
}
void 一个参数泛型
@FunctionalInterface
public interface Consumer<T> {
void accept(T t);
// 可以有默认方法和静态方法,但核心抽象方法是accept
}
获取请求ip
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
// 获取客户端IP地址
final String clientIp = getClientIp(request);
private String getClientIp(HttpServletRequest request) {
String ip = request.getHeader("X-Forwarded-For");
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_CLIENT_IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_X_FORWARDED_FOR");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
}
return "0:0:0:0:0:0:0:1".equals(ip) ? "127.0.0.1" : getMultistageReverseProxyIp(ip);
}
请求信息获取
静态获取:RequestContextHolder
AjaxResult 返回值信息
import io.swagger.annotations.ApiModel;
import lombok.Data;
import java.io.Serializable;
import java.util.Objects;
@ApiModel(description = "返回")
@Data
public class AjaxResult<T> implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 是否成功 true or false
*/
private boolean success;
/**
* 状态码
*/
private int code;
/**
* 返回内容
*/
private String msg;
/**
* 数据对象
*/
private T data;
/**
* 状态类型
*/
public enum Type
{
/** 成功 */
SUCCESS(0),
/** 警告 */
WARN(301),
/** 错误 */
ERROR(500);
private final int value;
Type(int value)
{
this.value = value;
}
public int value()
{
return this.value;
}
}
/**
* 初始化一个新创建的 AjaxResult 对象,使其表示一个空消息。
*/
public AjaxResult()
{
}
/**
* 初始化一个新创建的 AjaxResult 对象
*
* @param type 状态类型
* @param msg 返回内容
* @param data 数据对象
*/
public AjaxResult(Type type, String msg, T data) {
this.code = type.value();
this.msg = msg;
if (Objects.nonNull(data)) {
this.data = data;
}
if (type.value == Type.SUCCESS.value) {
this.success = Boolean.TRUE;
} else {
this.success = Boolean.FALSE;
}
}
/**
* 返回成功消息
*
* @return 成功消息
*/
public static AjaxResult success()
{
return AjaxResult.success("操作成功");
}
/**
* 返回成功数据
*
* @return 成功消息
*/
public static <U> AjaxResult<U> success(U data)
{
return AjaxResult.success("操作成功", data);
}
/**
* 返回成功消息
*
* @param msg 返回内容
* @return 成功消息
*/
public static AjaxResult success(String msg)
{
return AjaxResult.success(msg, null);
}
/**
* 返回成功消息
*
* @param msg 返回内容
* @param data 数据对象
* @return 成功消息
*/
public static <U> AjaxResult<U> success(String msg, U data)
{
return new AjaxResult(Type.SUCCESS, msg, data);
}
/**
* 返回警告消息
*
* @param msg 返回内容
* @return 警告消息
*/
public static AjaxResult warn(String msg)
{
return AjaxResult.warn(msg, null);
}
/**
* 返回警告消息
*
* @param msg 返回内容
* @param data 数据对象
* @return 警告消息
*/
public static <U> AjaxResult<U> warn(String msg, U data)
{
return new AjaxResult(Type.WARN, msg, data);
}
/**
* 返回错误消息
*
* @return
*/
public static AjaxResult error()
{
return AjaxResult.error("操作失败");
}
/**
* 返回错误消息
*
* @param msg 返回内容
* @return 警告消息
*/
public static AjaxResult error(String msg)
{
return AjaxResult.error(msg, null);
}
/**
* 返回错误消息
*
* @param msg 返回内容
* @param data 数据对象
* @return 警告消息
*/
public static <U> AjaxResult<U> error(String msg, U data)
{
return new AjaxResult(Type.ERROR, msg, data);
}
/**
* 方便链式调用
*
* @param key 键
* @param value 值
* @return 数据对象
*/
@Deprecated
public AjaxResult put(String key, Object value) {
//super.put(key, value);
return this;
}
/**
* 是否为成功消息
*
* @return 结果
*/
public boolean isSuccess() {
return success;
}
public String getMsg() {
return msg;
}
public Integer getCode() {
return code;
}
}
Httpstatus 返回状态码
/**
* 返回状态码
*
* @author ruoyi
*/
public class HttpStatus
{
/**
* 操作成功
*/
public static final int SUCCESS = 200;
/**
* 对象创建成功
*/
public static final int CREATED = 201;
/**
* 请求已经被接受
*/
public static final int ACCEPTED = 202;
/**
* 操作已经执行成功,但是没有返回数据
*/
public static final int NO_CONTENT = 204;
/**
* 资源已被移除
*/
public static final int MOVED_PERM = 301;
/**
* 重定向
*/
public static final int SEE_OTHER = 303;
/**
* 资源没有被修改
*/
public static final int NOT_MODIFIED = 304;
/**
* 参数列表错误(缺少,格式不匹配)
*/
public static final int BAD_REQUEST = 400;
/**
* 未授权
*/
public static final int UNAUTHORIZED = 401;
/**
* 访问受限,授权过期
*/
public static final int FORBIDDEN = 403;
/**
* 资源,服务未找到
*/
public static final int NOT_FOUND = 404;
/**
* 不允许的http方法
*/
public static final int BAD_METHOD = 405;
/**
* 资源冲突,或者资源被锁
*/
public static final int CONFLICT = 409;
/**
* 不支持的数据,媒体类型
*/
public static final int UNSUPPORTED_TYPE = 415;
/**
* 系统内部错误
*/
public static final int ERROR = 500;
/**
* 接口未实现
*/
public static final int NOT_IMPLEMENTED = 501;
/**
* 系统警告消息
*/
public static final int WARN = 601;
}
stream 流
数据 收集.collect
数据格式控制 Collectors
分组:Collectors .groupingBy ()
示例
.collect(Collectors.groupingBy(String::toLowerCase,Collectors.groupingBy(String::toUpperCase)))
List<Map<Date, BigDecimal>> list = iphmsBraceletDataList.stream()
.map(iphmsBraceletData -> Collections.singletonMap(
iphmsBraceletData.getCreateTime(),
iphmsBraceletData.getKcal()))
.collect(Collectors.toList());
K8S
分页
import com.github.pagehelper.Page;Page<IphmsTopicsRecordSleepResp> page = new Page<>(); page.addAll(list); page.add(list); page.setTotal(new PageInfo(iphmsSleepResultList).getTotal());
Integer t1 = PageUtils.getPageNunSiz().getT1();
Integer t2 = PageUtils.getPageNunSiz().getT2();
Page<IphmsHealthResult> page = new Page<>(t1
,t2);
日期时间
常见日期格式字符串
- Jan 4, 2025 10:45:26 转 MMM d, yyyy HH:mm:ss
- 2024-12-27 20:53:57 转 yyyy-MM-dd HH:mm:ss
字符串日期,解析
format
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
- format(startTime) Date时间转字符串
formatter
DateTimeFormatter.ofPattern("yyyy-MM-dd")
- .parse(dateString) 解析字符串,返回Date
LocalDate 操作
- .withDayOfMonth(1); 设置天
-
startTime.withDayOfMonth(startTime.lengthOfMonth()); 获取当前月的最后一天的日期
- .plusMonths(1) 增加 月份
- .parse(dateString, formatter) 把有格式的字符串转 LocalDate
LocalDateTime 操作
-
.withYear(Integer.parseInt(year)) 年 .withMonth(Integer.parseInt(month)) 月 .withDayOfMonth(Integer.parseInt(day)); 日
-
.withHour(timeToSet.getHour()) 时
.withMinute(timeToSet.getMinute()) 分
.withSecond(timeToSet.getSecond()); 秒
.withNano(0); 纳秒 - LocalDateTime.parse(dateTimeString, formatter) 字符串转LocalDateTime
- .atZone() 设置 时区
- now() 现在的日期时间
- .atStartOfDay(ZoneId.systemDefault())
LocalTime 操作
- .now() 获取现在的时间
- .format(formatter); 获取格式时间字符串
YearMonth 年月 操作
-
YearMonth.from(localDateTime) 获取 LocalDateTime 的年月数据
- .atDay(1) 设置 天
- .atEndOfMonth() 月份的最后一天
- parse(dateString, formatter) 把有格式的字符串转 YearMonth
时分秒 操作
// 获取当前日期和时间
Calendar calendar = Calendar.getInstance();
// 设置时、分、秒
calendar.set(Calendar.HOUR_OF_DAY, 15); // 设置小时(24小时制)
calendar.set(Calendar.MINUTE, 30); // 设置分钟
calendar.set(Calendar.SECOND, 0);
// 转换为Date对象
Date date = calendar.getTime();
Date 操作
-
.getTime() 获取时间戳
-
Date.from() 其他日期对象转Date
-
时间格式控制
import java.text.SimpleDateFormat;Date startTime = new Date(); // 假设 startTime 是当前时间
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String formattedDate = sdf.format(startTime);
转换
- Date 转 LocalDate
// 将 Date 转 LocalDate
// 假设 startTime 是一个 Date 对象
LocalDate localDate = startTime.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
- Date 转 LocalDateTime
// 将 Date 转 LocalDateTime
// 假设 startTime 是一个 Date 对象
LocalDate localDate = startTime.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
- LocalDate 转 Date
// localDate 为LocalDate 对象
Date newStartTime = Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant());
- localDateTime 转 Date
// localDateTime 为LocalDateTime 对象
Date newStartTime = Date.from(Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
DateUtil
当月日期获取
// 当月的第一天
startTime = DateUtil.offsetDay(DateUtil.parse(time, "yyyy-MM"), 0);
// 获取 当月数据 最后一天
endTime = DateUtil.offsetDay(DateUtil.parse(time, "yyyy-MM"), -1);
- DateUtil.parse(time,"yyyy-MM") 字符串 转Date
- DateUtils.getNowDate() 获取现在的日期时间
TEST
依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
注解
@SpringBootTest(classes = BianQueIphmsApplication.class) @ExtendWith(SpringExtension.class)
获取对象的值和属性
Class<?> aClass = iphmsAnalysis.getClass();
Field[] declaredFields = aClass.getDeclaredFields();
for (Field declaredField : declaredFields)
{
declaredField.setAccessible(true);
// 属性名
String name = declaredField.getName();
System.out.println(name);
System.out.println(declaredField.getType());
try {
// 属性值
Object o = declaredField.get(iphmsAnalysis);
System.out.println(o);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
json 处理
JSON.parseArray(rangeName, String.class)
debug 开启
<logger name="com.bianque" level="debug" />




















