From fed1404ab4f5bcb9ebaa7a8bddd922c47ad371d3 Mon Sep 17 00:00:00 2001 From: Date: Sun, 16 Mar 2025 04:06:27 +0000 Subject: [PATCH] =?UTF-8?q?2025/3/16=2012:06:03---=E8=B0=83=E6=95=B4?= =?UTF-8?q?=E6=9F=A5=E8=AF=A2=E6=95=B0=E6=8D=AE=E8=BD=AC=E6=8D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- camel-mybatis-yml/RequestProcessor.java | 161 ++++++++++++++++++++--- camel-mybatis-yml/UserMapper.xml | 17 ++- camel-mybatis-yml/application.properties | 2 +- 3 files changed, 157 insertions(+), 23 deletions(-) diff --git a/camel-mybatis-yml/RequestProcessor.java b/camel-mybatis-yml/RequestProcessor.java index 17197f9..a96b30c 100644 --- a/camel-mybatis-yml/RequestProcessor.java +++ b/camel-mybatis-yml/RequestProcessor.java @@ -2,35 +2,56 @@ package com.example.processor; import com.example.model.AdvancedSearchRequest; import com.example.model.PageRequest; -import com.alibaba.fastjson.JSON; -import com.alibaba.fastjson.JSONObject; -import com.alibaba.fastjson.serializer.SerializeConfig; -import com.alibaba.fastjson.serializer.SerializerFeature; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.module.SimpleModule; + +import org.apache.camel.Configuration; +import org.apache.camel.BindToRegistry; import org.apache.camel.Exchange; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.io.IOException; +import java.text.ParseException; +import java.text.SimpleDateFormat; import java.util.Date; import java.util.HashMap; +import java.util.List; import java.util.Map; +import java.sql.Timestamp; /** * 统一请求处理器 * 适用于Camel Karavan低代码平台配置 * 通用处理器,不依赖于特定实体类型 */ +@Configuration +@BindToRegistry("requestProcessor") public class RequestProcessor { private static final Logger LOGGER = LoggerFactory.getLogger(RequestProcessor.class); - private final SerializeConfig serializeConfig; + private final ObjectMapper objectMapper; public RequestProcessor() { - // 配置Fastjson序列化 - serializeConfig = new SerializeConfig(); - // 配置日期序列化为时间戳 - serializeConfig.put(Date.class, (serializer, object, fieldName, fieldType, features) -> { - serializer.write(((Date) object).getTime()); + // 配置Jackson序列化 + objectMapper = new ObjectMapper(); + // 启用日期序列化为时间戳 + objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, true); + + // 添加Date序列化器 + SimpleModule module = new SimpleModule(); + module.addSerializer(Date.class, new JsonSerializer() { + @Override + public void serialize(Date value, JsonGenerator gen, SerializerProvider provider) + throws IOException { + gen.writeNumber(value.getTime()); + } }); + objectMapper.registerModule(module); } /** @@ -50,7 +71,7 @@ public class RequestProcessor { if(body instanceof String){ String bodyStr = (String) body; LOGGER.info("分页拿到的请求body: {}", bodyStr); - pageRequest = JSON.parseObject(bodyStr, PageRequest.class); + pageRequest = objectMapper.readValue(bodyStr, PageRequest.class); // 保存请求对象供后续使用 exchange.setProperty("pageRequest", pageRequest); @@ -58,7 +79,7 @@ public class RequestProcessor { @SuppressWarnings("unchecked") Map bodyMap = (Map) body; LOGGER.info("分页拿到的请求body: {}", bodyMap); - pageRequest = JSONObject.toJavaObject(new JSONObject(bodyMap), PageRequest.class); + pageRequest = objectMapper.convertValue(bodyMap, PageRequest.class); }else{ // 处理其他类型或null LOGGER.warn("无法处理的请求体类型: {}", body != null ? body.getClass().getName() : "null"); @@ -102,14 +123,14 @@ public class RequestProcessor { if(body instanceof String){ String bodyStr = (String) body; LOGGER.info("高级搜索拿到的请求body: {}", bodyStr); - searchRequest = JSON.parseObject(bodyStr, AdvancedSearchRequest.class); + searchRequest = objectMapper.readValue(bodyStr, AdvancedSearchRequest.class); }else if(body instanceof Map){ @SuppressWarnings("unchecked") Map bodyMap = (Map) body; LOGGER.info("高级搜索拿到的请求body: {}", bodyMap); - searchRequest = JSONObject.toJavaObject(new JSONObject(bodyMap), AdvancedSearchRequest.class); - }else if(body instanceof JSONObject){ - searchRequest = JSONObject.toJavaObject((JSONObject)body, AdvancedSearchRequest.class); + searchRequest = objectMapper.convertValue(bodyMap, AdvancedSearchRequest.class); + }else if(body instanceof ObjectMapper){ + searchRequest = objectMapper.convertValue(body, AdvancedSearchRequest.class); }else{ LOGGER.warn("无法处理的请求体类型: {}", body != null ? body.getClass().getName() : "null"); searchRequest = new AdvancedSearchRequest(); @@ -118,11 +139,13 @@ public class RequestProcessor { // 保存请求对象供后续使用 exchange.setProperty("searchRequest", searchRequest); - // 使用日期序列化为时间戳的配置序列化对象 - String searchRequestStr = JSON.toJSONString(searchRequest, serializeConfig, SerializerFeature.WriteMapNullValue); + // 使用日期序列化为时间戳 + String searchRequestStr = objectMapper.writeValueAsString(searchRequest); + LOGGER.info("searchRequest转json字符串: {}", searchRequestStr); @SuppressWarnings("unchecked") - Map params = JSON.parseObject(searchRequestStr, Map.class); + Map params = convertJsonWithDates(searchRequestStr); + LOGGER.info("转换后参数: {}", params); return params; } @@ -153,7 +176,7 @@ public class RequestProcessor { */ public T prepareEntity(Exchange exchange, Class entityClass) throws Exception { String body = exchange.getIn().getBody(String.class); - T entity = JSON.parseObject(body, entityClass); + T entity = objectMapper.readValue(body, entityClass); // 通过反射设置创建和更新时间(如果实体有这些字段) try { @@ -210,7 +233,7 @@ public class RequestProcessor { Long id = Long.parseLong(idStr); String body = exchange.getIn().getBody(String.class); - T entity = JSON.parseObject(body, entityClass); + T entity = objectMapper.readValue(body, entityClass); // 通过反射设置ID和更新时间 try { @@ -273,4 +296,100 @@ public class RequestProcessor { public void setStatusCode(Exchange exchange, int code) { exchange.getIn().setHeader(Exchange.HTTP_RESPONSE_CODE, code); } + + public Map convertJsonWithDates(String json) throws Exception { + // 将JSON字符串转为Map + ObjectMapper mapper = new ObjectMapper(); + Map map = mapper.readValue(json, Map.class); + + // 递归处理日期字段 + processDateFields(map); + + return map; + } + + @SuppressWarnings("unchecked") + private void processDateFields(Object obj) throws ParseException { + if (obj instanceof Map) { + Map map = (Map) obj; + + // 处理Map中的每个键值对 + for (Map.Entry entry : map.entrySet()) { + String key = entry.getKey(); + Object value = entry.getValue(); + + if (value instanceof String && isDateString((String) value)) { + // 如果是日期字符串,则转换为时间戳 + map.put(key, parseTimestamp((String) value)); + } else if (value instanceof List) { + // 处理数组 + processList((List) value); + } else if (value instanceof Map) { + // 递归处理子Map + processDateFields(value); + } + } + + // 特殊处理criteria字段 + if (map.containsKey("criteria") && map.get("criteria") instanceof List) { + processList((List) map.get("criteria")); + } + } + } + + @SuppressWarnings("unchecked") + private void processList(List list) throws ParseException { + for (int i = 0; i < list.size(); i++) { + Object item = list.get(i); + + if (item instanceof String && isDateString((String) item)) { + // 如果是日期字符串,则转换为时间戳 + list.set(i, parseTimestamp((String) item)); + } else if (item instanceof Map) { + Map mapItem = (Map) item; + processDateFields(mapItem); + + // 特殊处理value为数组的情况(如BETWEEN操作符) + if (mapItem.containsKey("value") && mapItem.get("value") instanceof List) { + processList((List) mapItem.get("value")); + } + + // 处理subCriteria + if (mapItem.containsKey("subCriteria") && mapItem.get("subCriteria") instanceof List) { + processList((List) mapItem.get("subCriteria")); + } + } else if (item instanceof List) { + // 递归处理子List + processList((List) item); + } + } + } + + // private boolean isDateString(String str) { + // // 检查字符串是否符合ISO日期格式 "yyyy-MM-dd'T'HH:mm:ss" + // return str.matches("\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}"); + // } + private boolean isDateString(String str) { + // 修改正则表达式匹配更多日期格式(包括带毫秒和时区的格式) + return str.matches("\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d+)?(Z|[+-]\\d{2}:?\\d{2})?"); + } + + // private long parseTimestamp(String dateStr) throws ParseException { + // SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss"); + // return sdf.parse(dateStr).getTime(); + // } + // private Timestamp parseTimestamp(String dateStr) throws ParseException { + // SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss"); + // return new Timestamp(sdf.parse(dateStr).getTime()); + // } + private Timestamp parseTimestamp(String dateStr) throws ParseException { + try { + // 尝试直接解析ISO格式(带时区) + return Timestamp.valueOf(dateStr.replace('T', ' ').substring(0, 19)); + } catch (Exception e) { + // 回退到使用SimpleDateFormat + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss"); + return new Timestamp(sdf.parse(dateStr).getTime()); + } + } } \ No newline at end of file diff --git a/camel-mybatis-yml/UserMapper.xml b/camel-mybatis-yml/UserMapper.xml index 7eadbed..6ec2e58 100644 --- a/camel-mybatis-yml/UserMapper.xml +++ b/camel-mybatis-yml/UserMapper.xml @@ -182,7 +182,22 @@ - created_at BETWEEN #{criterion.value[0]} AND #{criterion.value[1]} + + + + + + + + created_at BETWEEN + (#{criterion.value[0]}::timestamp with time zone) AND + (#{criterion.value[1]}::timestamp with time zone) updated_at BETWEEN #{criterion.value[0]} AND #{criterion.value[1]} diff --git a/camel-mybatis-yml/application.properties b/camel-mybatis-yml/application.properties index abcc43f..e0addaa 100644 --- a/camel-mybatis-yml/application.properties +++ b/camel-mybatis-yml/application.properties @@ -23,4 +23,4 @@ camel.health.exposure-level=full jkube.version=1.18.0 jib.from.image=gcr.io/distroless/java17@sha256:68e2373f7bef9486c08356bd9ffd3b40b56e6b9316c5f6885eb58b1d9093b43d -camel.component.mybatis.configurationUri=classpath:SqlMapConfig.xml \ No newline at end of file +camel.component.mybatis.configurationUri=classpath:SqlMapConfig.xml