diff --git a/pom.xml b/pom.xml index 25656d8..2c42af3 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ org.springframework.boot spring-boot-starter-parent - 3.4.0 + 3.5.11 @@ -17,7 +17,7 @@ imyeyu.com API - 3.4.0 + 3.5.11 21 21 UTF-8 @@ -122,12 +122,12 @@ com.imyeyu.spring timi-spring - 0.0.2 + 0.0.9 com.imyeyu.network timi-network - 0.0.2 + 0.0.8 com.imyeyu.lang @@ -184,12 +184,12 @@ org.eclipse.jgit org.eclipse.jgit - 6.7.0.202309050840-r + 7.2.1.202505142326-r org.eclipse.jgit org.eclipse.jgit.archive - 6.7.0.202309050840-r + 7.2.1.202505142326-r org.apache.commons @@ -220,7 +220,7 @@ org.apache.tika tika-core - 2.9.2 + 3.2.2 org.jcodec diff --git a/src/main/java/com/imyeyu/api/bean/IOCBeans.java b/src/main/java/com/imyeyu/api/bean/IOCBeans.java deleted file mode 100644 index 6447e08..0000000 --- a/src/main/java/com/imyeyu/api/bean/IOCBeans.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.imyeyu.api.bean; - -import org.springframework.context.annotation.Bean; -import org.springframework.stereotype.Component; -import org.yaml.snakeyaml.Yaml; - -/** - * @author 夜雨 - * @since 2025-01-13 11:42 - */ -@Component -public class IOCBeans { - - @Bean - public Yaml yaml() { - return new Yaml(); - } -} diff --git a/src/main/java/com/imyeyu/api/config/BeanConfig.java b/src/main/java/com/imyeyu/api/config/BeanConfig.java index 4965856..b7f6a96 100644 --- a/src/main/java/com/imyeyu/api/config/BeanConfig.java +++ b/src/main/java/com/imyeyu/api/config/BeanConfig.java @@ -1,7 +1,12 @@ package com.imyeyu.api.config; -import com.google.gson.Gson; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.imyeyu.utils.Time; +import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.yaml.snakeyaml.Yaml; /** * @author 夜雨 @@ -10,7 +15,17 @@ import org.springframework.context.annotation.Configuration; @Configuration public class BeanConfig { - public Gson gson() { - return new Gson(); + @Bean + public ObjectMapper jackson() { + ObjectMapper mapper = new ObjectMapper(); + mapper.setDateFormat(Time.dateTime); + mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES); + mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); + return mapper; + } + + @Bean + public Yaml yaml() { + return new Yaml(); } } diff --git a/src/main/java/com/imyeyu/api/config/RedisConfig.java b/src/main/java/com/imyeyu/api/config/RedisConfig.java index ec69cbf..4efa999 100644 --- a/src/main/java/com/imyeyu/api/config/RedisConfig.java +++ b/src/main/java/com/imyeyu/api/config/RedisConfig.java @@ -6,6 +6,7 @@ import com.imyeyu.spring.bean.RedisConfigParams; import com.imyeyu.spring.config.AbstractRedisConfig; import com.imyeyu.spring.util.Redis; import com.imyeyu.spring.util.RedisSerializers; +import io.lettuce.core.api.StatefulConnection; import lombok.Data; import lombok.EqualsAndHashCode; import org.apache.commons.pool2.impl.GenericObjectPoolConfig; @@ -155,12 +156,13 @@ public class RedisConfig extends AbstractRedisConfig { /** @return 连接池配置 */ @Bean @Override - public GenericObjectPoolConfig getPoolConfig() { - GenericObjectPoolConfig config = new GenericObjectPoolConfig<>(); - config.setMaxTotal(lettuce.pool.maxActive); - config.setMinIdle(lettuce.pool.minIdle); - config.setMaxIdle(lettuce.pool.maxIdle); - config.setMaxWait(Duration.ofMillis(lettuce.pool.maxWait)); + public GenericObjectPoolConfig> getPoolConfig() { + RedisConfigParams configArgs = configParams(); + GenericObjectPoolConfig> config = new GenericObjectPoolConfig<>(); + config.setMaxTotal(8); + config.setMinIdle(configArgs.getMinIdle()); + config.setMaxIdle(configArgs.getMaxIdle()); + config.setMaxWait(Duration.ofMillis(-1)); return config; } @@ -224,7 +226,7 @@ public class RedisConfig extends AbstractRedisConfig { /** @return 文章访问统计,文章 ID: {@link ArticleRanking}(JSON) */ @Bean("redisArticleRanking") public Redis getArticleRankingRedisTemplate() { - return getRedis(database.articleRanking, RedisSerializers.LONG, RedisSerializers.gsonSerializer(ArticleRanking.class)); + return getRedis(database.articleRanking, RedisSerializers.LONG, RedisSerializers.jacksonSerializer(ArticleRanking.class)); } /** @return 文章访问记录,IP: [文章 ID] */ diff --git a/src/main/java/com/imyeyu/api/config/WebConfig.java b/src/main/java/com/imyeyu/api/config/WebConfig.java index 0fcf267..9b35628 100644 --- a/src/main/java/com/imyeyu/api/config/WebConfig.java +++ b/src/main/java/com/imyeyu/api/config/WebConfig.java @@ -1,32 +1,28 @@ package com.imyeyu.api.config; -import com.google.gson.GsonBuilder; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.MapperFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.json.JsonMapper; import com.imyeyu.api.annotation.EnableSettingInterceptor; import com.imyeyu.api.annotation.RequestRateLimitInterceptor; import com.imyeyu.api.annotation.RequiredTokenInterceptor; -import com.imyeyu.api.modules.common.entity.Attachment; -import com.imyeyu.api.modules.common.vo.user.UserProfileView; -import com.imyeyu.api.modules.common.vo.user.UserView; import com.imyeyu.api.modules.journal.util.JournalAPIInterceptor; import com.imyeyu.api.modules.minecraft.annotation.RequiredFMCServerTokenInterceptor; -import com.imyeyu.api.modules.minecraft.entity.MinecraftPlayer; -import com.imyeyu.api.modules.mirror.vo.MirrorView; import com.imyeyu.api.modules.system.util.SystemAPIInterceptor; -import com.imyeyu.api.util.GsonSerializerAdapter; -import com.imyeyu.spring.annotation.RequestSingleParamResolver; -import jakarta.validation.constraints.NotNull; -import lombok.NonNull; +import com.imyeyu.spring.annotation.RequestBodyValueArgumentResolver; +import com.imyeyu.utils.Time; import lombok.RequiredArgsConstructor; import org.springframework.context.annotation.Configuration; import org.springframework.http.converter.HttpMessageConverter; -import org.springframework.http.converter.json.GsonHttpMessageConverter; +import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; import org.springframework.web.method.support.HandlerMethodArgumentResolver; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; -import java.io.Writer; -import java.lang.reflect.Type; +import java.nio.charset.StandardCharsets; import java.util.List; /** @@ -40,12 +36,11 @@ import java.util.List; @RequiredArgsConstructor public class WebConfig implements WebMvcConfigurer { + private final ObjectMapper jackson; private final SystemAPIInterceptor systemAPIInterceptor; - private final GsonSerializerAdapter gsonSerializerAdapter; private final JournalAPIInterceptor journalAPIInterceptor; private final RequiredTokenInterceptor requiredTokenInterceptor; private final EnableSettingInterceptor enableSettingInterceptor; - private final RequestSingleParamResolver requestSingleParamResolver; private final RequestRateLimitInterceptor requestRateLimitInterceptor; private final RequiredFMCServerTokenInterceptor requiredFMCServerTokenInterceptor; @@ -66,7 +61,7 @@ public class WebConfig implements WebMvcConfigurer { @Override public void addArgumentResolvers(List argumentResolvers) { - argumentResolvers.add(requestSingleParamResolver); + argumentResolvers.add(new RequestBodyValueArgumentResolver(jackson)); } /** @@ -76,22 +71,17 @@ public class WebConfig implements WebMvcConfigurer { */ @Override public void configureMessageConverters(List> converters) { - GsonHttpMessageConverter converter = new GsonHttpMessageConverter() { - - @Override - protected void writeInternal(@NotNull Object object, Type type, @NonNull Writer writer) { - // 忽略参数类型,因为接口返回对象会被全局返回处理器包装为 TimiResponse,否则会序列化转型错误 - getGson().toJson(object, writer); - } - }; - - GsonBuilder builder = new GsonBuilder(); - builder.registerTypeAdapter(Attachment.class, gsonSerializerAdapter); - builder.registerTypeAdapter(UserView.class, gsonSerializerAdapter); - builder.registerTypeAdapter(MirrorView.class, gsonSerializerAdapter); - builder.registerTypeAdapter(UserProfileView.class, gsonSerializerAdapter); - builder.registerTypeAdapter(MinecraftPlayer.class, gsonSerializerAdapter); - converter.setGson(builder.create()); + JsonMapper jsonMapper = JsonMapper.builder() + // 设置默认属性包含规则:忽略 null 值 + .serializationInclusion(JsonInclude.Include.NON_NULL) + // 日期格式化 + .defaultDateFormat(Time.dateTime) + // 忽略不存在字段 + .disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES) + // 启用默认视图包含 + .enable(MapperFeature.DEFAULT_VIEW_INCLUSION).build(); + MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(jsonMapper); + converter.setDefaultCharset(StandardCharsets.UTF_8); converters.add(converter); } } diff --git a/src/main/java/com/imyeyu/api/modules/bill/controller/BillController.java b/src/main/java/com/imyeyu/api/modules/bill/controller/BillController.java deleted file mode 100644 index d324d04..0000000 --- a/src/main/java/com/imyeyu/api/modules/bill/controller/BillController.java +++ /dev/null @@ -1,49 +0,0 @@ -package com.imyeyu.api.modules.bill.controller; - -import jakarta.validation.Valid; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import com.imyeyu.java.bean.timi.TimiCode; -import com.imyeyu.java.bean.timi.TimiException; -import com.imyeyu.api.modules.bill.entity.Bill; -import com.imyeyu.api.modules.bill.service.BillService; -import com.imyeyu.api.modules.common.bean.SettingKey; -import com.imyeyu.api.modules.common.service.SettingService; -import com.imyeyu.spring.TimiSpring; -import com.imyeyu.spring.annotation.AOPLog; -import com.imyeyu.spring.annotation.RequestRateLimit; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -/** - * 收支帐单接口 - * - * @author 夜雨 - * @since 2023-02-04 01:02 - */ -@Slf4j -@RestController -@RequiredArgsConstructor -@RequestMapping("/bill") -public class BillController { - - private final BillService service; - private final SettingService settingService; - - /** - * 创建收支帐单 - * - * @param bill 账单 - */ - @AOPLog - @RequestRateLimit - @PostMapping("/create") - public void createREBill(@Valid @RequestBody Bill bill) { - if (!settingService.getAsString(SettingKey.BILL_API_TOKEN).equals(TimiSpring.getToken())) { - throw new TimiException(TimiCode.REQUEST_BAD).msgKey("token.illegal"); - } - service.create(bill); - } -} diff --git a/src/main/java/com/imyeyu/api/modules/bill/entity/Bill.java b/src/main/java/com/imyeyu/api/modules/bill/entity/Bill.java deleted file mode 100644 index 3769ecd..0000000 --- a/src/main/java/com/imyeyu/api/modules/bill/entity/Bill.java +++ /dev/null @@ -1,120 +0,0 @@ -package com.imyeyu.api.modules.bill.entity; - -import jakarta.validation.constraints.DecimalMin; -import jakarta.validation.constraints.NotBlank; -import jakarta.validation.constraints.NotNull; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.Getter; -import com.imyeyu.spring.entity.Entity; - -/** - * 收支账单 - * - * @author 夜雨 - * @since 2022-03-29 11:28 - */ -@Data -@EqualsAndHashCode(callSuper = true) -public class Bill extends Entity { - - /** - * 类型 - * - * @author 夜雨 - * @since 2022-03-29 11:28 - */ - @Getter - public enum Type { - - /** 收入 */ - REVENUE, - - /** 支出 */ - EXPENDITURE - } - - /** - * 收入类型 - * - * @author 夜雨 - * @since 2022-03-29 11:28 - */ - @Getter - public enum RevenueType { - - /** 工作 */ - WORK, - - /** 退款 */ - REFUND, - - /** 其他 */ - OTHER - } - - /** - * 支出类型 - * - * @author 夜雨 - * @since 2022-03-29 11:28 - */ - @Getter - public enum ExpenditureType { - - /** 饮食 */ - FOOD, - - /** 生活 */ - LIFE, - - /** 通信 */ - COMMUNICATION, - - /** 交通 */ - TRAFFIC, - - /** 娱乐 */ - GAME, - - /** 工作 */ - WORK, - - /** 服饰 */ - CLOTHES, - - /** 医疗 */ - HEALTH, - - /** 其他 */ - OTHER - } - - /** 收入类型 */ - private RevenueType revenueType; - - /** 支出类型 */ - private ExpenditureType expenditureType; - - /** 描述 */ - @NotBlank(message = "bill.description.empty") - private String description; - - /** 金额(未确保计算精度,放大了 100 倍) */ - @NotNull(message = "bill.decimal.empty") - @DecimalMin(value = "0", message = "bill.decimal.limit") - private Long decimal; - - /** 备注 */ - private String remarks; - - /** @return true 为收入账单 */ - public boolean isRevenue() { - return revenueType != null; - } - - /** @return true 为支出账单 */ - public boolean isExpenditure() { - return expenditureType != null; - } -} diff --git a/src/main/java/com/imyeyu/api/modules/bill/mapper/BillMapper.java b/src/main/java/com/imyeyu/api/modules/bill/mapper/BillMapper.java deleted file mode 100644 index 780f9ca..0000000 --- a/src/main/java/com/imyeyu/api/modules/bill/mapper/BillMapper.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.imyeyu.api.modules.bill.mapper; - -import com.imyeyu.api.modules.bill.entity.Bill; -import com.imyeyu.spring.mapper.BaseMapper; - -/** - * 收支帐单表 - * - * @author 夜雨 - * @since 2022-04-01 16:26 - */ -public interface BillMapper extends BaseMapper { -} diff --git a/src/main/java/com/imyeyu/api/modules/bill/service/BillService.java b/src/main/java/com/imyeyu/api/modules/bill/service/BillService.java deleted file mode 100644 index 887ca96..0000000 --- a/src/main/java/com/imyeyu/api/modules/bill/service/BillService.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.imyeyu.api.modules.bill.service; - -import com.imyeyu.api.modules.bill.entity.Bill; -import com.imyeyu.spring.service.CreatableService; - -/** - * 收支帐单服务 - * - * @author 夜雨 - * @since 2022-04-01 16:24 - */ -public interface BillService extends CreatableService { -} diff --git a/src/main/java/com/imyeyu/api/modules/bill/service/implement/BillServiceImplement.java b/src/main/java/com/imyeyu/api/modules/bill/service/implement/BillServiceImplement.java deleted file mode 100644 index ce1af39..0000000 --- a/src/main/java/com/imyeyu/api/modules/bill/service/implement/BillServiceImplement.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.imyeyu.api.modules.bill.service.implement; - -import com.imyeyu.api.modules.bill.entity.Bill; -import com.imyeyu.api.modules.bill.mapper.BillMapper; -import com.imyeyu.api.modules.bill.service.BillService; -import com.imyeyu.spring.mapper.BaseMapper; -import com.imyeyu.spring.service.AbstractEntityService; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Service; - -/** - * 收支账单服务 - * - * @author 夜雨 - * @since 2022-04-01 16:25 - */ -@Service -@RequiredArgsConstructor -public class BillServiceImplement extends AbstractEntityService implements BillService { - - private final BillMapper mapper; - - @Override - protected BaseMapper mapper() { - return mapper; - } -} diff --git a/src/main/java/com/imyeyu/api/modules/blog/entity/Article.java b/src/main/java/com/imyeyu/api/modules/blog/entity/Article.java index 77f15df..d47ba6c 100644 --- a/src/main/java/com/imyeyu/api/modules/blog/entity/Article.java +++ b/src/main/java/com/imyeyu/api/modules/blog/entity/Article.java @@ -1,6 +1,6 @@ package com.imyeyu.api.modules.blog.entity; -import com.google.gson.JsonElement; +import com.fasterxml.jackson.databind.JsonNode; import com.imyeyu.api.modules.common.bean.CommentSupport; import com.imyeyu.spring.entity.Destroyable; import com.imyeyu.spring.entity.Entity; @@ -48,7 +48,7 @@ public class Article extends Entity implements CommentSupport, Destroyable { protected String data; /** 扩展数据 */ - protected JsonElement extendData; + protected JsonNode extendData; /** 阅读数量 */ protected int reads; diff --git a/src/main/java/com/imyeyu/api/modules/common/controller/CommonController.java b/src/main/java/com/imyeyu/api/modules/common/controller/CommonController.java index 416bc2d..526d22e 100644 --- a/src/main/java/com/imyeyu/api/modules/common/controller/CommonController.java +++ b/src/main/java/com/imyeyu/api/modules/common/controller/CommonController.java @@ -1,7 +1,7 @@ package com.imyeyu.api.modules.common.controller; -import com.google.gson.Gson; -import com.google.gson.reflect.TypeToken; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; import com.imyeyu.api.bean.CaptchaFrom; import com.imyeyu.api.modules.common.bean.ImageType; import com.imyeyu.api.modules.common.bean.SettingKey; @@ -95,12 +95,28 @@ public class CommonController { private final AttachmentService attachmentService; private final ClipboardService clipboardService; - private final Gson gson; + private final ObjectMapper jackson; private final Yaml yaml; private final GridFSBucket gridFSBucket; private final CaptchaManager captchaManager; private final ResourceHandler resourceHandler; + private String writeJson(Object value) { + try { + return jackson.writeValueAsString(value); + } catch (IOException e) { + throw new TimiException(TimiCode.ERROR, "write json error", e); + } + } + + private Map readJsonMap(String value) { + try { + return jackson.readValue(value, new TypeReference<>() {}); + } catch (IOException e) { + throw new TimiException(TimiCode.ERROR, "read json error", e); + } + } + @AOPLog @RequestMapping("") public String root() { @@ -253,12 +269,12 @@ public class CommonController { case JSON -> { if (setting.getType() == Setting.Type.YAML) { Map obj = yaml.load(setting.getValue()); - result = gson.toJson(obj); + result = writeJson(obj); } } case YAML -> { if (setting.getType() == Setting.Type.JSON) { - Map obj = gson.fromJson(setting.getValue(), new TypeToken>() {}.getType()); + Map obj = readJsonMap(setting.getValue()); result = yaml.dump(obj); } } @@ -284,12 +300,12 @@ public class CommonController { case JSON -> { if (setting.getType() == Setting.Type.YAML) { Map obj = new Yaml().load(setting.getValue()); - setting.setValue(gson.toJson(obj)); + setting.setValue(writeJson(obj)); } } case YAML -> { if (setting.getType() == Setting.Type.JSON) { - Map obj = gson.fromJson(setting.getValue(), new TypeToken>() {}.getType()); + Map obj = readJsonMap(setting.getValue()); setting.setValue(new Yaml().dump(obj)); } } @@ -483,7 +499,7 @@ public class CommonController { GridFSFile file = attachmentService.readByMongoId(mongoId); @Cleanup GridFSDownloadStream downloadStream = gridFSBucket.openDownloadStream(file.getObjectId()); - RequestRange range = TimiSpring.requestRange(attach.getSize()); + RequestRange range = TimiSpring.getRequestRange(attach.getSize()); if (range == null) { // 完整文件 resp.setContentLengthLong(attach.getSize()); diff --git a/src/main/java/com/imyeyu/api/modules/common/controller/UserController.java b/src/main/java/com/imyeyu/api/modules/common/controller/UserController.java index 95f0808..d7bb4e8 100644 --- a/src/main/java/com/imyeyu/api/modules/common/controller/UserController.java +++ b/src/main/java/com/imyeyu/api/modules/common/controller/UserController.java @@ -26,7 +26,6 @@ import com.imyeyu.java.TimiJava; import com.imyeyu.java.bean.timi.TimiException; import com.imyeyu.spring.annotation.AOPLog; import com.imyeyu.spring.annotation.RequestRateLimit; -import com.imyeyu.spring.annotation.RequestSingleParam; import com.imyeyu.spring.annotation.RequiredToken; import com.imyeyu.spring.bean.CaptchaData; import com.imyeyu.spring.bean.Page; @@ -184,7 +183,7 @@ public class UserController implements TimiJava { @RequiredToken @RequestRateLimit @PostMapping("/cancel") - public void cancel(@RequestSingleParam String password) { + public void cancel(@RequestBody String password) { service.cancel(password); } @@ -275,7 +274,7 @@ public class UserController implements TimiJava { @RequiredToken @RequestRateLimit @PostMapping("/comment/delete") - public void deleteComment(@RequestSingleParam Long commentId) { + public void deleteComment(@RequestBody Long commentId) { commentService.get(commentId); commentService.delete(commentId); } @@ -298,7 +297,7 @@ public class UserController implements TimiJava { @RequiredToken @RequestRateLimit @PostMapping("/comment/reply/delete") - public void deleteCommentReply(@RequestSingleParam Long replyId) { + public void deleteCommentReply(@RequestBody Long replyId) { CommentReply reply = commentReplyService.get(replyId); TimiException.requiredTrue(reply.getSenderId().equals(service.getLoginUser().getId()), "user.comment.reply.delete.not_owner"); commentReplyService.delete(replyId); @@ -308,7 +307,7 @@ public class UserController implements TimiJava { @RequiredToken @RequestRateLimit @PostMapping("/comment/reply/ignore") - public void ignoreCommentReply(@RequestSingleParam Long replyId) { + public void ignoreCommentReply(@RequestBody Long replyId) { CommentReply reply = commentReplyService.get(replyId); TimiException.requiredTrue(reply.getReceiverId().equals(service.getLoginUser().getId()), "user.comment.reply.ignore.not_owner"); reply.setIgnoredAt(Time.now()); diff --git a/src/main/java/com/imyeyu/api/modules/common/entity/Attachment.java b/src/main/java/com/imyeyu/api/modules/common/entity/Attachment.java index cfe8c0e..470c6e5 100644 --- a/src/main/java/com/imyeyu/api/modules/common/entity/Attachment.java +++ b/src/main/java/com/imyeyu/api/modules/common/entity/Attachment.java @@ -1,6 +1,6 @@ package com.imyeyu.api.modules.common.entity; -import com.google.gson.JsonObject; +import com.fasterxml.jackson.databind.JsonNode; import com.imyeyu.api.TimiServerAPI; import com.imyeyu.api.bean.MultilingualHandler; import com.imyeyu.api.modules.common.service.AttachmentService; @@ -81,7 +81,7 @@ public class Attachment extends Entity implements MultilingualHandler { protected String mimeType; - protected JsonObject metadata; + protected JsonNode metadata; protected Long size; diff --git a/src/main/java/com/imyeyu/api/modules/common/service/SettingService.java b/src/main/java/com/imyeyu/api/modules/common/service/SettingService.java index ebbc417..8efc9dc 100644 --- a/src/main/java/com/imyeyu/api/modules/common/service/SettingService.java +++ b/src/main/java/com/imyeyu/api/modules/common/service/SettingService.java @@ -1,9 +1,9 @@ package com.imyeyu.api.modules.common.service; -import com.google.gson.JsonArray; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.reflect.TypeToken; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.node.ArrayNode; +import com.fasterxml.jackson.databind.node.ObjectNode; import com.imyeyu.api.modules.common.bean.SettingKey; import com.imyeyu.api.modules.common.entity.Setting; import com.imyeyu.java.bean.timi.TimiException; @@ -60,15 +60,15 @@ public interface SettingService extends UpdatableService { */ boolean not(SettingKey key); - JsonElement getAsJsonElement(SettingKey key); + JsonNode getAsJsonNode(SettingKey key); - JsonObject getAsJsonObject(SettingKey key); + ObjectNode getAsJsonObject(SettingKey key); - JsonArray getAsJsonArray(SettingKey key); + ArrayNode getAsArrayNode(SettingKey key); T fromJson(SettingKey key, Class clazz); - T fromJson(SettingKey key, TypeToken typeToken); + T fromJson(SettingKey key, TypeReference typeReference); T fromYaml(SettingKey key, Class clazz); diff --git a/src/main/java/com/imyeyu/api/modules/common/service/implement/AttachmentServiceImplement.java b/src/main/java/com/imyeyu/api/modules/common/service/implement/AttachmentServiceImplement.java index 701efa0..87294e1 100644 --- a/src/main/java/com/imyeyu/api/modules/common/service/implement/AttachmentServiceImplement.java +++ b/src/main/java/com/imyeyu/api/modules/common/service/implement/AttachmentServiceImplement.java @@ -1,7 +1,7 @@ package com.imyeyu.api.modules.common.service.implement; -import com.google.gson.Gson; -import com.google.gson.JsonObject; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ObjectNode; import com.imyeyu.api.config.dbsource.TimiServerDBConfig; import com.imyeyu.api.modules.common.bean.MediaAttach; import com.imyeyu.api.modules.common.bean.Metadata; @@ -55,7 +55,7 @@ public class AttachmentServiceImplement extends AbstractEntityService redisSetting; - private final Gson gson; + private final ObjectMapper jackson; @Override protected BaseMapper mapper() { @@ -59,7 +59,11 @@ public class SettingServiceImplement extends AbstractEntityService T fromJson(SettingKey key, Class clazz) { - return gson.fromJson(getAsJsonElement(key), clazz); + try { + return jackson.treeToValue(getAsJsonNode(key), clazz); + } catch (JsonProcessingException e) { + throw new TimiException(TimiCode.ERROR, "read setting json error", e); + } } @Override - public T fromJson(SettingKey key, TypeToken typeToken) { - return gson.fromJson(getAsJsonElement(key), typeToken); + public T fromJson(SettingKey key, TypeReference typeReference) { + return jackson.convertValue(getAsJsonNode(key), typeReference); } public T fromYaml(SettingKey key, Class clazz) { diff --git a/src/main/java/com/imyeyu/api/modules/common/service/implement/TempFileServiceImplement.java b/src/main/java/com/imyeyu/api/modules/common/service/implement/TempFileServiceImplement.java index ffccf8f..bd0db0d 100644 --- a/src/main/java/com/imyeyu/api/modules/common/service/implement/TempFileServiceImplement.java +++ b/src/main/java/com/imyeyu/api/modules/common/service/implement/TempFileServiceImplement.java @@ -1,6 +1,4 @@ package com.imyeyu.api.modules.common.service.implement; - -import com.google.gson.Gson; import com.imyeyu.api.modules.common.bean.SettingKey; import com.imyeyu.api.modules.common.entity.Attachment; import com.imyeyu.api.modules.common.service.AttachmentService; @@ -31,8 +29,6 @@ import java.util.List; @RequiredArgsConstructor public class TempFileServiceImplement implements TempFileService { - private final Gson gson; - private final SettingService settingService; private final AttachmentService attachmentService; diff --git a/src/main/java/com/imyeyu/api/modules/common/task/MultilingualTranslateTask.java b/src/main/java/com/imyeyu/api/modules/common/task/MultilingualTranslateTask.java index f494375..8c49fd0 100644 --- a/src/main/java/com/imyeyu/api/modules/common/task/MultilingualTranslateTask.java +++ b/src/main/java/com/imyeyu/api/modules/common/task/MultilingualTranslateTask.java @@ -1,8 +1,7 @@ package com.imyeyu.api.modules.common.task; -import com.google.gson.JsonArray; -import com.google.gson.JsonObject; -import com.google.gson.JsonParser; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; import com.imyeyu.api.config.dbsource.TimiServerDBConfig; import com.imyeyu.api.modules.common.bean.SettingKey; import com.imyeyu.api.modules.common.entity.Multilingual; @@ -81,6 +80,7 @@ public class MultilingualTranslateTask { } } + private final ObjectMapper jackson; private final SettingService settingService; private final MultilingualService service; @@ -147,18 +147,17 @@ public class MultilingualTranslateTask { .execute() .returnContent() .asString(); - JsonObject jo = JsonParser.parseString(response).getAsJsonObject(); + JsonNode jo = jackson.readTree(response); if (jo.has("error_code")) { System.err.println(jo); - throw new TimiException(TimiCode.ERROR, jo.get("error_msg").getAsString()); + throw new TimiException(TimiCode.ERROR, jo.get("error_msg").asText()); } - JsonArray ja = jo.get("trans_result").getAsJsonArray(); + JsonNode ja = jo.get("trans_result"); - JsonObject resultJO; Map result = new HashMap<>(); for (int i = 0; i < ja.size(); i++) { - resultJO = ja.get(i).getAsJsonObject(); - result.put(resultJO.get("src").getAsString(), resultJO.get("dst").getAsString()); + JsonNode resultJO = ja.get(i); + result.put(resultJO.get("src").asText(), resultJO.get("dst").asText()); } wait(200); return result; diff --git a/src/main/java/com/imyeyu/api/modules/git/bean/gitea/Branch.java b/src/main/java/com/imyeyu/api/modules/git/bean/gitea/Branch.java index e9228b8..04cd67a 100644 --- a/src/main/java/com/imyeyu/api/modules/git/bean/gitea/Branch.java +++ b/src/main/java/com/imyeyu/api/modules/git/bean/gitea/Branch.java @@ -1,6 +1,6 @@ package com.imyeyu.api.modules.git.bean.gitea; -import com.google.gson.annotations.SerializedName; +import com.fasterxml.jackson.annotation.JsonProperty; import lombok.Data; /** @@ -12,6 +12,6 @@ public class Branch { private String name; - @SerializedName("protected") + @JsonProperty("protected") private boolean isProtected; } diff --git a/src/main/java/com/imyeyu/api/modules/git/bean/gitea/File.java b/src/main/java/com/imyeyu/api/modules/git/bean/gitea/File.java index f149988..dedc107 100644 --- a/src/main/java/com/imyeyu/api/modules/git/bean/gitea/File.java +++ b/src/main/java/com/imyeyu/api/modules/git/bean/gitea/File.java @@ -1,6 +1,7 @@ package com.imyeyu.api.modules.git.bean.gitea; -import com.google.gson.annotations.JsonAdapter; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.imyeyu.api.modules.git.util.GiteaTimestampAdapter; import lombok.Data; @@ -36,6 +37,7 @@ public class File { private String lastCommitSha; - @JsonAdapter(GiteaTimestampAdapter.class) + @JsonSerialize(using = GiteaTimestampAdapter.Serializer.class) + @JsonDeserialize(using = GiteaTimestampAdapter.Deserializer.class) private Long lastCommitterDate; } diff --git a/src/main/java/com/imyeyu/api/modules/git/bean/gitea/Repository.java b/src/main/java/com/imyeyu/api/modules/git/bean/gitea/Repository.java index ed89606..051a523 100644 --- a/src/main/java/com/imyeyu/api/modules/git/bean/gitea/Repository.java +++ b/src/main/java/com/imyeyu/api/modules/git/bean/gitea/Repository.java @@ -1,6 +1,7 @@ package com.imyeyu.api.modules.git.bean.gitea; -import com.google.gson.annotations.JsonAdapter; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.imyeyu.api.modules.git.util.GiteaTimestampAdapter; import lombok.Data; @@ -35,13 +36,16 @@ public class Repository { private Boolean archived; - @JsonAdapter(GiteaTimestampAdapter.class) + @JsonSerialize(using = GiteaTimestampAdapter.Serializer.class) + @JsonDeserialize(using = GiteaTimestampAdapter.Deserializer.class) private Long createdAt; - @JsonAdapter(GiteaTimestampAdapter.class) + @JsonSerialize(using = GiteaTimestampAdapter.Serializer.class) + @JsonDeserialize(using = GiteaTimestampAdapter.Deserializer.class) private Long updatedAt; - @JsonAdapter(GiteaTimestampAdapter.class) + @JsonSerialize(using = GiteaTimestampAdapter.Serializer.class) + @JsonDeserialize(using = GiteaTimestampAdapter.Deserializer.class) private Long archivedAt; private List licenses; diff --git a/src/main/java/com/imyeyu/api/modules/git/service/implement/RepositoryServiceImplement.java b/src/main/java/com/imyeyu/api/modules/git/service/implement/RepositoryServiceImplement.java index d3d5c95..8d2740e 100644 --- a/src/main/java/com/imyeyu/api/modules/git/service/implement/RepositoryServiceImplement.java +++ b/src/main/java/com/imyeyu/api/modules/git/service/implement/RepositoryServiceImplement.java @@ -1,9 +1,8 @@ package com.imyeyu.api.modules.git.service.implement; -import com.google.gson.FieldNamingPolicy; -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.reflect.TypeToken; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.PropertyNamingStrategies; import com.imyeyu.java.TimiJava; import com.imyeyu.java.bean.timi.TimiCode; import com.imyeyu.java.bean.timi.TimiException; @@ -56,17 +55,18 @@ import java.util.List; @RequiredArgsConstructor public class RepositoryServiceImplement implements RepositoryService { - private final Gson gson = new GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES).create(); - private final UserService userService; private final GiteaService giteaService; private final SettingService settingService; + private final ObjectMapper jackson; private User owner; + private ObjectMapper giteaJackson; @PostConstruct private void postConstruct() { owner = giteaService.getOwner(); + giteaJackson = jackson.copy().setPropertyNamingStrategy(PropertyNamingStrategies.SNAKE_CASE); } @Override @@ -80,8 +80,7 @@ public class RepositoryServiceImplement implements RepositoryService { put("limit", page.getLimit()); }})).execute().returnResponse(); String respText = EntityUtils.toString(resp.getEntity()); - GiteaResponse> respObj = gson.fromJson(respText, new TypeToken>>() { - }.getType()); + GiteaResponse> respObj = giteaJackson.readValue(respText, new TypeReference<>() {}); PageResult result = new PageResult<>(); result.setTotal(Long.parseLong(resp.getHeader("X-Total-Count").getValue())); @@ -100,7 +99,7 @@ public class RepositoryServiceImplement implements RepositoryService { put("owner", owner.getName()); put("repoName", repoName); }})).execute().returnContent().asString(); - return gson.fromJson(respText, Repository.class); + return giteaJackson.readValue(respText, Repository.class); } catch (Exception e) { log.error("get repository error", e); throw new TimiException(TimiCode.ERROR, "get repository error", e); @@ -110,11 +109,11 @@ public class RepositoryServiceImplement implements RepositoryService { @Override public List listBranches(String repoName) { try { - String respText = Request.get(API.REPO_BRANCHES_LIST.buildURL(new HashMap<>() {{ + String respText = Request.get(API.REPO_BRANCHES_LIST.buildURL(new HashMap<>() {{ put("owner", owner.getName()); put("repoName", repoName); - }})).execute().returnContent().asString(); - return gson.fromJson(respText, new TypeToken>() {}.getType()); + }})).execute().returnContent().asString(); + return giteaJackson.readValue(respText, new TypeReference<>() {}); } catch (Exception e) { log.error("list repository branches error", e); throw new TimiException(TimiCode.ERROR, "list repository branches error", e); @@ -124,14 +123,14 @@ public class RepositoryServiceImplement implements RepositoryService { @Override public List listFile(String repoName, String branch, String path) { try { - String respText = Request.get(API.REPO_FILE_LIST.buildURL(new HashMap<>() {{ + String respText = Request.get(API.REPO_FILE_LIST.buildURL(new HashMap<>() {{ put("owner", owner.getName()); put("repoName", repoName); put("path", path); - }}, new HashMap<>() {{ + }}, new HashMap<>() {{ put("ref", branch); - }})).execute().returnContent().asString(); - List list = gson.fromJson(respText, new TypeToken>() {}.getType()); + }})).execute().returnContent().asString(); + List list = giteaJackson.readValue(respText, new TypeReference<>() {}); // 排序 list.sort((f1, f2) -> { if (f1.getType() == File.Type.dir && f2.getType() == File.Type.file) { diff --git a/src/main/java/com/imyeyu/api/modules/git/util/GiteaTimestampAdapter.java b/src/main/java/com/imyeyu/api/modules/git/util/GiteaTimestampAdapter.java index c92fa2d..2fd1827 100644 --- a/src/main/java/com/imyeyu/api/modules/git/util/GiteaTimestampAdapter.java +++ b/src/main/java/com/imyeyu/api/modules/git/util/GiteaTimestampAdapter.java @@ -1,28 +1,54 @@ package com.imyeyu.api.modules.git.util; -import com.google.gson.JsonDeserializationContext; -import com.google.gson.JsonDeserializer; -import com.google.gson.JsonElement; -import com.google.gson.JsonPrimitive; -import com.google.gson.JsonSerializationContext; -import com.google.gson.JsonSerializer; +import com.fasterxml.jackson.core.JacksonException; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; -import java.lang.reflect.Type; +import java.io.IOException; import java.time.Instant; /** * @author 夜雨 * @since 2025-06-26 11:40 */ -public class GiteaTimestampAdapter implements JsonSerializer, JsonDeserializer { +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public final class GiteaTimestampAdapter { - @Override - public Long deserialize(JsonElement json, Type type, JsonDeserializationContext context) { - return Instant.parse(json.getAsString()).toEpochMilli(); + /** + * + * + * @author 夜雨 + * @since 2026-04-07 22:16 + */ + public static class Serializer extends JsonSerializer { + + @Override + public void serialize(Long value, JsonGenerator gen, SerializerProvider serializers) throws IOException { + if (value == null) { + gen.writeNull(); + } else { + gen.writeNumber(value); + } + } } - @Override - public JsonElement serialize(Long src, Type type, JsonSerializationContext context) { - return new JsonPrimitive(src); + /** + * + * + * @author 夜雨 + * @since 2026-04-07 22:19 + */ + public static class Deserializer extends JsonDeserializer { + + @Override + public Long deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JacksonException { + return Instant.parse(p.getText()).toEpochMilli(); + } } } diff --git a/src/main/java/com/imyeyu/api/modules/gitea/bean/ActionLogDTO.java b/src/main/java/com/imyeyu/api/modules/gitea/bean/ActionLogDTO.java index c06a8d0..a6dfe8e 100644 --- a/src/main/java/com/imyeyu/api/modules/gitea/bean/ActionLogDTO.java +++ b/src/main/java/com/imyeyu/api/modules/gitea/bean/ActionLogDTO.java @@ -1,7 +1,8 @@ package com.imyeyu.api.modules.gitea.bean; -import com.google.gson.annotations.JsonAdapter; -import com.google.gson.annotations.SerializedName; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.imyeyu.api.modules.gitea.util.GiteaUTCTimestampAdapter; import lombok.AllArgsConstructor; import lombok.Data; @@ -50,14 +51,15 @@ public class ActionLogDTO { @Data public static class Commit { - @SerializedName("Sha1") + @JsonProperty("Sha1") private String sha; - @SerializedName("Message") + @JsonProperty("Message") private String message; - @JsonAdapter(GiteaUTCTimestampAdapter.class) - @SerializedName("Timestamp") + @JsonProperty("Timestamp") + @JsonSerialize(using = GiteaUTCTimestampAdapter.Serializer.class) + @JsonDeserialize(using = GiteaUTCTimestampAdapter.Deserializer.class) private Long timestamp; } } diff --git a/src/main/java/com/imyeyu/api/modules/gitea/util/GiteaUTCTimestampAdapter.java b/src/main/java/com/imyeyu/api/modules/gitea/util/GiteaUTCTimestampAdapter.java index a0f14ca..3605ba6 100644 --- a/src/main/java/com/imyeyu/api/modules/gitea/util/GiteaUTCTimestampAdapter.java +++ b/src/main/java/com/imyeyu/api/modules/gitea/util/GiteaUTCTimestampAdapter.java @@ -1,13 +1,14 @@ package com.imyeyu.api.modules.gitea.util; -import com.google.gson.JsonDeserializationContext; -import com.google.gson.JsonDeserializer; -import com.google.gson.JsonElement; -import com.google.gson.JsonPrimitive; -import com.google.gson.JsonSerializationContext; -import com.google.gson.JsonSerializer; +import com.fasterxml.jackson.core.JacksonException; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; -import java.lang.reflect.Type; +import java.io.IOException; import java.time.Instant; import java.time.OffsetDateTime; import java.time.ZoneOffset; @@ -18,15 +19,21 @@ import java.time.ZoneOffset; * @author 夜雨 * @since 2025-06-27 16:18 */ -public class GiteaUTCTimestampAdapter implements JsonDeserializer, JsonSerializer { +public class GiteaUTCTimestampAdapter { - @Override - public Long deserialize(JsonElement json, Type type, JsonDeserializationContext context) { - return OffsetDateTime.parse(json.getAsString()).toInstant().toEpochMilli(); + public static class Deserializer extends JsonDeserializer { + + @Override + public Long deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JacksonException { + return OffsetDateTime.parse(p.getText()).toInstant().toEpochMilli(); + } } - @Override - public JsonElement serialize(Long timestamp, Type type, JsonSerializationContext context) { - return new JsonPrimitive(OffsetDateTime.ofInstant(Instant.ofEpochMilli(timestamp), ZoneOffset.UTC).toString()); + public static class Serializer extends JsonSerializer { + + @Override + public void serialize(Long timestamp, JsonGenerator gen, SerializerProvider serializers) throws IOException { + gen.writeString(OffsetDateTime.ofInstant(Instant.ofEpochMilli(timestamp), ZoneOffset.UTC).toString()); + } } } diff --git a/src/main/java/com/imyeyu/api/modules/gitea/vo/ActionLogView.java b/src/main/java/com/imyeyu/api/modules/gitea/vo/ActionLogView.java index 299ce3c..3ef1155 100644 --- a/src/main/java/com/imyeyu/api/modules/gitea/vo/ActionLogView.java +++ b/src/main/java/com/imyeyu/api/modules/gitea/vo/ActionLogView.java @@ -1,9 +1,8 @@ package com.imyeyu.api.modules.gitea.vo; -import com.google.gson.Gson; -import com.google.gson.JsonObject; -import com.google.gson.JsonParser; -import com.google.gson.reflect.TypeToken; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; import com.imyeyu.java.TimiJava; import com.imyeyu.api.TimiServerAPI; import com.imyeyu.api.modules.common.service.UserService; @@ -34,7 +33,7 @@ public class ActionLogView { private UserView operator; public static ActionLogView fromDTO(ActionLogDTO dto) { - Gson gson = TimiServerAPI.applicationContext.getBean(Gson.class); + ObjectMapper jackson = TimiServerAPI.applicationContext.getBean(ObjectMapper.class); UserService userService = TimiServerAPI.applicationContext.getBean(UserService.class); ActionLogView view = new ActionLogView(); @@ -45,15 +44,19 @@ public class ActionLogView { view.setOperator(userService.view((long) dto.getOperatorId()).doFilter()); { if (TimiJava.isNotEmpty(dto.getContent())) { - JsonObject content = JsonParser.parseString(dto.getContent()).getAsJsonObject(); - List commitList = gson.fromJson(content.get("Commits"), new TypeToken>() {}.getType()); - view.setCommitList(new ArrayList<>()); - for (ActionLogDTO.Commit dtoCommit : commitList) { - Commit commit = new Commit(); - commit.setSha(dtoCommit.getSha()); - commit.setMessage(dtoCommit.getMessage().trim()); - commit.setCommittedAt(dtoCommit.getTimestamp()); - view.getCommitList().add(commit); + try { + JsonNode content = jackson.readTree(dto.getContent()); + List commitList = jackson.convertValue(content.get("Commits"), new TypeReference<>() {}); + view.setCommitList(new ArrayList<>()); + for (ActionLogDTO.Commit dtoCommit : commitList) { + Commit commit = new Commit(); + commit.setSha(dtoCommit.getSha()); + commit.setMessage(dtoCommit.getMessage().trim()); + commit.setCommittedAt(dtoCommit.getTimestamp()); + view.getCommitList().add(commit); + } + } catch (Exception e) { + throw new IllegalStateException("read gitea action log content error", e); } } } @@ -75,4 +78,4 @@ public class ActionLogView { private Long committedAt; } -} \ No newline at end of file +} diff --git a/src/main/java/com/imyeyu/api/modules/journal/controller/JournalController.java b/src/main/java/com/imyeyu/api/modules/journal/controller/JournalController.java index 57166bc..f8746a5 100644 --- a/src/main/java/com/imyeyu/api/modules/journal/controller/JournalController.java +++ b/src/main/java/com/imyeyu/api/modules/journal/controller/JournalController.java @@ -1,5 +1,6 @@ package com.imyeyu.api.modules.journal.controller; +import com.fasterxml.jackson.databind.ObjectMapper; import com.imyeyu.api.bean.PreviewPage; import com.imyeyu.api.bean.wechat.InitCodeResponse; import com.imyeyu.api.modules.common.bean.MediaAttach; @@ -18,10 +19,8 @@ import com.imyeyu.api.modules.journal.vo.journal.UpdateRequest; import com.imyeyu.java.bean.timi.TimiCode; import com.imyeyu.java.bean.timi.TimiException; import com.imyeyu.network.ArgMap; -import com.imyeyu.network.GsonRequest; import com.imyeyu.spring.annotation.AOPLog; import com.imyeyu.spring.annotation.RequestRateLimit; -import com.imyeyu.spring.annotation.RequestSingleParam; import com.imyeyu.spring.bean.Page; import com.imyeyu.spring.bean.PageResult; import jakarta.validation.Valid; @@ -53,6 +52,7 @@ public class JournalController { private final JournalService service; private final SettingService settingService; private final AttachmentService attachmentService; + private final ObjectMapper jackson; private final JournalAPIInterceptor apiInterceptor; @@ -65,14 +65,18 @@ public class JournalController { @AOPLog @RequestRateLimit @PostMapping("/openid") - public String initOpenId(@RequestSingleParam String code) { + public String initOpenId(@RequestBody String code) { try { ArgMap args = new ArgMap<>(); args.put("appid", settingService.getAsString(SettingKey.JOURNAL_APP_ID)); args.put("secret", settingService.getAsString(SettingKey.JOURNAL_APP_SECRET)); args.put("js_code", code); args.put("grant_type", "authorization_code"); - InitCodeResponse resp = GsonRequest.get(args.toURL("https://api.weixin.qq.com/sns/jscode2session")).resultAs(InitCodeResponse.class); + String response = org.apache.hc.client5.http.fluent.Request.get(args.toURL("https://api.weixin.qq.com/sns/jscode2session")) + .execute() + .returnContent() + .asString(); + InitCodeResponse resp = jackson.readValue(response, InitCodeResponse.class); return resp.getOpenid(); } catch (Exception e) { log.error("init WeChat openId error", e); @@ -139,7 +143,7 @@ public class JournalController { @AOPLog @RequiredUploadPermission @PostMapping("/delete") - public void delete(@RequestSingleParam Long id) { + public void delete(@RequestBody Long id) { service.delete(id); } diff --git a/src/main/java/com/imyeyu/api/modules/journal/controller/ToolController.java b/src/main/java/com/imyeyu/api/modules/journal/controller/ToolController.java index f495a79..32d8f5e 100644 --- a/src/main/java/com/imyeyu/api/modules/journal/controller/ToolController.java +++ b/src/main/java/com/imyeyu/api/modules/journal/controller/ToolController.java @@ -4,7 +4,7 @@ import com.imyeyu.api.modules.common.bean.SettingKey; import com.imyeyu.api.modules.common.entity.Setting; import com.imyeyu.api.modules.common.service.SettingService; import com.imyeyu.api.modules.journal.bean.RequiredUploadPermission; -import com.imyeyu.spring.annotation.RequestSingleParam; +import com.imyeyu.spring.annotation.RequestBodyValue; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.GetMapping; @@ -31,7 +31,7 @@ public class ToolController { @RequiredUploadPermission @PostMapping("/memo/update") - public void updateMemo(@RequestSingleParam String data) { + public void updateMemo(@RequestBodyValue String data) { Setting setting = settingService.getByKey(SettingKey.JOURNAL_MEMO); setting.setValue(data); settingService.update(setting); diff --git a/src/main/java/com/imyeyu/api/modules/journal/controller/TravelController.java b/src/main/java/com/imyeyu/api/modules/journal/controller/TravelController.java index 2dfc2eb..9acac57 100644 --- a/src/main/java/com/imyeyu/api/modules/journal/controller/TravelController.java +++ b/src/main/java/com/imyeyu/api/modules/journal/controller/TravelController.java @@ -5,7 +5,6 @@ import com.imyeyu.api.modules.journal.entity.Travel; import com.imyeyu.api.modules.journal.service.TravelService; import com.imyeyu.spring.annotation.AOPLog; import com.imyeyu.spring.annotation.RequestRateLimit; -import com.imyeyu.spring.annotation.RequestSingleParam; import com.imyeyu.spring.bean.Page; import com.imyeyu.spring.bean.PageResult; import jakarta.validation.Valid; @@ -67,7 +66,7 @@ public class TravelController { @RequestRateLimit @RequiredUploadPermission @PostMapping("/delete") - public void delete(@RequestSingleParam Long id) { + public void delete(@RequestBody Long id) { service.delete(id); } diff --git a/src/main/java/com/imyeyu/api/modules/journal/controller/TravelLocationController.java b/src/main/java/com/imyeyu/api/modules/journal/controller/TravelLocationController.java index fbd4dfc..87a43cb 100644 --- a/src/main/java/com/imyeyu/api/modules/journal/controller/TravelLocationController.java +++ b/src/main/java/com/imyeyu/api/modules/journal/controller/TravelLocationController.java @@ -9,7 +9,6 @@ import com.imyeyu.api.modules.journal.entity.TravelLocation; import com.imyeyu.api.modules.journal.service.TravelLocationService; import com.imyeyu.spring.annotation.AOPLog; import com.imyeyu.spring.annotation.RequestRateLimit; -import com.imyeyu.spring.annotation.RequestSingleParam; import com.imyeyu.spring.bean.Page; import com.imyeyu.spring.bean.PageResult; import jakarta.validation.Valid; @@ -74,7 +73,7 @@ public class TravelLocationController { @RequestRateLimit @RequiredUploadPermission @PostMapping("/delete") - public void delete(@RequestSingleParam Long id) { + public void delete(@RequestBody Long id) { service.delete(id); } diff --git a/src/main/java/com/imyeyu/api/modules/journal/service/implement/JournalServiceImplement.java b/src/main/java/com/imyeyu/api/modules/journal/service/implement/JournalServiceImplement.java index 874e2cb..055b315 100644 --- a/src/main/java/com/imyeyu/api/modules/journal/service/implement/JournalServiceImplement.java +++ b/src/main/java/com/imyeyu/api/modules/journal/service/implement/JournalServiceImplement.java @@ -1,6 +1,6 @@ package com.imyeyu.api.modules.journal.service.implement; -import com.google.gson.Gson; +import com.fasterxml.jackson.databind.ObjectMapper; import com.imyeyu.api.config.dbsource.TimiServerDBConfig; import com.imyeyu.api.modules.common.bean.MediaAttach; import com.imyeyu.api.modules.common.bean.Metadata; @@ -40,7 +40,7 @@ import java.util.stream.Collectors; @RequiredArgsConstructor public class JournalServiceImplement extends AbstractEntityService implements JournalService { - private final Gson gson; + private final ObjectMapper jackson; private final SettingService settingService; private final TempFileService tempFileService; @@ -192,7 +192,7 @@ public class JournalServiceImplement extends AbstractEntityService allLyric; + private final ObjectMapper jackson; @Override public Lyric get(Long id) { @@ -113,12 +114,12 @@ public class LyricServiceImplement implements LyricService { Request request = Request.get(API_GET_SONG + Encoder.urlArgs(args)); HEADER.forEach(request::addHeader); response = request.execute().returnContent().asString(); - JsonObject data = JsonParser.parseString(response).getAsJsonObject().get("data").getAsJsonObject().get("info").getAsJsonArray().get(0).getAsJsonObject(); + JsonNode data = jackson.readTree(response).path("data").path("info").get(0); args.clear(); args.put("cmd", "100"); - args.put("keyword", data.get("songname").getAsString()); - args.put("hash", data.get("hash").getAsString()); + args.put("keyword", data.path("songname").asText()); + args.put("hash", data.path("hash").asText()); args.put("timelength", tl); args.put("d", String.valueOf(Math.random())); request = Request.get(API_GET_LRC + Encoder.urlArgs(args)); @@ -128,8 +129,8 @@ public class LyricServiceImplement implements LyricService { } Lyric lyric = new Lyric(); - lyric.setSong(data.get("songname").getAsString()); - lyric.setSinger(data.get("singername").getAsString()); + lyric.setSong(data.path("songname").asText()); + lyric.setSinger(data.path("singername").asText()); lyric.setData(response); return lyric; } catch (Exception e) { diff --git a/src/main/java/com/imyeyu/api/modules/minecraft/controller/PlayerController.java b/src/main/java/com/imyeyu/api/modules/minecraft/controller/PlayerController.java index b14bb59..21b8387 100644 --- a/src/main/java/com/imyeyu/api/modules/minecraft/controller/PlayerController.java +++ b/src/main/java/com/imyeyu/api/modules/minecraft/controller/PlayerController.java @@ -17,7 +17,6 @@ import com.imyeyu.api.modules.minecraft.vo.TokenRequest; import com.imyeyu.api.modules.minecraft.vo.TokenResponse; import com.imyeyu.spring.annotation.AOPLog; import com.imyeyu.spring.annotation.RequestRateLimit; -import com.imyeyu.spring.annotation.RequestSingleParam; import com.imyeyu.spring.annotation.RequiredToken; import com.imyeyu.spring.util.Redis; import com.imyeyu.spring.util.RedisSerializers; @@ -73,7 +72,7 @@ public class PlayerController { @RequiredToken @RequestRateLimit @PostMapping("/bind") - public void bind(@RequestSingleParam String name) { + public void bind(@RequestBody String name) { MinecraftPlayer player = new MinecraftPlayer(); player.setName(name); player.setUserId(userService.getLoginUser().getId()); @@ -84,7 +83,7 @@ public class PlayerController { @RequiredToken @RequestRateLimit @PostMapping("/unbind") - public void unbind(@RequestSingleParam Long id) { + public void unbind(@RequestBody Long id) { service.listByUserId(userService.getLoginUser().getId()) .stream() .filter(player -> player.getId().equals(id)) @@ -113,7 +112,7 @@ public class PlayerController { @RequestRateLimit @EnableSetting(value = SettingKey.FMC_PLAYER_LOGIN_ENABLE, message = "登录服务未启用") @PostMapping("/login") - public TokenResponse login(@RequestSingleParam Long playerId, @RequestHeader("Token") String token) { + public TokenResponse login(@RequestBody Long playerId, @RequestHeader("Token") String token) { return service.login(playerId, token); } diff --git a/src/main/java/com/imyeyu/api/modules/mirror/FabricAPIMirror.java b/src/main/java/com/imyeyu/api/modules/mirror/FabricAPIMirror.java index 25450d4..0267525 100644 --- a/src/main/java/com/imyeyu/api/modules/mirror/FabricAPIMirror.java +++ b/src/main/java/com/imyeyu/api/modules/mirror/FabricAPIMirror.java @@ -1,6 +1,6 @@ package com.imyeyu.api.modules.mirror; -import com.google.gson.Gson; +import com.fasterxml.jackson.databind.ObjectMapper; import com.imyeyu.api.modules.common.entity.Attachment; import com.imyeyu.api.modules.common.service.AttachmentService; import com.imyeyu.api.modules.mirror.bean.AttachType; @@ -47,7 +47,7 @@ public class FabricAPIMirror extends AttachmentMirror { /** 版本匹配正则 */ private static final Pattern versionRegex = Pattern.compile("^(\\d+\\.){1,2}(\\*|\\d+)$"); - private final Gson gson; + private final ObjectMapper jackson; private final MirrorService service; private final AttachmentService attachmentService; @@ -100,7 +100,7 @@ public class FabricAPIMirror extends AttachmentMirror { result.add(item); } } - mirror.setData(gson.toJsonTree(result)); + mirror.setData(jackson.valueToTree(result)); service.update(mirror); } diff --git a/src/main/java/com/imyeyu/api/modules/mirror/OpenJDKGithubMirror.java b/src/main/java/com/imyeyu/api/modules/mirror/OpenJDKGithubMirror.java index 36bdb7e..60507eb 100644 --- a/src/main/java/com/imyeyu/api/modules/mirror/OpenJDKGithubMirror.java +++ b/src/main/java/com/imyeyu/api/modules/mirror/OpenJDKGithubMirror.java @@ -1,16 +1,13 @@ package com.imyeyu.api.modules.mirror; -import com.google.gson.Gson; -import com.google.gson.JsonArray; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParser; -import com.imyeyu.java.bean.timi.TimiCode; -import com.imyeyu.java.bean.timi.TimiException; -import com.imyeyu.java.ref.Ref; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; import com.imyeyu.api.modules.mirror.data.OpenJDK; import com.imyeyu.api.modules.mirror.entity.Mirror; import com.imyeyu.api.modules.mirror.service.MirrorService; +import com.imyeyu.java.bean.timi.TimiCode; +import com.imyeyu.java.bean.timi.TimiException; +import com.imyeyu.java.ref.Ref; import com.imyeyu.utils.OS; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -27,9 +24,9 @@ import java.util.List; import java.util.Map; /** - * Github JDK 镜像,仅同步下载链接等信息,不储存文件 + * Github JDK 闀滃儚锛屼粎鍚屾涓嬭浇閾炬帴绛変俊鎭紝涓嶅偍瀛樻枃浠? * - * @author 夜雨 + * @author 澶滈洦 * @version 2024-06-10 10:51 */ @Slf4j @@ -37,10 +34,10 @@ import java.util.Map; @RequiredArgsConstructor public class OpenJDKGithubMirror extends AbstractMirror { - /** 版本发布列表接口,插值 {@link #REPOS_MAP} 的值 */ + /** 鐗堟湰鍙戝竷鍒楄〃鎺ュ彛锛屾彃鍊?{@link #REPOS_MAP} 鐨勫€?*/ private static final String API_RELEASE = "https://api.github.com/repos/adoptium/%s/releases?page=1"; - /** 版本仓库映射,key 为版本,value 为对应仓库,只读 */ + /** 鐗堟湰浠撳簱鏄犲皠锛宬ey 涓虹増鏈紝value 涓哄搴斾粨搴擄紝鍙 */ private static final Map REPOS_MAP = Collections.unmodifiableMap(new HashMap<>() {{ put("8", "temurin8-binaries"); put("11", "temurin11-binaries"); @@ -48,31 +45,30 @@ public class OpenJDKGithubMirror extends AbstractMirror { put("21", "temurin21-binaries"); }}); - private final Gson gson; + private final ObjectMapper jackson; private final MirrorService service; @Override protected void sync(Mirror mirror) throws Exception { - mirror.setData(gson.toJsonTree(fetch())); + mirror.setData(jackson.valueToTree(fetch())); service.update(mirror); } /** - * 获取 {@link OpenJDK} 列表,{@link OpenJDKMirror} 也会使用此接口 + * 鑾峰彇 {@link OpenJDK} 鍒楄〃锛寋@link OpenJDKMirror} 涔熶細浣跨敤姝ゆ帴鍙? * - * @return jdk 列表 - * @throws Exception 获取异常 + * @return jdk 鍒楄〃 + * @throws Exception 鑾峰彇寮傚父 */ final List fetch() throws Exception { List result = new ArrayList<>(); for (Map.Entry repo : REPOS_MAP.entrySet()) { String respText = Request.get(API_RELEASE.formatted(repo.getValue())).connectTimeout(Timeout.ofSeconds(60)).execute().returnContent().asString(); - JsonArray root = JsonParser.parseString(respText).getAsJsonArray(); - JsonObject itemRel = null; - for (JsonElement el : root) { - itemRel = el.getAsJsonObject(); - if (itemRel.get("prerelease").getAsBoolean() || itemRel.get("draft").getAsBoolean()) { - // 忽略草稿或预发布版本 + JsonNode root = jackson.readTree(respText); + JsonNode itemRel = null; + for (JsonNode el : root) { + itemRel = el; + if (itemRel.path("prerelease").asBoolean() || itemRel.path("draft").asBoolean()) { itemRel = null; } else { break; @@ -81,12 +77,8 @@ public class OpenJDKGithubMirror extends AbstractMirror { if (itemRel == null) { throw new TimiException(TimiCode.ERROR, "not found release item for " + repo.getValue()); } - JsonArray assets = itemRel.get("assets").getAsJsonArray(); - for (JsonElement asset : assets) { - JsonObject itemAsset = asset.getAsJsonObject(); - // OpenJDK21U-jdk_x64_windows_hotspot_21.0.3_9.zip - String name = itemAsset.get("name").getAsString(); - + for (JsonNode itemAsset : itemRel.path("assets")) { + String name = itemAsset.path("name").asText(); if (!name.contains("-") || !name.contains("_")) { continue; } @@ -102,14 +94,13 @@ public class OpenJDKGithubMirror extends AbstractMirror { } OS.Platform platform = Ref.toType(OS.Platform.class, split[2].toUpperCase()); OpenJDK.Type type = Ref.toType(OpenJDK.Type.class, split[0].toUpperCase()); - if (platform != null && type != null) { OpenJDK jdk = new OpenJDK(); jdk.setPlatform(platform); jdk.setType(type); jdk.setName(name); jdk.setVersion(repo.getKey()); - jdk.setData(URLDecoder.decode(itemAsset.get("browser_download_url").getAsString(), StandardCharsets.UTF_8)); + jdk.setData(URLDecoder.decode(itemAsset.path("browser_download_url").asText(), StandardCharsets.UTF_8)); result.add(jdk); } } diff --git a/src/main/java/com/imyeyu/api/modules/mirror/OpenJDKMirror.java b/src/main/java/com/imyeyu/api/modules/mirror/OpenJDKMirror.java index f48b358..28d04ed 100644 --- a/src/main/java/com/imyeyu/api/modules/mirror/OpenJDKMirror.java +++ b/src/main/java/com/imyeyu/api/modules/mirror/OpenJDKMirror.java @@ -1,6 +1,6 @@ package com.imyeyu.api.modules.mirror; -import com.google.gson.Gson; +import com.fasterxml.jackson.databind.ObjectMapper; import com.imyeyu.api.modules.common.entity.Attachment; import com.imyeyu.api.modules.common.service.AttachmentService; import com.imyeyu.api.modules.mirror.bean.AttachType; @@ -30,7 +30,7 @@ import java.util.stream.Collectors; @RequiredArgsConstructor public class OpenJDKMirror extends AttachmentMirror { - private final Gson gson; + private final ObjectMapper jackson; private final MirrorService service; private final AttachmentService attachmentService; private final OpenJDKGithubMirror githubMirror; @@ -64,7 +64,7 @@ public class OpenJDKMirror extends AttachmentMirror { result.add(jdk); } } - mirror.setData(gson.toJsonTree(result)); + mirror.setData(jackson.valueToTree(result)); service.update(mirror); } diff --git a/src/main/java/com/imyeyu/api/modules/mirror/OpenJDKTunaMirror.java b/src/main/java/com/imyeyu/api/modules/mirror/OpenJDKTunaMirror.java index 589f296..fb578d8 100644 --- a/src/main/java/com/imyeyu/api/modules/mirror/OpenJDKTunaMirror.java +++ b/src/main/java/com/imyeyu/api/modules/mirror/OpenJDKTunaMirror.java @@ -1,12 +1,12 @@ package com.imyeyu.api.modules.mirror; -import com.google.gson.Gson; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; +import com.fasterxml.jackson.databind.ObjectMapper; import com.imyeyu.api.modules.mirror.data.OpenJDK; import com.imyeyu.api.modules.mirror.entity.Mirror; import com.imyeyu.api.modules.mirror.service.MirrorService; import com.imyeyu.utils.OS; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import org.jsoup.nodes.Element; @@ -41,18 +41,18 @@ public class OpenJDKTunaMirror extends AbstractMirror { /** 版本列表 */ private static final String[] VERSIONS = {"8", "11", "17", "21"}; - private final Gson gson; + private final ObjectMapper jackson; private final MirrorService service; @Override protected void sync(Mirror mirror) throws Exception { List result = new ArrayList<>(); - for (int i = 0; i < VERSIONS.length; i++) { + for (String version : VERSIONS) { OpenJDK.Type[] types = OpenJDK.Type.values(); - for (int j = 0; j < types.length; j++) { + for (OpenJDK.Type type : types) { OS.Platform[] platforms = OS.Platform.values(); - for (int k = 0; k < platforms.length; k++) { - String url = PAGE_URL_TEMPLATE.formatted(VERSIONS[i], types[j].toString().toLowerCase(), platforms[k].toString().toLowerCase()); + for (OS.Platform platform : platforms) { + String url = PAGE_URL_TEMPLATE.formatted(version, type.toString().toLowerCase(), platform.toString().toLowerCase()); Document document = Jsoup.connect(url).get(); Element fileList = document.getElementById("list"); Elements linkTDList = fileList.getElementsByClass("link"); @@ -64,10 +64,10 @@ public class OpenJDKTunaMirror extends AbstractMirror { continue; } OpenJDK jdk = new OpenJDK(); - jdk.setPlatform(platforms[k]); - jdk.setType(types[j]); + jdk.setPlatform(platform); + jdk.setType(type); jdk.setName(href); - jdk.setVersion(VERSIONS[i]); + jdk.setVersion(version); jdk.setData(url + href); result.add(jdk); @@ -77,7 +77,7 @@ public class OpenJDKTunaMirror extends AbstractMirror { } } } - mirror.setData(gson.toJsonTree(result)); + mirror.setData(jackson.valueToTree(result)); service.update(mirror); } } diff --git a/src/main/java/com/imyeyu/api/modules/mirror/controller/MirrorController.java b/src/main/java/com/imyeyu/api/modules/mirror/controller/MirrorController.java index 3b5c896..cf9f098 100644 --- a/src/main/java/com/imyeyu/api/modules/mirror/controller/MirrorController.java +++ b/src/main/java/com/imyeyu/api/modules/mirror/controller/MirrorController.java @@ -1,6 +1,6 @@ package com.imyeyu.api.modules.mirror.controller; -import com.google.gson.JsonElement; +import com.fasterxml.jackson.databind.JsonNode; import com.imyeyu.api.modules.mirror.entity.Mirror; import com.imyeyu.api.modules.mirror.service.MirrorService; import com.imyeyu.api.modules.mirror.vo.MirrorView; @@ -38,7 +38,7 @@ public class MirrorController { */ @RequestRateLimit @GetMapping("/{mirrorName}") - public JsonElement get(@PathVariable String mirrorName) { + public JsonNode get(@PathVariable String mirrorName) { return service.getByName(mirrorName).getData(); } diff --git a/src/main/java/com/imyeyu/api/modules/mirror/entity/Mirror.java b/src/main/java/com/imyeyu/api/modules/mirror/entity/Mirror.java index 50c7943..7409e27 100644 --- a/src/main/java/com/imyeyu/api/modules/mirror/entity/Mirror.java +++ b/src/main/java/com/imyeyu/api/modules/mirror/entity/Mirror.java @@ -1,9 +1,9 @@ package com.imyeyu.api.modules.mirror.entity; -import com.google.gson.JsonElement; +import com.fasterxml.jackson.databind.JsonNode; +import com.imyeyu.spring.entity.Entity; import lombok.Data; import lombok.EqualsAndHashCode; -import com.imyeyu.spring.entity.Entity; /** * 镜像 @@ -22,7 +22,7 @@ public class Mirror extends Entity { protected String name; /** 同步数据 */ - protected JsonElement data; + protected JsonNode data; /** 周期(分钟) */ protected int period; diff --git a/src/main/java/com/imyeyu/api/modules/music/core/Middleware.java b/src/main/java/com/imyeyu/api/modules/music/core/Middleware.java index 449a652..3307716 100644 --- a/src/main/java/com/imyeyu/api/modules/music/core/Middleware.java +++ b/src/main/java/com/imyeyu/api/modules/music/core/Middleware.java @@ -1,6 +1,7 @@ package com.imyeyu.api.modules.music.core; -import com.google.gson.Gson; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.ChannelHandlerContext; @@ -36,7 +37,7 @@ public class Middleware implements SchedulingConfigurer { private static final String CACHE_CLEAR_CORN = "0 0/20 * * * ?"; @Autowired - private Gson gson; + private ObjectMapper jackson; /** 缓存频道,Map<频道 ID, 关联频道> */ private final Map channels = new HashMap<>(); @@ -67,7 +68,7 @@ public class Middleware implements SchedulingConfigurer { channelBinding.setPlayerChannel(ctx); channelBinding.setLastActiviedAt(Time.now()); if (channelBinding.getControllerChannel() != null) { - channelBinding.getControllerChannel().writeAndFlush(new TextWebSocketFrame(gson.toJson(pkg))); + channelBinding.getControllerChannel().writeAndFlush(new TextWebSocketFrame(writeValueAsString(pkg))); } } @@ -90,11 +91,19 @@ public class Middleware implements SchedulingConfigurer { channelBinding.setControllerChannel(ctx); channelBinding.setLastActiviedAt(Time.now()); if (pkg.getAction() != null && channelBinding.getPlayerChannel() != null) { - byte[] bytes = gson.toJson(pkg).getBytes(StandardCharsets.UTF_8); + byte[] bytes = writeValueAsString(pkg).getBytes(StandardCharsets.UTF_8); ByteBuf buffer = Unpooled.buffer(); buffer.writeInt(bytes.length); buffer.writeBytes(bytes); channelBinding.getPlayerChannel().writeAndFlush(buffer); } } + + private String writeValueAsString(Object value) { + try { + return jackson.writeValueAsString(value); + } catch (JsonProcessingException e) { + throw new IllegalStateException("write music websocket payload error", e); + } + } } diff --git a/src/main/java/com/imyeyu/api/modules/music/handler/ControllerMessageHandler.java b/src/main/java/com/imyeyu/api/modules/music/handler/ControllerMessageHandler.java index 475c91c..45d55ee 100644 --- a/src/main/java/com/imyeyu/api/modules/music/handler/ControllerMessageHandler.java +++ b/src/main/java/com/imyeyu/api/modules/music/handler/ControllerMessageHandler.java @@ -1,6 +1,6 @@ package com.imyeyu.api.modules.music.handler; -import com.google.gson.Gson; +import com.fasterxml.jackson.databind.ObjectMapper; import io.netty.channel.ChannelFutureListener; import io.netty.channel.ChannelHandler; import io.netty.channel.ChannelHandlerContext; @@ -26,7 +26,7 @@ import org.springframework.stereotype.Component; public class ControllerMessageHandler extends SimpleChannelInboundHandler { @Autowired - private Gson gson; + private ObjectMapper jackson; @Autowired private Middleware middleware; @@ -34,7 +34,11 @@ public class ControllerMessageHandler extends SimpleChannelInboundHandler { @Autowired - private Gson gson; + private ObjectMapper jackson; @Autowired private Middleware middleware; @Override protected synchronized void channelRead0(ChannelHandlerContext ctx, String result) { - middleware.pushPlayerData(ctx, gson.fromJson(result, PlayerPackage.class)); + try { + middleware.pushPlayerData(ctx, jackson.readValue(result, PlayerPackage.class)); + } catch (Exception e) { + throw new IllegalStateException("read player websocket payload error", e); + } } @Override diff --git a/src/main/java/com/imyeyu/api/modules/system/controller/FileController.java b/src/main/java/com/imyeyu/api/modules/system/controller/FileController.java index 8074ec8..055870b 100644 --- a/src/main/java/com/imyeyu/api/modules/system/controller/FileController.java +++ b/src/main/java/com/imyeyu/api/modules/system/controller/FileController.java @@ -475,7 +475,7 @@ public class FileController implements TimiJava, OS.FileSystem { resp.setHeader("Content-Disposition", Network.getFileDownloadHeader(file.getName())); resp.setHeader("Accept-Ranges", "bytes"); - RequestRange range = TimiSpring.requestRange(file.length()); + RequestRange range = TimiSpring.getRequestRange(file.length()); if (range == null) { // 完整文件 resp.setContentLengthLong(file.length()); diff --git a/src/main/java/com/imyeyu/api/modules/system/controller/TerminalController.java b/src/main/java/com/imyeyu/api/modules/system/controller/TerminalController.java index 49552bf..d906378 100644 --- a/src/main/java/com/imyeyu/api/modules/system/controller/TerminalController.java +++ b/src/main/java/com/imyeyu/api/modules/system/controller/TerminalController.java @@ -7,7 +7,6 @@ import com.imyeyu.api.modules.common.service.SettingService; import com.imyeyu.api.modules.system.service.TerminalService; import com.imyeyu.api.modules.system.vo.terminal.ExecCommand; import com.imyeyu.spring.annotation.AOPLog; -import com.imyeyu.spring.annotation.RequestSingleParam; import com.imyeyu.spring.annotation.RequiredToken; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; @@ -51,7 +50,7 @@ public class TerminalController { */ @RequiredToken @PostMapping("/alive") - public boolean isAlive(@RequestSingleParam String sessionId) { + public boolean isAlive(@RequestBody String sessionId) { return service.isAlive(sessionId); } @@ -64,7 +63,7 @@ public class TerminalController { @AOPLog @RequiredToken @PostMapping("/fill") - public synchronized String pathFill(@RequestSingleParam String path) { + public synchronized String pathFill(@RequestBody String path) { return service.pathFill(path); } @@ -94,7 +93,7 @@ public class TerminalController { @AOPLog @RequiredToken @PostMapping("/close") - public void close(@RequestSingleParam String sessionId) { + public void close(@RequestBody String sessionId) { service.close(sessionId); } } diff --git a/src/main/java/com/imyeyu/api/modules/system/task/DockerStatusTask.java b/src/main/java/com/imyeyu/api/modules/system/task/DockerStatusTask.java index 7b35fc7..24827bb 100644 --- a/src/main/java/com/imyeyu/api/modules/system/task/DockerStatusTask.java +++ b/src/main/java/com/imyeyu/api/modules/system/task/DockerStatusTask.java @@ -1,8 +1,7 @@ package com.imyeyu.api.modules.system.task; -import com.google.gson.JsonArray; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.node.ArrayNode; import com.imyeyu.api.modules.system.bean.DockerStatusStore; import com.imyeyu.api.modules.system.util.DockerEngineClient; import com.imyeyu.utils.Time; @@ -21,7 +20,7 @@ import java.util.Set; import java.util.concurrent.TimeUnit; /** - * Docker 状态采集任务 + * Docker 鐘舵€侀噰闆嗕换鍔? * * @author Codex * @since 2026-04-06 @@ -34,7 +33,7 @@ public class DockerStatusTask implements SchedulingConfigurer { private final DockerEngineClient dockerEngineClient; private final DockerStatusStore dockerStatusStore; - @Value("${docker.engine.collect-enabled:true}") + @Value("${docker.engine.collect-enabled:false}") private boolean collectEnabled; @Value("${docker.engine.collect-rate-ms:10000}") @@ -55,13 +54,12 @@ public class DockerStatusTask implements SchedulingConfigurer { private void collect() { try { - JsonArray containers = dockerEngineClient.getJson("/containers/json", DockerEngineClient.query("all", "true")).getAsJsonArray(); + ArrayNode containers = (ArrayNode) dockerEngineClient.getJson("/containers/json", DockerEngineClient.query("all", "true")); long now = Time.now(); synchronized (dockerStatusStore) { Set activeIds = new HashSet<>(); - for (JsonElement item : containers) { + for (JsonNode summary : containers) { try { - JsonObject summary = item.getAsJsonObject(); String containerId = getAsString(summary, "Id"); activeIds.add(containerId); DockerStatusStore.Container container = dockerStatusStore.getContainers().computeIfAbsent(containerId, key -> new DockerStatusStore.Container()); @@ -79,7 +77,7 @@ public class DockerStatusTask implements SchedulingConfigurer { } } - private void updateContainerSummary(DockerStatusStore.Container container, JsonObject summary) { + private void updateContainerSummary(DockerStatusStore.Container container, JsonNode summary) { container.setId(getAsString(summary, "Id")); container.setName(trimContainerName(readFirstArrayText(summary, "Names"))); container.setImage(getAsString(summary, "Image")); @@ -90,19 +88,19 @@ public class DockerStatusTask implements SchedulingConfigurer { } private void updateContainerInspect(String containerId, DockerStatusStore.Container container) { - JsonObject inspect = dockerEngineClient.getJson("/containers/%s/json".formatted(containerId), Map.of()).getAsJsonObject(); - JsonObject state = getAsObject(inspect, "State"); + JsonNode inspect = dockerEngineClient.getJson("/containers/%s/json".formatted(containerId), Map.of()); + JsonNode state = getAsObject(inspect, "State"); container.setStartedAt(getAsString(state, "StartedAt")); container.setFinishedAt(getAsString(state, "FinishedAt")); container.setExitCode(getAsInteger(state, "ExitCode")); container.setRestartCount(getAsInteger(inspect, "RestartCount", 0)); container.setOomKilled(getAsBoolean(state, "OOMKilled")); - JsonObject health = getAsObject(state, "Health"); + JsonNode health = getAsObject(state, "Health"); container.setHealthStatus(health == null ? null : getAsString(health, "Status")); } private void updateContainerStats(String containerId, DockerStatusStore.Container container, long now) { - JsonObject stats = dockerEngineClient.getJson("/containers/%s/stats".formatted(containerId), DockerEngineClient.query("stream", "false")).getAsJsonObject(); + JsonNode stats = dockerEngineClient.getJson("/containers/%s/stats".formatted(containerId), DockerEngineClient.query("stream", "false")); Double cpuPercent = calculateCpuPercent(stats); Long memoryUsageBytes = getNestedLong(stats, "memory_stats", "usage"); Long memoryLimitBytes = getNestedLong(stats, "memory_stats", "limit"); @@ -112,21 +110,20 @@ public class DockerStatusTask implements SchedulingConfigurer { } Long networkRxBytes = 0L; Long networkTxBytes = 0L; - JsonObject networks = getAsObject(stats, "networks"); + JsonNode networks = getAsObject(stats, "networks"); if (networks != null) { - for (Map.Entry item : networks.entrySet()) { - JsonObject network = item.getValue().getAsJsonObject(); + for (Map.Entry item : (Iterable>) networks::fields) { + JsonNode network = item.getValue(); networkRxBytes += getAsLong(network, "rx_bytes", 0L); networkTxBytes += getAsLong(network, "tx_bytes", 0L); } } Long blockReadBytes = 0L; Long blockWriteBytes = 0L; - JsonObject blkioStats = getAsObject(stats, "blkio_stats"); - JsonArray ioServiceBytes = blkioStats == null ? null : blkioStats.getAsJsonArray("io_service_bytes_recursive"); + JsonNode blkioStats = getAsObject(stats, "blkio_stats"); + ArrayNode ioServiceBytes = blkioStats == null ? null : getAsArray(blkioStats, "io_service_bytes_recursive"); if (ioServiceBytes != null) { - for (JsonElement item : ioServiceBytes) { - JsonObject io = item.getAsJsonObject(); + for (JsonNode io : ioServiceBytes) { String op = getAsString(io, "op"); long value = getAsLong(io, "value", 0L); if ("Read".equalsIgnoreCase(op)) { @@ -165,14 +162,14 @@ public class DockerStatusTask implements SchedulingConfigurer { } } - private Double calculateCpuPercent(JsonObject stats) { + private Double calculateCpuPercent(JsonNode stats) { Long cpuTotal = getNestedLong(stats, "cpu_stats", "cpu_usage", "total_usage"); Long preCpuTotal = getNestedLong(stats, "precpu_stats", "cpu_usage", "total_usage"); Long systemTotal = getNestedLong(stats, "cpu_stats", "system_cpu_usage"); Long preSystemTotal = getNestedLong(stats, "precpu_stats", "system_cpu_usage"); Integer onlineCpus = getNestedInteger(stats, "cpu_stats", "online_cpus"); if (onlineCpus == null || onlineCpus <= 0) { - JsonArray perCpuUsage = getNestedArray(stats, "cpu_stats", "cpu_usage", "percpu_usage"); + ArrayNode perCpuUsage = getNestedArray(stats, "cpu_stats", "cpu_usage", "percpu_usage"); onlineCpus = perCpuUsage == null ? 1 : perCpuUsage.size(); } if (cpuTotal == null || preCpuTotal == null || systemTotal == null || preSystemTotal == null) { @@ -186,81 +183,89 @@ public class DockerStatusTask implements SchedulingConfigurer { return cpuDelta * 100D * onlineCpus / systemDelta; } - private JsonObject getAsObject(JsonObject source, String key) { - if (source == null || !source.has(key) || source.get(key).isJsonNull()) { + private JsonNode getAsObject(JsonNode source, String key) { + if (source == null || !source.has(key) || source.get(key).isNull() || !source.get(key).isObject()) { return null; } - return source.getAsJsonObject(key); + return source.get(key); } - private JsonArray getNestedArray(JsonObject source, String... keys) { - JsonElement current = source; + private ArrayNode getAsArray(JsonNode source, String key) { + if (source == null || !source.has(key) || !source.get(key).isArray()) { + return null; + } + return (ArrayNode) source.get(key); + } + + private ArrayNode getNestedArray(JsonNode source, String... keys) { + JsonNode current = source; for (String key : keys) { - if (current == null || !current.isJsonObject() || !current.getAsJsonObject().has(key)) { + if (current == null || !current.isObject() || !current.has(key)) { return null; } - current = current.getAsJsonObject().get(key); + current = current.get(key); } - return current != null && current.isJsonArray() ? current.getAsJsonArray() : null; + return current != null && current.isArray() ? (ArrayNode) current : null; } - private Long getNestedLong(JsonObject source, String... keys) { - JsonElement current = source; + private Long getNestedLong(JsonNode source, String... keys) { + JsonNode current = source; for (String key : keys) { - if (current == null || !current.isJsonObject() || !current.getAsJsonObject().has(key)) { + if (current == null || !current.isObject() || !current.has(key)) { return null; } - current = current.getAsJsonObject().get(key); + current = current.get(key); } - return current == null || current.isJsonNull() ? null : current.getAsLong(); + return current == null || current.isNull() ? null : current.asLong(); } - private Integer getNestedInteger(JsonObject source, String... keys) { + private Integer getNestedInteger(JsonNode source, String... keys) { Long value = getNestedLong(source, keys); return value == null ? null : value.intValue(); } - private String readFirstArrayText(JsonObject source, String key) { - if (source == null || !source.has(key) || !source.get(key).isJsonArray() || source.getAsJsonArray(key).isEmpty()) { + private String readFirstArrayText(JsonNode source, String key) { + ArrayNode array = getAsArray(source, key); + if (array == null || array.isEmpty()) { return null; } - return source.getAsJsonArray(key).get(0).getAsString(); + return array.get(0).asText(); } - private String getAsString(JsonObject source, String key) { - if (source == null || !source.has(key) || source.get(key).isJsonNull()) { + private String getAsString(JsonNode source, String key) { + if (source == null || !source.has(key) || source.get(key).isNull()) { return null; } - return source.get(key).getAsString(); + return source.get(key).asText(); } - private long getAsLong(JsonObject source, String key) { + private long getAsLong(JsonNode source, String key) { return getAsLong(source, key, 0L); } - private long getAsLong(JsonObject source, String key, long defaultValue) { - if (source == null || !source.has(key) || source.get(key).isJsonNull()) { + private long getAsLong(JsonNode source, String key, long defaultValue) { + if (source == null || !source.has(key) || source.get(key).isNull()) { return defaultValue; } - return source.get(key).getAsLong(); + return source.get(key).asLong(); } - private Integer getAsInteger(JsonObject source, String key) { - if (source == null || !source.has(key) || source.get(key).isJsonNull()) { + private Integer getAsInteger(JsonNode source, String key) { + if (source == null || !source.has(key) || source.get(key).isNull()) { return null; } - return source.get(key).getAsInt(); + return source.get(key).asInt(); } - private int getAsInteger(JsonObject source, String key, int defaultValue) { - if (source == null || !source.has(key) || source.get(key).isJsonNull()) { + private int getAsInteger(JsonNode source, String key, int defaultValue) { + if (source == null || !source.has(key) || source.get(key).isNull()) { return defaultValue; } - return source.get(key).getAsInt(); + return source.get(key).asInt(); } - private boolean getAsBoolean(JsonObject source, String key) { - return source != null && source.has(key) && !source.get(key).isJsonNull() && source.get(key).getAsBoolean(); + private boolean getAsBoolean(JsonNode source, String key) { + return source != null && source.has(key) && !source.get(key).isNull() && source.get(key).asBoolean(); } private String trimContainerName(String name) { diff --git a/src/main/java/com/imyeyu/api/modules/system/task/UpsStatusTask.java b/src/main/java/com/imyeyu/api/modules/system/task/UpsStatusTask.java index 1064bc9..f84eca1 100644 --- a/src/main/java/com/imyeyu/api/modules/system/task/UpsStatusTask.java +++ b/src/main/java/com/imyeyu/api/modules/system/task/UpsStatusTask.java @@ -28,7 +28,7 @@ public class UpsStatusTask implements SchedulingConfigurer { private final UpsStatusClient upsStatusClient; private final UpsStatusStore upsStatusStore; - @Value("${ups.collect-enabled:true}") + @Value("${ups.collect-enabled:false}") private boolean collectEnabled; @Value("${ups.collect-rate-ms:60000}") diff --git a/src/main/java/com/imyeyu/api/modules/system/util/DockerEngineClient.java b/src/main/java/com/imyeyu/api/modules/system/util/DockerEngineClient.java index 8e02292..abe64fd 100644 --- a/src/main/java/com/imyeyu/api/modules/system/util/DockerEngineClient.java +++ b/src/main/java/com/imyeyu/api/modules/system/util/DockerEngineClient.java @@ -1,7 +1,7 @@ package com.imyeyu.api.modules.system.util; -import com.google.gson.JsonElement; -import com.google.gson.JsonParser; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; import com.imyeyu.java.bean.timi.TimiCode; import com.imyeyu.java.bean.timi.TimiException; import lombok.extern.slf4j.Slf4j; @@ -36,13 +36,16 @@ public class DockerEngineClient { private final String host; private final String apiVersion; private final Duration timeout; + private final ObjectMapper jackson; private final HttpClient httpClient = HttpClient.newBuilder().build(); public DockerEngineClient( + ObjectMapper jackson, @Value("${docker.engine.host:unix:///var/run/docker.sock}") String host, @Value("${docker.engine.api-version:v1.41}") String apiVersion, @Value("${docker.engine.timeout-ms:5000}") long timeoutMs ) { + this.jackson = jackson; this.host = host; this.apiVersion = apiVersion; this.timeout = Duration.ofMillis(timeoutMs); @@ -55,13 +58,11 @@ public class DockerEngineClient { * @param queryParams 查询参数 * @return JSON 数据 */ - public JsonElement getJson(String path, Map queryParams) { + public JsonNode getJson(String path, Map queryParams) { String requestPath = buildRequestPath(path, queryParams); try { - String body = host.startsWith("unix://") - ? executeUnixGet(requestPath) - : executeHttpGet(requestPath); - return JsonParser.parseString(body); + String body = host.startsWith("unix://") ? executeUnixGet(requestPath) : executeHttpGet(requestPath); + return jackson.readTree(body); } catch (InterruptedException e) { Thread.currentThread().interrupt(); log.error("docker engine request interrupted: {}", requestPath, e); @@ -72,13 +73,6 @@ public class DockerEngineClient { } } - /** - * 构建请求路径 - * - * @param path 接口路径 - * @param queryParams 查询参数 - * @return 请求路径 - */ private String buildRequestPath(String path, Map queryParams) { StringBuilder builder = new StringBuilder(); builder.append("/"); @@ -101,14 +95,6 @@ public class DockerEngineClient { return builder.toString(); } - /** - * 通过 HTTP/TCP 执行 GET - * - * @param requestPath 请求路径 - * @return 响应体 - * @throws IOException IO 异常 - * @throws InterruptedException 中断异常 - */ private String executeHttpGet(String requestPath) throws IOException, InterruptedException { HttpRequest request = HttpRequest.newBuilder() .uri(URI.create(host + requestPath)) @@ -122,13 +108,6 @@ public class DockerEngineClient { return response.body(); } - /** - * 通过 Unix Socket 执行 GET - * - * @param requestPath 请求路径 - * @return 响应体 - * @throws IOException IO 异常 - */ private String executeUnixGet(String requestPath) throws IOException { String socketPath = host.substring("unix://".length()); UnixDomainSocketAddress address = UnixDomainSocketAddress.of(Path.of(socketPath)); @@ -147,13 +126,6 @@ public class DockerEngineClient { } } - /** - * 读取全部响应字节 - * - * @param channel 通道 - * @return 字节数组 - * @throws IOException IO 异常 - */ private byte[] readAll(SocketChannel channel) throws IOException { ByteBuffer buffer = ByteBuffer.allocate(8192); ByteArrayOutputStream output = new ByteArrayOutputStream(); @@ -172,13 +144,6 @@ public class DockerEngineClient { return output.toByteArray(); } - /** - * 解析 HTTP 响应体 - * - * @param responseBytes 响应字节 - * @return 响应体 - * @throws IOException IO 异常 - */ private String parseHttpBody(byte[] responseBytes) throws IOException { int splitIndex = indexOf(responseBytes, new byte[] {'\r', '\n', '\r', '\n'}); if (splitIndex < 0) { @@ -196,13 +161,6 @@ public class DockerEngineClient { return new String(bodyBytes, StandardCharsets.UTF_8); } - /** - * 解码 Chunked 响应体 - * - * @param bodyBytes 原始响应体 - * @return 解码后的响应体 - * @throws IOException IO 异常 - */ private byte[] decodeChunkedBody(byte[] bodyBytes) throws IOException { int offset = 0; ByteArrayOutputStream output = new ByteArrayOutputStream(); @@ -223,25 +181,10 @@ public class DockerEngineClient { return output.toByteArray(); } - /** - * 查找字节序列 - * - * @param source 原数组 - * @param pattern 目标数组 - * @return 下标 - */ private int indexOf(byte[] source, byte[] pattern) { return indexOf(source, 0, pattern); } - /** - * 从指定位置查找字节序列 - * - * @param source 原数组 - * @param start 起始位置 - * @param pattern 目标数组 - * @return 下标 - */ private int indexOf(byte[] source, int start, byte[] pattern) { for (int i = start; i <= source.length - pattern.length; i++) { boolean matched = true; @@ -258,12 +201,6 @@ public class DockerEngineClient { return -1; } - /** - * 创建查询参数映射 - * - * @param entries 键值对 - * @return 映射 - */ public static Map query(String... entries) { LinkedHashMap result = new LinkedHashMap<>(); for (int i = 0; i + 1 < entries.length; i += 2) { diff --git a/src/main/java/com/imyeyu/api/modules/system/util/UpsStatusClient.java b/src/main/java/com/imyeyu/api/modules/system/util/UpsStatusClient.java index 12baac0..afb8626 100644 --- a/src/main/java/com/imyeyu/api/modules/system/util/UpsStatusClient.java +++ b/src/main/java/com/imyeyu/api/modules/system/util/UpsStatusClient.java @@ -1,22 +1,19 @@ package com.imyeyu.api.modules.system.util; -import com.google.gson.JsonArray; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParser; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ArrayNode; import com.imyeyu.api.modules.system.bean.UpsStatusStore; import com.imyeyu.java.bean.timi.TimiCode; import com.imyeyu.java.bean.timi.TimiException; +import com.imyeyu.network.ArgMap; +import com.imyeyu.network.CommonRequest; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import java.io.IOException; -import java.net.URI; import java.net.http.HttpClient; -import java.net.http.HttpRequest; -import java.net.http.HttpResponse; -import java.nio.charset.StandardCharsets; import java.time.Duration; /** @@ -31,55 +28,35 @@ public class UpsStatusClient { private final String statusUrl; private final Duration timeout; + private final ObjectMapper jackson; private final HttpClient httpClient = HttpClient.newBuilder().build(); public UpsStatusClient( - @Value("${ups.status-url:}") String statusUrl, + ObjectMapper jackson, + @Value("${ups.status-url:http://192.168.3.24:15178/ViewPower/workstatus/reqMonitorData?0.9053892723012932}") String statusUrl, @Value("${ups.timeout-ms:5000}") long timeoutMs ) { + this.jackson = jackson; this.statusUrl = statusUrl; this.timeout = Duration.ofMillis(timeoutMs); } - /** - * 获取 UPS 状态 JSON - * - * @return JSON 数据 - */ - public JsonElement getStatusJson() { + public JsonNode getStatusJson() { if (statusUrl == null || statusUrl.isBlank()) { throw new TimiException(TimiCode.ARG_MISS).msgKey("缺少配置:ups.status-url"); } - - HttpRequest request = HttpRequest.newBuilder() - .uri(URI.create(statusUrl)) - .timeout(timeout) - .GET() - .build(); try { - HttpResponse response = httpClient.send(request, HttpResponse.BodyHandlers.ofString(StandardCharsets.UTF_8)); - if (400 <= response.statusCode()) { - throw new IOException("ups http error: " + response.statusCode()); - } - return JsonParser.parseString(response.body()); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - log.error("request ups status interrupted: {}", statusUrl, e); - throw new TimiException(TimiCode.ERROR).msgKey("UPS 状态请求被中断"); + String response = CommonRequest.post(statusUrl).bodyEntity(ArgMap.of("portName", "USBusbdev3").toEntity()).asString(); + return jackson.readTree(response); } catch (IOException e) { log.error("request ups status error: {}", statusUrl, e); throw new TimiException(TimiCode.ERROR).msgKey("UPS 状态请求失败"); } } - /** - * 拉取并解析 UPS 当前快照 - * - * @return UPS 当前快照 - */ public UpsStatusStore.Snapshot fetchSnapshot() { - JsonObject root = getStatusJson().getAsJsonObject(); - JsonObject workInfo = getAsObject(root, "workInfo"); + JsonNode root = getStatusJson(); + JsonNode workInfo = getAsObject(root, "workInfo"); UpsStatusStore.Snapshot snapshot = new UpsStatusStore.Snapshot(); snapshot.setUpsTime(readUpsTime(workInfo)); @@ -110,37 +87,25 @@ public class UpsStatusClient { return snapshot; } - /** - * 读取 UPS 时间戳 - * - * @param workInfo 工作信息 - * @return 时间戳 - */ - private Long readUpsTime(JsonObject workInfo) { - JsonObject currentTime = getAsObject(workInfo, "currentTime"); - if (currentTime == null || !currentTime.has("time") || currentTime.get("time").isJsonNull()) { + private Long readUpsTime(JsonNode workInfo) { + JsonNode currentTime = getAsObject(workInfo, "currentTime"); + if (currentTime == null || !currentTime.has("time") || currentTime.get("time").isNull()) { return null; } - return currentTime.get("time").getAsLong(); + return currentTime.get("time").asLong(); } - /** - * 读取告警列表 - * - * @param workInfo 工作信息 - * @return 告警列表 - */ - private java.util.List readWarnings(JsonObject workInfo) { + private java.util.List readWarnings(JsonNode workInfo) { java.util.List warnings = new java.util.ArrayList<>(); - if (workInfo == null || !workInfo.has("warnings") || !workInfo.get("warnings").isJsonArray()) { + if (workInfo == null || !workInfo.has("warnings") || !workInfo.get("warnings").isArray()) { return warnings; } - JsonArray array = workInfo.getAsJsonArray("warnings"); - for (JsonElement item : array) { - if (!item.isJsonPrimitive()) { + ArrayNode array = (ArrayNode) workInfo.get("warnings"); + for (JsonNode item : array) { + if (!item.isValueNode()) { continue; } - String warning = normalizeText(item.getAsString()); + String warning = normalizeText(item.asText()); if (warning != null) { warnings.add(warning); } @@ -148,50 +113,29 @@ public class UpsStatusClient { return warnings; } - /** - * 读取对象字段 - * - * @param source 源对象 - * @param key 键 - * @return 子对象 - */ - private JsonObject getAsObject(JsonObject source, String key) { - if (source == null || !source.has(key) || source.get(key).isJsonNull() || !source.get(key).isJsonObject()) { + private JsonNode getAsObject(JsonNode source, String key) { + if (source == null || !source.has(key) || source.get(key).isNull() || !source.get(key).isObject()) { return null; } - return source.getAsJsonObject(key); + return source.get(key); } - /** - * 读取有效文本 - * - * @param source 源对象 - * @param key 键 - * @return 文本 - */ - private String readMeaningfulText(JsonObject source, String key) { - if (source == null || !source.has(key) || source.get(key).isJsonNull()) { + private String readMeaningfulText(JsonNode source, String key) { + if (source == null || !source.has(key) || source.get(key).isNull()) { return null; } - return normalizeText(source.get(key).getAsString()); + return normalizeText(source.get(key).asText()); } - /** - * 读取有效整数 - * - * @param source 源对象 - * @param key 键 - * @return 整数 - */ - private Integer readMeaningfulInteger(JsonObject source, String key) { - if (source == null || !source.has(key) || source.get(key).isJsonNull()) { + private Integer readMeaningfulInteger(JsonNode source, String key) { + if (source == null || !source.has(key) || source.get(key).isNull()) { return null; } - JsonElement element = source.get(key); - if (element.isJsonPrimitive() && element.getAsJsonPrimitive().isNumber()) { - return element.getAsInt(); + JsonNode element = source.get(key); + if (element.isNumber()) { + return element.asInt(); } - String text = normalizeText(element.getAsString()); + String text = normalizeText(element.asText()); if (text == null) { return null; } @@ -202,22 +146,15 @@ public class UpsStatusClient { } } - /** - * 读取有效小数 - * - * @param source 源对象 - * @param key 键 - * @return 小数 - */ - private Double readMeaningfulDouble(JsonObject source, String key) { - if (source == null || !source.has(key) || source.get(key).isJsonNull()) { + private Double readMeaningfulDouble(JsonNode source, String key) { + if (source == null || !source.has(key) || source.get(key).isNull()) { return null; } - JsonElement element = source.get(key); - if (element.isJsonPrimitive() && element.getAsJsonPrimitive().isNumber()) { - return element.getAsDouble(); + JsonNode element = source.get(key); + if (element.isNumber()) { + return element.asDouble(); } - String text = normalizeText(element.getAsString()); + String text = normalizeText(element.asText()); if (text == null) { return null; } @@ -228,23 +165,10 @@ public class UpsStatusClient { } } - /** - * 读取布尔值 - * - * @param source 源对象 - * @param key 键 - * @return 布尔值 - */ - private boolean readAsBoolean(JsonObject source, String key) { - return source != null && source.has(key) && !source.get(key).isJsonNull() && source.get(key).getAsBoolean(); + private boolean readAsBoolean(JsonNode source, String key) { + return source != null && source.has(key) && !source.get(key).isNull() && source.get(key).asBoolean(); } - /** - * 规范化文本 - * - * @param text 原始文本 - * @return 规范化后的文本 - */ private String normalizeText(String text) { if (text == null) { return null; diff --git a/src/main/java/com/imyeyu/api/util/GsonSerializerAdapter.java b/src/main/java/com/imyeyu/api/util/GsonSerializerAdapter.java deleted file mode 100644 index 9a0a071..0000000 --- a/src/main/java/com/imyeyu/api/util/GsonSerializerAdapter.java +++ /dev/null @@ -1,60 +0,0 @@ -package com.imyeyu.api.util; - -import com.google.gson.Gson; -import com.google.gson.JsonElement; -import com.google.gson.JsonSerializationContext; -import com.google.gson.JsonSerializer; -import com.imyeyu.java.TimiJava; -import com.imyeyu.java.ref.Ref; -import com.imyeyu.api.TimiServerAPI; -import com.imyeyu.api.bean.MultilingualHandler; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Component; - -import java.lang.reflect.Field; -import java.lang.reflect.Type; -import java.util.List; - -/** - * @author 夜雨 - * @version 2023-10-26 10:16 - */ -@Slf4j -@Component -@RequiredArgsConstructor -public class GsonSerializerAdapter implements JsonSerializer { - - private final Gson gson; - private final RedisMultilingual redisMultilingual; - - @Override - public JsonElement serialize(Object value, Type typeOfSrc, JsonSerializationContext context) { - if (value instanceof MultilingualHandler _value) { - fillMultilingual(_value); - } - return gson.toJsonTree(value); - } - - private void fillMultilingual(K value) { - try { - List fields = Ref.listFields(value.getClass()); - for (int i = 0; i < fields.size(); i++) { - Field field = fields.get(i); - MultilingualHandler.MultilingualField multiField = field.getAnnotation(MultilingualHandler.MultilingualField.class); - if (multiField != null) { - String multiLangId = Ref.getFieldValue(value, field, String.class); - if (TimiJava.isNotEmpty(multiLangId)) { - Long langId = Long.parseLong(multiLangId); - if (redisMultilingual.map(TimiServerAPI.getUserLanguage()) instanceof RedisLanguage rl) { - // TODO 支持插值参数 - Ref.setFieldValue(value, field, rl.text(langId)); - } - } - } - } - } catch (IllegalAccessException e) { - throw new RuntimeException(e); - } - } -} diff --git a/src/main/java/com/imyeyu/api/util/InitApplication.java b/src/main/java/com/imyeyu/api/util/InitApplication.java index 9af6687..aa8408d 100644 --- a/src/main/java/com/imyeyu/api/util/InitApplication.java +++ b/src/main/java/com/imyeyu/api/util/InitApplication.java @@ -1,8 +1,8 @@ package com.imyeyu.api.util; -import com.google.gson.JsonArray; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.node.ArrayNode; +import com.fasterxml.jackson.databind.node.ObjectNode; import com.imyeyu.api.TimiServerAPI; import com.imyeyu.api.modules.common.bean.SettingKey; import com.imyeyu.api.modules.common.entity.Multilingual; @@ -88,22 +88,22 @@ public class InitApplication implements ApplicationRunner { } private void initFileType() { - JsonObject items = settingService.getAsJsonObject(SettingKey.SYSTEM_FILE_TYPE); + ObjectNode items = settingService.getAsJsonObject(SettingKey.SYSTEM_FILE_TYPE); String[] extensions; - JsonArray extensionsArray; - JsonObject itemObject; + ArrayNode extensionsArray; + JsonNode itemObject; List extensionsList; - for (Map.Entry item : items.entrySet()) { + for (Map.Entry item : (Iterable>) items::fields) { ServerFile.FileType fileType = Ref.toType(ServerFile.FileType.class, item.getKey()); - itemObject = item.getValue().getAsJsonObject(); + itemObject = item.getValue(); extensionsList = new ArrayList<>(); - extensionsArray = itemObject.get("extensions").getAsJsonArray(); - for (int i = 0; i < extensionsArray.size(); i++) { - if (extensionsArray.get(i).isJsonObject()) { - extensionsList.add(extensionsArray.get(i).getAsJsonObject().get("value").getAsString()); + extensionsArray = (ArrayNode) itemObject.get("extensions"); + for (JsonNode extensionNode : extensionsArray) { + if (extensionNode.isObject()) { + extensionsList.add(extensionNode.path("value").asText()); } else { - extensionsList.add(extensionsArray.get(i).getAsString()); + extensionsList.add(extensionNode.asText()); } } extensions = new String[extensionsList.size()]; diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index a47f817..aed4226 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -40,9 +40,6 @@ spring: enable: true required: true default-encoding: UTF-8 - mvc: # JSON 序列化 - converters: - preferred-json-mapper: gson # 返回 JSON 序列化使用 GSON redis: # Redis 数据库 host: dev.vm.imyeyu.test port: 6379