webhook通知
package global.exworth.fund.manage.openapi.partnerapi.webHook;
import org.springframework.http.HttpEntity;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
import java.util.Arrays;
import java.util.List;
@Component
public class WebhookService {
private RestTemplate restTemplate = new RestTemplate();
@Async
public void sendWebhookNotification(WebhookEvent event) {
List<String> webhookUrls = Arrays.asList("http://pro.exworth.localdev/api/thirdparty/easyeuro/webhook");
for (String url : webhookUrls) {
try {
HttpEntity<WebhookEvent> request = new HttpEntity<>(event);
restTemplate.postForEntity(url, request, String.class);
System.out.println("Webhook sent successfully!");
} catch (Exception e) {
System.err.println("Failed to send webhook: " + e.getMessage());
e.printStackTrace();
}
}
}
}
package global.exworth.fund.manage.openapi.partnerapi.webHook;
public class WebhookEvent {
private String eventType;
private Object data;
public WebhookEvent() {
}
public String getEventType() {
return eventType;
}
public void setEventType(String eventType) {
this.eventType = eventType;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
}
redistemplate为null
redis正常,调用为null 报空指针,原因是new出来的,需要使用SpringContext.getBean(StringRedisTemplate.class)即正常,可使用new,否者需要find这个实体,才能使用注入的方式
ddd领域防腐层设计
意思就是这个
ThirdPartSupporter
只针对excard这个领域,其他模块,例如market,需要校验第三方的参数,使用的就不是这个ThirdPartSupporter了,可能是ThirdPartSupporter_price这样
记一次mysql事务未提交导致的长时间获取不到锁,load不到数据
--1.不自动提交事务
set autocommit = 0;
select * from t_clearing_detail;
--2.这个时候去改表注释发现卡住,再去select,查不出来的数据(缺一不可,要先改表注释,再查数据)
--3.提交刚刚的事务,发现又可以改表注释,查询了
commit
前端传参不知道怎么传 用 postman
import com.google.gson.Gson;
import java.util.HashSet;
import java.util.Set;
public class Main {
public static void main(String[] args) {
Set<String> hashSet = new HashSet<>();
hashSet.add("value1");
hashSet.add("value2");
hashSet.add("value3");
Gson gson = new Gson();
String jsonString = gson.toJson(hashSet);
System.out.println(jsonString);
}
}
Java实体生成 需要sql语句
SELECT
CONCAT("/**\r","* ",REPLACE(a.COLUMN_COMMENT,"\n",""),"\r*/\r",'private ', (CASE
WHEN a.DATA_TYPE ='bigint' THEN 'Long '
WHEN a.DATA_TYPE ='decimal' THEN 'BigDecimal '
WHEN a.DATA_TYPE ='int' THEN 'Integer '
WHEN a.DATA_TYPE ='tinyint' THEN 'Integer '
WHEN a.DATA_TYPE ='varchar' THEN 'String '
WHEN a.DATA_TYPE= 'timeStamp' THEN 'Date '
WHEN a.DATA_TYPE= 'datetime' THEN 'Date '
WHEN a.DATA_TYPE= 'float' THEN 'Float '
WHEN a.DATA_TYPE= 'double' THEN 'Double '
else '请补充类型 '
END
),COLUMN_NAME ,";") COLUMN_NAME
FROM
information_schema.COLUMNS a
WHERE
table_name = '表名(改这里即可)'
)dd
SELECT
CONCAT("/**\r","* ",REPLACE(a.COLUMN_COMMENT,"\n",""),"\r*/\r private ",
(CASE
WHEN a.DATA_TYPE = 'bigint' THEN 'Long '
WHEN a.DATA_TYPE = 'decimal' THEN 'BigDecimal '
WHEN a.DATA_TYPE = 'int' THEN 'Integer '
WHEN a.DATA_TYPE = 'tinyint' THEN 'Integer '
WHEN a.DATA_TYPE = 'varchar' THEN 'String '
WHEN a.DATA_TYPE = 'timeStamp' THEN 'Date '
WHEN a.DATA_TYPE = 'datetime' THEN 'Date '
WHEN a.DATA_TYPE = 'float' THEN 'Float '
WHEN a.DATA_TYPE = 'double' THEN 'Double '
ELSE '请补充类型 '
END),
COLUMN_NAME ,";") COLUMN_NAME
FROM
information_schema.COLUMNS a
WHERE
table_name = '表名'
打成了jar包用 java -jar -Dfile.encoding=utf-8运行不管用 还是乱码
控制台先执行
chcp 65001
再运行jar包
theme: jzman
打印日志
log.info("relust结果:{}", JSON.toJSONString(result));
stream流
//归类
Map<String, List<ReleaseProjectDO>> collect = releaseProjectDOSList.stream().collect(Collectors.groupingBy(ReleaseProjectDO::getCpCode));
//从大到小排序
List sortVersion = releaseProjectDOList.stream().sorted(Comparator.comparingInt(ReleaseProjectDO::getVersion).reversed()).collect(Collectors.toList());
内存分页
List<ReleaseProjectDO> data = res.getData();
long page = Long.parseLong("1");
long size = Long.parseLong(String.valueOf(data.size()));
List<ReleaseProjectDO> subList = data.stream().skip((page-1)*size).limit(size).collect(Collectors.toList());
return ResponseResultUtil.success(size,subList);
//内存分页
List<ReleaseProjectDO> value = new ArrayList<ReleaseProjectDO>(map.values());
List<ReleaseProjectDO> subList = value.stream().skip((dto.getPage() - 1) * dto.getSize()).limit(dto.getSize()).collect(Collectors.toList());
return ResponseResultUtil.success(subList.size(),subList);
前端文本换行空格处理
String content = req.getContent().replaceAll("\\n", "<br/>").replace("\\t", " ");
map转对象
Map map = JSON.parseObject(JSON.toJSONString(data), Map.class);
Object rows = map.get("rows");
List<BdopScForm> bdopScFormList = JSON.parseArray(JSON.toJSONString(data), BdopScForm.class);
日期
System.out.println(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
利用反射给ArrayList添加String
public static void main(String[] args) throws Exception {
ArrayList<Integer> list = new ArrayList<Integer>();
list.add(1);
//这样调用 add 方法只能存储整形,因为泛型类型的实例为 Integer
//在程序中定义了一个ArrayList泛型类型实例化为Integer对象,如果直接调用add()方法,那么只能存储整数数据,不过当我们利用反射调用add()方法的时候,却可以存储字符串,这说明了Integer泛型实例在编译之后被擦除掉了,只保留了原始类型
list.getClass().getMethod("add", Object.class).invoke(list, "asd");
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
}
作者:ytKing
链接:https://juejin.cn/post/7131953899111448612
来源:稀土掘金
根据年月日返回date(生日)
Calendar calendar = Calendar.getInstance();
calendar.set(year, month, day);
return calendar.getTime();
}
不把本地服务注册到注册中心
-Dspring.cloud.nacos.discovery.register-enabled=false
-Deureka.client.register-with-eureka=false
各位本地使用 test 启动应用请加上这个参数(不把自己注册到注册中心),第一个是使用nacos做为注册中心,第二个是eureka的,已经有很多同学找,问为什么有些接口偶尔失败的,大部分都是这个原因,把自己本地的服务注册上去,导致网关请求不到
多数据源的方式
方法1:aop
spring.datasource.price.username = root
spring.datasource.price.password = 123
spring.datasource.price.driver-class-name = com.mysql.jdbc.Driver
spring.datasource.ware.url = jdbc:mysql://192.233.0.101:3303,192.233.0.102:4000/ware?useUnicode=true&characterEncoding=utf-8&useSSL=false&allowMultiQueries=true
spring.datasource.ware.username = root
spring.datasource.ware.password = 123
spring.datasource.ware.driver-class-name = com.mysql.jdbc.Driver
import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;
import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;
@Configuration
@Component
public class DynamicDataSourceConfig {
@Bean(name = "priceDataSource")
@ConfigurationProperties("spring.datasource.price")
public DataSource priceDataSource(){
return DruidDataSourceBuilder.create().build();
}
@Bean(name = "wareDataSource")
@ConfigurationProperties("spring.datasource.ware")
public DataSource wareDataSource(){
return DruidDataSourceBuilder.create().build();
}
@Bean
@Primary
public DynamicDataSource dataSource(DataSource priceDataSource, DataSource wareDataSource) {
Map<Object, Object> targetDataSources = new HashMap<>();
targetDataSources.put("priceDataSource",priceDataSource);
targetDataSources.put("wareDataSource", wareDataSource);
return new DynamicDataSource(priceDataSource, targetDataSources);
}
}
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
import javax.sql.DataSource;
import java.util.Map;
public class DynamicDataSource extends AbstractRoutingDataSource {
private static final ThreadLocal<String> contextHolder = new ThreadLocal<>();
public DynamicDataSource(DataSource defaultTargetDataSource, Map<Object, Object> targetDataSources) {
super.setDefaultTargetDataSource(defaultTargetDataSource);
super.setTargetDataSources(targetDataSources);
super.afterPropertiesSet();
}
@Override
protected Object determineCurrentLookupKey() {
return getDataSource();
}
public static void setDataSource(String dataSource) {
contextHolder.set(dataSource);
}
public static String getDataSource() {
return contextHolder.get();
}
public static void clearDataSource() {
contextHolder.remove();
}
}
import cn.hutool.core.util.ObjectUtil;
import com.hydee.h3.devopstask.annotation.DataSource;
import com.hydee.h3.devopstask.config.DynamicDataSource;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;
@Aspect
@Component
public class DataSourceAspect {
@Pointcut("@annotation(com.hydee.h3.devopstask.annotation.DataSource)")
public void dataSourcePointCut() {
}
@Around("dataSourcePointCut()")
public Object around(ProceedingJoinPoint point) throws Throwable {
MethodSignature signature = (MethodSignature) point.getSignature();
Method method = signature.getMethod();
DataSource dataSource = method.getAnnotation(DataSource.class);
if(ObjectUtil.isNull(dataSource)){
DynamicDataSource.setDataSource("priceDataSource");
}else {
DynamicDataSource.setDataSource(dataSource.name());
}
try {
return point.proceed();
} finally {
DynamicDataSource.clearDataSource();
}
}
}
import java.lang.annotation.*;
/**
* @description:
* @author: linqi 00118792
* @date: 2022/5/11 20:46
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DataSource {
String name() default "";
}
@DS()方式 方法简单 但是需要引入依赖
<groupId>com.baomidou</groupId>
<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
<version>3.5.1</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.26</version>
</dependency>
在实现类impl上添加@DS("ware") 不添加走默认配置
spring.datasource.dynamic.primary = price
spring.datasource.dynamic.strict = false
spring.datasource.dynamic.datasource.price.username =
spring.datasource.dynamic.datasource.price.password =
spring.datasource.dynamic.datasource.price.driver-class-name =
spring.datasource.dynamic.datasource.price.url =
spring.datasource.dynamic.datasource.ware.password =
spring.datasource.dynamic.datasource.ware.url =
spring.datasource.dynamic.datasource.ware.username =
spring.datasource.dynamic.datasource.ware.driver-class-name =