当前位置: 首页 > news >正文

java开发springoot

阅读理解

  • 命令之间空一行:表示前面的是配置 
  • 红色背景:表示待验证
  • 蓝色背景:表示常用或推荐
  • 绿色背景:注意/推荐

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

详细步骤 

  1. 官网地址:Jenkins
  2. 启动: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 {@Beanpublic 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: truesetting: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.DruidDataSourcedriver-class-name: com.mysql.jdbc.Driverjdbc-url: jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&failOverReadOnly=false&allowMultiQueries=true&serverTimezone=GMT%2B8&useSSL=falseusername: rootpassword: rootsecondary:type: com.alibaba.druid.pool.DruidDataSourcedriver-class-name: com.mysql.jdbc.Driverjdbc-url: jdbc:mysql://localhost:3306/test1?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&failOverReadOnly=false&allowMultiQueries=true&serverTimezone=GMT%2B8&useSSL=falseusername: rootpassword: 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")@Primarypublic 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;}@Beanpublic 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);
//    }@Beanpublic PlatformTransactionManager transactionManager(){return new DataSourceTransactionManager(dynamicDataSource());}@Beanpublic 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 {@Overrideprotected 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){//获得当前访问的classClass<?> 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 {@Beanpublic TaskScheduler taskScheduler() {ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();scheduler.setPoolSize(10); // 设置线程池大小scheduler.initialize();return scheduler;}
}

2.写异步类的@Async 异步方法

 @Asyncpublic 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 数据对象*/@Deprecatedpublic 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)

json转对象 

import com.alibaba.nacos.shaded.com.google.gson.Gson;
Gson gson = new Gson();
Test test= gson.fromJson(rawJson, Test.class);

debug 开启

<logger name="com.bianque" level="debug" /> 

AOP 

1.导包

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId>
</dependency>

 2.创建Aop 类

@Aspect
@Component
public class IphmsServiceBraceletRecordControllerAop {@Before("execution(* com.aa(..))")public void parseBraceletData1before(JoinPoint joinPoint) {System.out.println("parseBraceletData1before");}}
  •  路劲切入:execution()
    * com.aa(com.bb) 具体的某个方法
  • 注解切入:@annotation()

3启动类增加注解:@EnableAspectJAutoProxy 

http 数据获取 

@PostMapping("/test")
@ApiOperation(value = "test")
public AjaxResult<Boolean> Test(HttpServletRequest request) {
StringBuilder jsonBuilder = new StringBuilder();
try (BufferedReader reader = request.getReader()) {char[] buffer = new char[1024];int read;while ((read = reader.read(buffer, 0, buffer.length)) != -1) {jsonBuilder.append(buffer, 0, read);}
} catch (IOException e) {e.printStackTrace();
}
return jsonBuilder.toString();
}

正则 

  • Pattern.compile("正则表达式") 获取正则表达式对象
  • .matcher(string) 正则提取


http://www.mrgr.cn/news/83359.html

相关文章:

  • vue,router路由传值问题,引用官方推荐
  • 软件23种设计模式完整版[附Java版示例代码]
  • 【阅读笔记】消化内镜入门及规范操作
  • Meilisearch ASP.Net Core API 功能demo
  • 学习threejs,导入babylon格式的模型
  • Nginx | 解决 Spring Boot 与 Nginx 中的 “413 Request Entity Too Large“ 错误
  • 金融项目实战 02|接口测试分析、设计以及实现
  • 鼠标自动移动防止锁屏的办公神器 —— 定时执行专家
  • 【traefik】forwadAuth中间件跨namespace请求的问题
  • 【FPGA】时序约束与分析
  • 【git】-初始git
  • 【git】-2 分支管理
  • mysql-运维sql
  • 2025年第三届“华数杯”国际赛B题解题思路与代码(Matlab版)
  • 熵与交叉熵:从不确定性角度理解 KL 散度
  • win32汇编环境,窗口程序中对按钮控件常用操作的示例
  • 2025年第三届“华数杯”国际赛A题解题思路与代码(Python版)
  • linux RT-Preempt spin lock实现
  • TVbox 手机、智能电视节目一网打尽
  • 2025年第三届“华数杯”国际赛A题解题思路与代码(Matlab版)
  • Ubuntu | PostgreSQL | 解决 ERROR: `xmllint` is missing on your system.
  • 初学stm32 --- DAC模数转换器工作原理
  • 2025年第三届“华数杯”国际大学生数学建模竞赛A题完整论文讲解
  • 嵌入式C语言:二维数组
  • LeetCode 热题 100 | 哈希
  • C#从“Hello World!“开始