diff --git a/APIJSON-Java-Server/APIJSONBoot-MultiDataSource/libs/APIJSON-7.0.3.jar b/APIJSON-Java-Server/APIJSONBoot-BigData/libs/APIJSON-7.0.3.jar similarity index 100% rename from APIJSON-Java-Server/APIJSONBoot-MultiDataSource/libs/APIJSON-7.0.3.jar rename to APIJSON-Java-Server/APIJSONBoot-BigData/libs/APIJSON-7.0.3.jar diff --git a/APIJSON-Java-Server/APIJSONBoot-BigData/libs/apijson-column-2.0.3.jar b/APIJSON-Java-Server/APIJSONBoot-BigData/libs/apijson-column-2.0.3.jar new file mode 100644 index 00000000..b8d3c257 Binary files /dev/null and b/APIJSON-Java-Server/APIJSONBoot-BigData/libs/apijson-column-2.0.3.jar differ diff --git a/APIJSON-Java-Server/APIJSONBoot-BigData/libs/apijson-framework-7.0.3.jar b/APIJSON-Java-Server/APIJSONBoot-BigData/libs/apijson-framework-7.0.3.jar new file mode 100644 index 00000000..3c3341e9 Binary files /dev/null and b/APIJSON-Java-Server/APIJSONBoot-BigData/libs/apijson-framework-7.0.3.jar differ diff --git a/APIJSON-Java-Server/APIJSONBoot-BigData/libs/apijson-router-2.0.3.jar b/APIJSON-Java-Server/APIJSONBoot-BigData/libs/apijson-router-2.0.3.jar new file mode 100644 index 00000000..6576ef9b Binary files /dev/null and b/APIJSON-Java-Server/APIJSONBoot-BigData/libs/apijson-router-2.0.3.jar differ diff --git a/APIJSON-Java-Server/APIJSONBoot-BigData/libs/unitauto-jar-3.0.5.jar b/APIJSON-Java-Server/APIJSONBoot-BigData/libs/unitauto-jar-3.0.5.jar new file mode 100644 index 00000000..346459ce Binary files /dev/null and b/APIJSON-Java-Server/APIJSONBoot-BigData/libs/unitauto-jar-3.0.5.jar differ diff --git a/APIJSON-Java-Server/APIJSONBoot-BigData/libs/unitauto-java-3.0.5.jar b/APIJSON-Java-Server/APIJSONBoot-BigData/libs/unitauto-java-3.0.5.jar new file mode 100644 index 00000000..cc636d7f Binary files /dev/null and b/APIJSON-Java-Server/APIJSONBoot-BigData/libs/unitauto-java-3.0.5.jar differ diff --git a/APIJSON-Java-Server/APIJSONBoot-BigData/pom.xml b/APIJSON-Java-Server/APIJSONBoot-BigData/pom.xml index 8a7b0fc0..ff46cf9e 100755 --- a/APIJSON-Java-Server/APIJSONBoot-BigData/pom.xml +++ b/APIJSON-Java-Server/APIJSONBoot-BigData/pom.xml @@ -5,7 +5,7 @@ apijson.boot apijson-boot - 7.0.3 + 7.1.5 jar APIJSONBoot-BigData @@ -14,7 +14,10 @@ UTF-8 UTF-8 - 1.8 + 17 + UTF-8 + 17 + 17 @@ -36,12 +39,12 @@ com.github.TommyLemon unitauto-java - 2.9.0 + 3.0.5 com.github.TommyLemon unitauto-jar - 2.9.0 + 3.0.5 io.github.classgraph @@ -55,17 +58,17 @@ com.github.Tencent APIJSON - 7.0.3 + 7.1.0 com.github.APIJSON apijson-framework - 7.0.3 + 7.1.5 com.github.APIJSON apijson-column - 2.0.3 + 2.1.0 @@ -110,6 +113,7 @@ org.springframework.boot spring-boot-maven-plugin + 3.2.5 @@ -121,9 +125,10 @@ org.apache.maven.plugins maven-compiler-plugin + 3.8.1 - 1.8 - 1.8 + 17 + 17 diff --git a/APIJSON-Java-Server/APIJSONBoot-BigData/src/main/java/apijson/boot/DemoApplication.java b/APIJSON-Java-Server/APIJSONBoot-BigData/src/main/java/apijson/boot/DemoApplication.java index 83c9e730..f2206c13 100755 --- a/APIJSON-Java-Server/APIJSONBoot-BigData/src/main/java/apijson/boot/DemoApplication.java +++ b/APIJSON-Java-Server/APIJSONBoot-BigData/src/main/java/apijson/boot/DemoApplication.java @@ -43,9 +43,9 @@ import apijson.demo.DemoSQLConfig; import apijson.demo.DemoSQLExecutor; import apijson.demo.DemoVerifier; -import apijson.framework.APIJSONApplication; -import apijson.framework.APIJSONCreator; -import apijson.framework.APIJSONParser; +import apijson.framework.javax.APIJSONApplication; +import apijson.framework.javax.APIJSONCreator; +import apijson.framework.javax.APIJSONParser; import apijson.orm.AbstractVerifier; import apijson.orm.FunctionParser; import apijson.orm.Parser; @@ -96,7 +96,7 @@ public void customize(ConfigurableServletWebServerFactory server) { // 支持 APIAuto 中 JavaScript 代码跨域请求 @Bean - public WebMvcConfigurer corsConfigurer() { + public WebMvcConfigurer corsConfig() { return new WebMvcConfigurer() { @Override public void addCorsMappings(CorsRegistry registry) { @@ -188,7 +188,7 @@ public Parser createParser() { } @Override - public FunctionParser createFunctionParser() { + public FunctionParser createFunctionParser() { return new DemoFunctionParser(); } @@ -198,12 +198,12 @@ public Verifier createVerifier() { } @Override - public SQLConfig createSQLConfig() { + public SQLConfig createSQLConfig() { return new DemoSQLConfig(); } @Override - public SQLExecutor createSQLExecutor() { + public SQLExecutor createSQLExecutor() { return new DemoSQLExecutor(); } diff --git a/APIJSON-Java-Server/APIJSONBoot-BigData/src/main/java/apijson/boot/DemoController.java b/APIJSON-Java-Server/APIJSONBoot-BigData/src/main/java/apijson/boot/DemoController.java index e6d70aa2..590aa4d2 100644 --- a/APIJSON-Java-Server/APIJSONBoot-BigData/src/main/java/apijson/boot/DemoController.java +++ b/APIJSON-Java-Server/APIJSONBoot-BigData/src/main/java/apijson/boot/DemoController.java @@ -21,14 +21,14 @@ import static apijson.RequestMethod.HEADS; import static apijson.RequestMethod.POST; import static apijson.RequestMethod.PUT; -import static apijson.framework.APIJSONConstant.ACCESS_; -import static apijson.framework.APIJSONConstant.COUNT; -import static apijson.framework.APIJSONConstant.FORMAT; -import static apijson.framework.APIJSONConstant.FUNCTION_; -import static apijson.framework.APIJSONConstant.ID; -import static apijson.framework.APIJSONConstant.REQUEST_; -import static apijson.framework.APIJSONConstant.USER_ID; -import static apijson.framework.APIJSONConstant.VERSION; +import static apijson.framework.javax.APIJSONConstant.ACCESS_; +import static apijson.framework.javax.APIJSONConstant.COUNT; +import static apijson.framework.javax.APIJSONConstant.FORMAT; +import static apijson.framework.javax.APIJSONConstant.FUNCTION_; +import static apijson.framework.javax.APIJSONConstant.ID; +import static apijson.framework.javax.APIJSONConstant.REQUEST_; +import static apijson.framework.javax.APIJSONConstant.USER_ID; +import static apijson.framework.javax.APIJSONConstant.VERSION; import static org.springframework.http.HttpHeaders.COOKIE; import static org.springframework.http.HttpHeaders.SET_COOKIE; @@ -49,6 +49,7 @@ import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; +import apijson.orm.Parser; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; @@ -78,8 +79,8 @@ import apijson.demo.model.Privacy; import apijson.demo.model.User; import apijson.demo.model.Verify; -import apijson.framework.APIJSONController; -import apijson.framework.BaseModel; +import apijson.framework.javax.APIJSONController; +import apijson.framework.javax.BaseModel; import apijson.orm.JSONRequest; import apijson.orm.exception.ConditionErrorException; import apijson.orm.exception.ConflictException; @@ -110,13 +111,15 @@ public String getRequestURL() { return httpServletRequest.getRequestURL().toString(); } - + @Override + public Parser newParser(HttpSession session, RequestMethod method) { + return super.newParser(session, method).setNeedVerify(false); + } + // 通用接口,非事务型操作 和 简单事务型操作 都可通过这些接口自动化实现 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< /**增删改查统一入口,这个一个方法可替代以下 7 个方法,牺牲一些路由解析性能来提升一点开发效率 * @param method - * @param tag - * @param params * @param request * @param session * @return diff --git a/APIJSON-Java-Server/APIJSONBoot-BigData/src/main/java/apijson/demo/DemoFunctionParser.java b/APIJSON-Java-Server/APIJSONBoot-BigData/src/main/java/apijson/demo/DemoFunctionParser.java index c2d75054..6b641ede 100644 --- a/APIJSON-Java-Server/APIJSONBoot-BigData/src/main/java/apijson/demo/DemoFunctionParser.java +++ b/APIJSON-Java-Server/APIJSONBoot-BigData/src/main/java/apijson/demo/DemoFunctionParser.java @@ -28,7 +28,7 @@ import apijson.NotNull; import apijson.RequestMethod; import apijson.StringUtil; -import apijson.framework.APIJSONFunctionParser; +import apijson.framework.javax.APIJSONFunctionParser; import apijson.orm.AbstractVerifier; import apijson.orm.JSONRequest; import apijson.orm.Visitor; @@ -38,7 +38,7 @@ * 具体见 https://github.com/Tencent/APIJSON/issues/101 * @author Lemon */ -public class DemoFunctionParser extends APIJSONFunctionParser { +public class DemoFunctionParser extends APIJSONFunctionParser { public static final String TAG = "DemoFunctionParser"; public DemoFunctionParser() { diff --git a/APIJSON-Java-Server/APIJSONBoot-BigData/src/main/java/apijson/demo/DemoObjectParser.java b/APIJSON-Java-Server/APIJSONBoot-BigData/src/main/java/apijson/demo/DemoObjectParser.java index f177a9db..c789fc2b 100644 --- a/APIJSON-Java-Server/APIJSONBoot-BigData/src/main/java/apijson/demo/DemoObjectParser.java +++ b/APIJSON-Java-Server/APIJSONBoot-BigData/src/main/java/apijson/demo/DemoObjectParser.java @@ -22,7 +22,7 @@ import apijson.NotNull; import apijson.RequestMethod; -import apijson.framework.APIJSONObjectParser; +import apijson.framework.javax.APIJSONObjectParser; import apijson.orm.Join; import apijson.orm.SQLConfig; @@ -30,7 +30,7 @@ /**对象解析器,用来简化 Parser * @author Lemon */ -public class DemoObjectParser extends APIJSONObjectParser { +public class DemoObjectParser extends APIJSONObjectParser { public DemoObjectParser(HttpSession session, @NotNull JSONObject request, String parentPath, SQLConfig arrayConfig , boolean isSubquery, boolean isTable, boolean isArrayMainTable) throws Exception { diff --git a/APIJSON-Java-Server/APIJSONBoot-BigData/src/main/java/apijson/demo/DemoParser.java b/APIJSON-Java-Server/APIJSONBoot-BigData/src/main/java/apijson/demo/DemoParser.java index 08103166..9ed3491e 100644 --- a/APIJSON-Java-Server/APIJSONBoot-BigData/src/main/java/apijson/demo/DemoParser.java +++ b/APIJSON-Java-Server/APIJSONBoot-BigData/src/main/java/apijson/demo/DemoParser.java @@ -17,8 +17,8 @@ import com.alibaba.fastjson.JSONObject; import apijson.RequestMethod; -import apijson.framework.APIJSONObjectParser; -import apijson.framework.APIJSONParser; +import apijson.framework.javax.APIJSONObjectParser; +import apijson.framework.javax.APIJSONParser; import apijson.orm.SQLConfig; @@ -46,7 +46,7 @@ public DemoParser(RequestMethod method, boolean needVerify) { @Override - public APIJSONObjectParser createObjectParser(JSONObject request, String parentPath, SQLConfig arrayConfig + public APIJSONObjectParser createObjectParser(JSONObject request, String parentPath, SQLConfig arrayConfig , boolean isSubquery, boolean isTable, boolean isArrayMainTable) throws Exception { return new DemoObjectParser(getSession(), request, parentPath, arrayConfig , isSubquery, isTable, isArrayMainTable).setMethod(getMethod()).setParser(this); diff --git a/APIJSON-Java-Server/APIJSONBoot-BigData/src/main/java/apijson/demo/DemoSQLConfig.java b/APIJSON-Java-Server/APIJSONBoot-BigData/src/main/java/apijson/demo/DemoSQLConfig.java index 57a7eb2f..0192b96b 100755 --- a/APIJSON-Java-Server/APIJSONBoot-BigData/src/main/java/apijson/demo/DemoSQLConfig.java +++ b/APIJSON-Java-Server/APIJSONBoot-BigData/src/main/java/apijson/demo/DemoSQLConfig.java @@ -14,10 +14,10 @@ package apijson.demo; -import static apijson.framework.APIJSONConstant.ID; -import static apijson.framework.APIJSONConstant.PRIVACY_; -import static apijson.framework.APIJSONConstant.USER_; -import static apijson.framework.APIJSONConstant.USER_ID; +import static apijson.framework.javax.APIJSONConstant.ID; +import static apijson.framework.javax.APIJSONConstant.PRIVACY_; +import static apijson.framework.javax.APIJSONConstant.USER_; +import static apijson.framework.javax.APIJSONConstant.USER_ID; import java.text.SimpleDateFormat; import java.util.Arrays; @@ -31,7 +31,7 @@ import apijson.RequestMethod; import apijson.StringUtil; import apijson.column.ColumnUtil; -import apijson.framework.APIJSONSQLConfig; +import apijson.framework.javax.APIJSONSQLConfig; import apijson.orm.AbstractSQLConfig; import apijson.orm.Join; import apijson.orm.Join.On; @@ -309,8 +309,8 @@ protected void onJoinNotRelation(String sql, String quote, Join join, String tab } @Override - protected void onJoinComplextRelation(String sql, String quote, Join j, String jt, List onList, On on) { - // 开启 JOIN ON t1.c1 LIKE concat('%', t2.c2, '%') 等复杂关联 super.onJoinComplextRelation(sql, quote, j, jt, onList, on); + protected void onJoinComplexRelation(String sql, String quote, Join j, String jt, List onList, On on) { + // 开启 JOIN ON t1.c1 LIKE concat('%', t2.c2, '%') 等复杂关联 super.onJoinComplexRelation(sql, quote, j, jt, onList, on); } } diff --git a/APIJSON-Java-Server/APIJSONBoot-BigData/src/main/java/apijson/demo/DemoSQLExecutor.java b/APIJSON-Java-Server/APIJSONBoot-BigData/src/main/java/apijson/demo/DemoSQLExecutor.java index 6119a689..1d48c5fe 100644 --- a/APIJSON-Java-Server/APIJSONBoot-BigData/src/main/java/apijson/demo/DemoSQLExecutor.java +++ b/APIJSON-Java-Server/APIJSONBoot-BigData/src/main/java/apijson/demo/DemoSQLExecutor.java @@ -20,7 +20,7 @@ import apijson.Log; import apijson.boot.DemoApplication; -import apijson.framework.APIJSONSQLExecutor; +import apijson.framework.javax.APIJSONSQLExecutor; import apijson.orm.SQLConfig; @@ -49,13 +49,13 @@ public class DemoSQLExecutor extends APIJSONSQLExecutor { @Override public Connection getConnection(SQLConfig config) throws Exception { Log.d(TAG, "getConnection config.getDatasource() = " + config.getDatasource()); - - Connection c = connectionMap.get(config.getDatabase()); + String connectionKey = config.getDatasource() + "-" + config.getDatabase(); + Connection c = connectionMap.get(connectionKey); if (c == null || c.isClosed()) { try { DataSource ds = DemoApplication.getApplicationContext().getBean(DataSource.class); // 另一种方式是 DruidConfig 初始化获取到 Datasource 后给静态变量 DATA_SOURCE 赋值: ds = DruidConfig.DATA_SOURCE.getConnection(); - connectionMap.put(config.getDatabase(), ds == null ? null : ds.getConnection()); + connectionMap.put(connectionKey, ds == null ? null : ds.getConnection()); } catch (Exception e) { Log.e(TAG, "getConnection try { " + "DataSource ds = DemoApplication.getApplicationContext().getBean(DataSource.class); .." diff --git a/APIJSON-Java-Server/APIJSONBoot-BigData/src/main/java/apijson/demo/DemoVerifier.java b/APIJSON-Java-Server/APIJSONBoot-BigData/src/main/java/apijson/demo/DemoVerifier.java index 97b39129..1a0ee189 100644 --- a/APIJSON-Java-Server/APIJSONBoot-BigData/src/main/java/apijson/demo/DemoVerifier.java +++ b/APIJSON-Java-Server/APIJSONBoot-BigData/src/main/java/apijson/demo/DemoVerifier.java @@ -14,7 +14,7 @@ package apijson.demo; -import apijson.framework.APIJSONVerifier; +import apijson.framework.javax.APIJSONVerifier; /**安全校验器,校验请求参数、角色与权限等 diff --git a/APIJSON-Java-Server/APIJSONBoot-BigData/src/main/java/apijson/demo/model/Privacy.java b/APIJSON-Java-Server/APIJSONBoot-BigData/src/main/java/apijson/demo/model/Privacy.java index e8877e90..930c4ed1 100644 --- a/APIJSON-Java-Server/APIJSONBoot-BigData/src/main/java/apijson/demo/model/Privacy.java +++ b/APIJSON-Java-Server/APIJSONBoot-BigData/src/main/java/apijson/demo/model/Privacy.java @@ -21,7 +21,7 @@ import com.alibaba.fastjson.annotation.JSONField; import apijson.MethodAccess; -import apijson.framework.BaseModel; +import apijson.framework.javax.BaseModel; /** * TODO 漏洞:如果GETS允许CONTACT,则CONTACT能看到自己的余额,tag可以不是Privacy-circle。 diff --git a/APIJSON-Java-Server/APIJSONBoot-BigData/src/main/java/apijson/demo/model/User.java b/APIJSON-Java-Server/APIJSONBoot-BigData/src/main/java/apijson/demo/model/User.java index 1ea89000..a535d28f 100644 --- a/APIJSON-Java-Server/APIJSONBoot-BigData/src/main/java/apijson/demo/model/User.java +++ b/APIJSON-Java-Server/APIJSONBoot-BigData/src/main/java/apijson/demo/model/User.java @@ -20,7 +20,7 @@ import java.util.List; import apijson.MethodAccess; -import apijson.framework.BaseModel; +import apijson.framework.javax.BaseModel; import apijson.orm.Visitor; /**用户开放信息 diff --git a/APIJSON-Java-Server/APIJSONBoot-BigData/src/main/java/apijson/demo/model/Verify.java b/APIJSON-Java-Server/APIJSONBoot-BigData/src/main/java/apijson/demo/model/Verify.java index 0da333a0..fa5fc135 100644 --- a/APIJSON-Java-Server/APIJSONBoot-BigData/src/main/java/apijson/demo/model/Verify.java +++ b/APIJSON-Java-Server/APIJSONBoot-BigData/src/main/java/apijson/demo/model/Verify.java @@ -22,7 +22,7 @@ import static apijson.orm.AbstractVerifier.UNKNOWN; import apijson.MethodAccess; -import apijson.framework.BaseModel; +import apijson.framework.javax.BaseModel; /**验证码 * @author Lemon diff --git a/APIJSON-Java-Server/APIJSONBoot-MultiDataSource/libs/APIJSON-8.0.2.jar b/APIJSON-Java-Server/APIJSONBoot-MultiDataSource/libs/APIJSON-8.0.2.jar new file mode 100644 index 00000000..77ad60f6 Binary files /dev/null and b/APIJSON-Java-Server/APIJSONBoot-MultiDataSource/libs/APIJSON-8.0.2.jar differ diff --git a/APIJSON-Java-Server/APIJSONBoot-MultiDataSource/libs/apijson-fastjson2-1.0.2.jar b/APIJSON-Java-Server/APIJSONBoot-MultiDataSource/libs/apijson-fastjson2-1.0.2.jar new file mode 100644 index 00000000..8abde0bb Binary files /dev/null and b/APIJSON-Java-Server/APIJSONBoot-MultiDataSource/libs/apijson-fastjson2-1.0.2.jar differ diff --git a/APIJSON-Java-Server/APIJSONBoot-MultiDataSource/libs/apijson-framework-7.2.2.jar b/APIJSON-Java-Server/APIJSONBoot-MultiDataSource/libs/apijson-framework-7.2.2.jar new file mode 100644 index 00000000..09f8390a Binary files /dev/null and b/APIJSON-Java-Server/APIJSONBoot-MultiDataSource/libs/apijson-framework-7.2.2.jar differ diff --git a/APIJSON-Java-Server/APIJSONBoot-MultiDataSource/libs/apijson-router-2.2.0.1.jar b/APIJSON-Java-Server/APIJSONBoot-MultiDataSource/libs/apijson-router-2.2.0.1.jar new file mode 100644 index 00000000..b84407e9 Binary files /dev/null and b/APIJSON-Java-Server/APIJSONBoot-MultiDataSource/libs/apijson-router-2.2.0.1.jar differ diff --git a/APIJSON-Java-Server/APIJSONBoot-MultiDataSource/pom.xml b/APIJSON-Java-Server/APIJSONBoot-MultiDataSource/pom.xml index c810854c..c91b629e 100755 --- a/APIJSON-Java-Server/APIJSONBoot-MultiDataSource/pom.xml +++ b/APIJSON-Java-Server/APIJSONBoot-MultiDataSource/pom.xml @@ -5,7 +5,7 @@ apijson.boot apijson-boot-multi-datasource - 7.0.3 + 7.2.2 jar APIJSONBoot-MultiDataSource @@ -23,13 +23,18 @@ + + + + + - com.alibaba - fastjson - 1.2.83 + com.alibaba.fastjson2 + fastjson2 + 2.0.57 - + jakarta.servlet jakarta.servlet-api @@ -59,23 +64,46 @@ com.github.Tencent APIJSON - 7.0.3 + 8.0.2 com.github.APIJSON apijson-framework - 7.0.3 + 7.2.2 com.github.APIJSON - apijson-column - 2.0.3 - - - com.github.APIJSON - apijson-router - 2.0.3 + apijson-fastjson2 + 1.0.2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -152,7 +180,7 @@ com.mysql mysql-connector-j - 8.4.0 + 9.2.0 org.postgresql @@ -179,11 +207,6 @@ taos-jdbcdriver 2.0.38 - - - - - org.influxdb influxdb-java @@ -209,6 +232,18 @@ mongodb-jdbc 2.0.3 + + + + + + + + + + + + @@ -252,6 +287,8 @@ + + org.yaml snakeyaml @@ -274,6 +311,14 @@ + + + + + + + + diff --git a/APIJSON-Java-Server/APIJSONBoot-MultiDataSource/src/main/java/apijson/boot/DemoApplication.java b/APIJSON-Java-Server/APIJSONBoot-MultiDataSource/src/main/java/apijson/boot/DemoApplication.java index dd79a774..e83bbd3b 100755 --- a/APIJSON-Java-Server/APIJSONBoot-MultiDataSource/src/main/java/apijson/boot/DemoApplication.java +++ b/APIJSON-Java-Server/APIJSONBoot-MultiDataSource/src/main/java/apijson/boot/DemoApplication.java @@ -14,11 +14,12 @@ package apijson.boot; -import apijson.framework.APIJSONSQLConfig; -import com.alibaba.fastjson.JSON; -import com.alibaba.fastjson.JSONObject; -import com.alibaba.fastjson.serializer.PropertyFilter; - +import apijson.fastjson2.APIJSONApplication; +import apijson.fastjson2.APIJSONCreator; +import apijson.fastjson2.APIJSONVerifier; +import apijson.fastjson2.APIJSONSQLConfig; +import apijson.orm.AbstractParser; +import apijson.orm.AbstractVerifier; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.web.server.WebServerFactoryCustomizer; @@ -29,8 +30,6 @@ import org.springframework.web.servlet.config.annotation.CorsRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; -import java.lang.reflect.Modifier; -import java.util.List; import java.util.Map; import java.util.regex.Pattern; @@ -44,21 +43,12 @@ import apijson.demo.DemoSQLConfig; import apijson.demo.DemoSQLExecutor; import apijson.demo.DemoVerifier; -import apijson.framework.APIJSONApplication; -import apijson.framework.APIJSONCreator; -import apijson.framework.APIJSONParser; -import apijson.orm.AbstractVerifier; -import apijson.orm.FunctionParser; -import apijson.orm.Parser; -import apijson.orm.SQLConfig; -import apijson.orm.SQLExecutor; import apijson.orm.Verifier; -import apijson.router.APIJSONRouterApplication; -import unitauto.MethodUtil; -import unitauto.MethodUtil.Argument; -import unitauto.MethodUtil.InstanceGetter; -import unitauto.MethodUtil.JSONCallback; -import unitauto.jar.UnitAutoApp; +//import unitauto.MethodUtil; +//import unitauto.MethodUtil.Argument; +//import unitauto.MethodUtil.InstanceGetter; +//import unitauto.MethodUtil.JSONCallback; +//import unitauto.jar.UnitAutoApp; /** @@ -91,12 +81,13 @@ public static void main(String[] args) throws Exception { // FIXME 不要开放给项目组后端之外的任何人使用 UnitAuto(强制登录鉴权)!!!如果不需要单元测试则移除相关代码或 unitauto.Log.DEBUG = false; // 上线生产环境前改为 false,可不输出 APIJSONORM 的日志 以及 SQLException 的原始(敏感)信息 - unitauto.Log.DEBUG = Log.DEBUG = true; // 是否开启调试模式(打印详细日志、返回详细调试信息等) - APIJSONParser.IS_PRINT_BIG_LOG = true; // 是否打印大日志 -// APIJSONParser.IS_START_FROM_1 = true; // 分页页码是否从 1 开始,true - 从 1 开始;false - 从 0 开始 -// APIJSONSQLConfig.ENABLE_COLUMN_CONFIG = true; // apijson-framework 已集成字段插件 apijson-column,支持 !key 反选字段 和 字段名映射 + //unitauto.Log.DEBUG = true; + Log.DEBUG = true; // 是否开启调试模式(打印详细日志、返回详细调试信息等) + AbstractParser.IS_PRINT_BIG_LOG = true; // 是否打印大日志 + APIJSONVerifier.ENABLE_APIJSON_ROUTER = true; // apijson-framework 已集成字段插件 apijson-router,是否开启 接口路由 模式,支持简单接口转为 APIJSON JSON + //APIJSONParser.IS_START_FROM_1 = true; // 分页页码是否从 1 开始,true - 从 1 开始;false - 从 0 开始 + APIJSONSQLConfig.ENABLE_COLUMN_CONFIG = false; // apijson-framework 已集成字段插件 apijson-column,支持 !key 反选字段 和 字段名映射 APIJSONApplication.init(); - APIJSONRouterApplication.init(); System.out.println("\n\n<<<<<<<<< 本 Demo 在 resources/static 内置了 APIAuto,Chrome/Firefox 打开 http://localhost:8080 即可调试(端口号根据项目配置而定) ^_^ >>>>>>>>>\n"); } @@ -204,6 +195,16 @@ public void addCorsMappings(CorsRegistry registry) { Log.e(TAG, "加载 IoTDB 驱动失败,请检查 pom.xml 中 org.apache.iotdb.jdbc 版本是否存在以及可用 !!!"); } + try { //加载驱动程序 + Log.d(TAG, "尝试加载 DuckDB 驱动 <<<<<<<<<<<<<<<<<<<<< "); + Class.forName("org.duckdb.DuckDBDriver"); + Log.d(TAG, "成功加载 DuckDB 驱动!>>>>>>>>>>>>>>>>>>>>> "); + } + catch (ClassNotFoundException e) { + e.printStackTrace(); + Log.e(TAG, "加载 DuckDB 驱动失败,请检查 pom.xml 中 org.duckdb 版本是否存在以及可用 !!!"); + } + // try { //加载驱动程序 // Log.d(TAG, "尝试加载 TDengine 驱动 <<<<<<<<<<<<<<<<<<<<< "); // Class.forName("com.taosdata.jdbc.TSDBDriver"); @@ -212,15 +213,15 @@ public void addCorsMappings(CorsRegistry registry) { // e.printStackTrace(); // Log.e(TAG, "加载 TDengine 驱动失败,请检查 pom.xml 中 com.taosdata.jdbc 版本是否存在以及可用 !!!"); // } - // - // try { //加载驱动程序 - // Log.d(TAG, "尝试加载 NebulaGraph 驱动 <<<<<<<<<<<<<<<<<<<<< "); - // Class.forName("com.vesoft.nebula.jdbc.impl.NebulaDriver"); - // Log.d(TAG, "成功加载 NebulaGraph 驱动!>>>>>>>>>>>>>>>>>>>>> "); - // } catch (ClassNotFoundException e) { - // e.printStackTrace(); - // Log.e(TAG, "加载 NebulaGraph 驱动失败,请检查 pom.xml 中 org.nebula-contrib 版本是否存在以及可用 !!!"); - // } + + // try { //加载驱动程序 + // Log.d(TAG, "尝试加载 openGauss 驱动 <<<<<<<<<<<<<<<<<<<<< "); + // Class.forName("org.opengauss.Driver"); + // Log.d(TAG, "成功加载 openGauss 驱动!>>>>>>>>>>>>>>>>>>>>> "); + // } catch (ClassNotFoundException e) { + // e.printStackTrace(); + // Log.e(TAG, "加载 openGauss 驱动失败,请检查 pom.xml 中 org.opengauss 版本是否存在以及可用 !!!"); + // } // APIJSON 配置 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< @@ -233,27 +234,27 @@ public void addCorsMappings(CorsRegistry registry) { APIJSONApplication.DEFAULT_APIJSON_CREATOR = new APIJSONCreator() { @Override - public Parser createParser() { + public DemoParser createParser() { return new DemoParser(); } @Override - public FunctionParser createFunctionParser() { + public DemoFunctionParser createFunctionParser() { return new DemoFunctionParser(); } @Override - public Verifier createVerifier() { + public DemoVerifier createVerifier() { return new DemoVerifier(); } @Override - public SQLConfig createSQLConfig() { + public DemoSQLConfig createSQLConfig() { return new DemoSQLConfig(); } @Override - public SQLExecutor createSQLExecutor() { + public DemoSQLExecutor createSQLExecutor() { return new DemoSQLExecutor(); } @@ -264,96 +265,96 @@ public SQLExecutor createSQLExecutor() { // UnitAuto 单元测试配置 https://github.com/TommyLemon/UnitAuto <<<<<<<<<<<<<<<<<<<<<<<<<<< // FIXME 不要开放给项目组后端之外的任何人使用 UnitAuto(强制登录鉴权)!!!如果不需要单元测试则移除相关代码或 unitauto.Log.DEBUG = false; - UnitAutoApp.init(); + //UnitAutoApp.init(); // 适配 Spring 注入的类及 Context 等环境相关的类 - final InstanceGetter ig = MethodUtil.INSTANCE_GETTER; - MethodUtil.INSTANCE_GETTER = new InstanceGetter() { - - @Override - public Object getInstance(@NotNull Class clazz, List classArgs, Boolean reuse) throws Exception { - if (APPLICATION_CONTEXT != null && ApplicationContext.class.isAssignableFrom(clazz) && clazz.isAssignableFrom(APPLICATION_CONTEXT.getClass())) { - return APPLICATION_CONTEXT; - } - - if (reuse != null && reuse && (classArgs == null || classArgs.isEmpty())) { - return APPLICATION_CONTEXT.getBean(clazz); - } - - return ig.getInstance(clazz, classArgs, reuse); - } - }; - - // 排除转换 JSON 异常的类,一般是 Context 等环境相关的类 - final JSONCallback jc = MethodUtil.JSON_CALLBACK; - MethodUtil.JSON_CALLBACK = new JSONCallback() { - - @Override - public JSONObject newSuccessResult() { - return jc.newSuccessResult(); - } - - @Override - public JSONObject newErrorResult(Throwable e) { - return jc.newErrorResult(e); - } - - @Override - public JSONObject parseJSON(String type, Object value) { - if (value == null || unitauto.JSON.isBooleanOrNumberOrString(value) || value instanceof JSON || value instanceof Enum) { - return jc.parseJSON(type, value); - } - - if (value instanceof ApplicationContext - || value instanceof Context - || value instanceof org.apache.catalina.Context - // SpringBoot 2.6.7 已移除 || value instanceof ch.qos.logback.core.Context - ) { - value = value.toString(); - } else { - try { - value = JSON.parse(JSON.toJSONString(value, new PropertyFilter() { - @Override - public boolean apply(Object object, String name, Object value) { - if (value == null) { - return true; - } - - if (value instanceof ApplicationContext - || value instanceof Context - || value instanceof org.apache.catalina.Context - // SpringBoot 2.6.7 已移除 || value instanceof ch.qos.logback.core.Context - ) { - return false; - } - - // 防止通过 UnitAuto 远程执行 getDBPassword 等方法来查到敏感信息,但如果直接调用 public String getDBUri 这里没法拦截,仍然会返回敏感信息 - // if (object instanceof SQLConfig) { - // // 这个类部分方法不序列化返回 - // if ("dBUri".equalsIgnoreCase(name) || "dBPassword".equalsIgnoreCase(name) || "dBAccount".equalsIgnoreCase(name)) { - // return false; - // } - // return false; // 这个类所有方法都不序列化返回 - // } - - // 所有类中的方法只要包含关键词就不序列化返回 - String n = StringUtil.toLowerCase(name); - if (n.contains("database") || n.contains("schema") || n.contains("dburi") || n.contains("password") || n.contains("account")) { - return false; - } - - return Modifier.isPublic(value.getClass().getModifiers()); - } - })); - } catch (Exception e) { - Log.e(TAG, "toJSONString catch \n" + e.getMessage()); - } - } - - return jc.parseJSON(type, value); - } - - }; + //final InstanceGetter ig = MethodUtil.INSTANCE_GETTER; + //MethodUtil.INSTANCE_GETTER = new InstanceGetter() { + // + // @Override + // public Object getInstance(@NotNull Class clazz, List classArgs, Boolean reuse) throws Exception { + // if (APPLICATION_CONTEXT != null && ApplicationContext.class.isAssignableFrom(clazz) && clazz.isAssignableFrom(APPLICATION_CONTEXT.getClass())) { + // return APPLICATION_CONTEXT; + // } + // + // if (reuse != null && reuse && (classArgs == null || classArgs.isEmpty())) { + // return APPLICATION_CONTEXT.getBean(clazz); + // } + // + // return ig.getInstance(clazz, classArgs, reuse); + // } + //}; + // + //// 排除转换 JSON 异常的类,一般是 Context 等环境相关的类 + //final JSONCallback jc = MethodUtil.JSON_CALLBACK; + //MethodUtil.JSON_CALLBACK = new JSONCallback() { + // + // @Override + // public JSONObject newSuccessResult() { + // return jc.newSuccessResult(); + // } + // + // @Override + // public JSONObject newErrorResult(Throwable e) { + // return jc.newErrorResult(e); + // } + // + // @Override + // public JSONObject parseJSON(String type, Object value) { + // if (value == null || unitauto.JSON.isBooleanOrNumberOrString(value) || value instanceof JSON || value instanceof Enum) { + // return jc.parseJSON(type, value); + // } + // + // if (value instanceof ApplicationContext + // || value instanceof Context + // || value instanceof org.apache.catalina.Context + // // SpringBoot 2.6.7 已移除 || value instanceof ch.qos.logback.core.Context + // ) { + // value = value.toString(); + // } else { + // try { + // value = parseJSON(JSON.toJSONString(value, new PropertyFilter() { + // @Override + // public boolean apply(Object object, String name, Object value) { + // if (value == null) { + // return true; + // } + // + // if (value instanceof ApplicationContext + // || value instanceof Context + // || value instanceof org.apache.catalina.Context + // // SpringBoot 2.6.7 已移除 || value instanceof ch.qos.logback.core.Context + // ) { + // return false; + // } + // + // // 防止通过 UnitAuto 远程执行 getDBPassword 等方法来查到敏感信息,但如果直接调用 public String getDBUri 这里没法拦截,仍然会返回敏感信息 + // // if (object instanceof SQLConfig) { + // // // 这个类部分方法不序列化返回 + // // if ("dBUri".equalsIgnoreCase(name) || "dBPassword".equalsIgnoreCase(name) || "dBAccount".equalsIgnoreCase(name)) { + // // return false; + // // } + // // return false; // 这个类所有方法都不序列化返回 + // // } + // + // // 所有类中的方法只要包含关键词就不序列化返回 + // String n = StringUtil.toLowerCase(name); + // if (n.contains("database") || n.contains("schema") || n.contains("dburi") || n.contains("password") || n.contains("account")) { + // return false; + // } + // + // return Modifier.isPublic(value.getClass().getModifiers()); + // } + // })); + // } catch (Exception e) { + // Log.e(TAG, "toJSONString catch \n" + e.getMessage()); + // } + // } + // + // return jc.parseJSON(type, value); + // } + // + //}; // UnitAuto 单元测试配置 https://github.com/TommyLemon/UnitAuto >>>>>>>>>>>>>>>>>>>>>>>>>>>>>> diff --git a/APIJSON-Java-Server/APIJSONBoot-MultiDataSource/src/main/java/apijson/boot/DemoController.java b/APIJSON-Java-Server/APIJSONBoot-MultiDataSource/src/main/java/apijson/boot/DemoController.java index 1063fe74..19455c2d 100644 --- a/APIJSON-Java-Server/APIJSONBoot-MultiDataSource/src/main/java/apijson/boot/DemoController.java +++ b/APIJSON-Java-Server/APIJSONBoot-MultiDataSource/src/main/java/apijson/boot/DemoController.java @@ -14,44 +14,22 @@ package apijson.boot; -import apijson.orm.AbstractParser; -import apijson.orm.Parser; +import apijson.fastjson2.APIJSONController; +import apijson.fastjson2.APIJSONParser; +import apijson.fastjson2.JSONRequest; import apijson.orm.exception.*; -import com.alibaba.fastjson.JSONArray; -import com.alibaba.fastjson.JSONObject; -import com.alibaba.fastjson.serializer.SerializerFeature; -import com.alibaba.fastjson.serializer.ValueFilter; +import com.alibaba.fastjson2.JSONArray; +import com.alibaba.fastjson2.JSONObject; import com.fasterxml.jackson.databind.util.LRUMap; -//import com.vesoft.nebula.Date; -//import com.vesoft.nebula.DateTime; -//import com.vesoft.nebula.Duration; -//import com.vesoft.nebula.Edge; -//import com.vesoft.nebula.NullType; -//import com.vesoft.nebula.Tag; -//import com.vesoft.nebula.Time; -//import com.vesoft.nebula.Value; -//import com.vesoft.nebula.Vertex; -//import com.vesoft.nebula.client.graph.data.DateTimeWrapper; -//import com.vesoft.nebula.client.graph.data.DateWrapper; -//import com.vesoft.nebula.client.graph.data.DurationWrapper; -//import com.vesoft.nebula.client.graph.data.TimeWrapper; -//import com.vesoft.nebula.client.graph.data.ValueWrapper; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.*; +import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; import org.springframework.stereotype.Service; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -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.RequestParam; -import org.springframework.web.bind.annotation.RestController; -import org.springframework.web.client.HttpClientErrorException; +import org.springframework.web.bind.annotation.*; import org.springframework.web.client.RestClientResponseException; import org.springframework.web.client.RestTemplate; -import java.io.IOException; import java.lang.reflect.Array; import java.net.URLDecoder; import java.net.URLEncoder; @@ -68,8 +46,8 @@ import jakarta.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpSession; -import apijson.JSON; -import apijson.JSONResponse; +import apijson.fastjson2.JSON; +import apijson.fastjson2.JSONResponse; import apijson.Log; import apijson.RequestMethod; import apijson.StringUtil; @@ -82,12 +60,9 @@ import apijson.demo.model.User; import apijson.demo.model.Verify; import apijson.framework.BaseModel; -import apijson.orm.JSONRequest; -import apijson.orm.model.TestRecord; -import apijson.router.APIJSONRouterController; -import org.springframework.web.servlet.ModelAndView; import unitauto.MethodUtil; +import static apijson.JSON.getString; import static apijson.RequestMethod.DELETE; import static apijson.RequestMethod.GET; import static apijson.RequestMethod.GETS; @@ -101,14 +76,13 @@ import static apijson.framework.APIJSONConstant.FUNCTION_; import static apijson.framework.APIJSONConstant.ID; import static apijson.framework.APIJSONConstant.REQUEST_; -import static apijson.framework.APIJSONConstant.TEST_RECORD_; import static apijson.framework.APIJSONConstant.USER_ID; import static apijson.framework.APIJSONConstant.VERSION; import static org.springframework.http.HttpHeaders.COOKIE; import static org.springframework.http.HttpHeaders.SET_COOKIE; -/**请求路由入口控制器,包括通用增删改查接口等,转交给 APIJSON 的 Parser 来处理 +/**请求路由入口控制器,包括通用增删改查接口等,转交给 APIJSON 的 Parser 来处理 * 具体见 SpringBoot 文档 * https://www.springcloud.cc/spring-boot.html#boot-features-spring-mvc * 以及 APIJSON 通用文档 3.设计规范 3.1 操作方法 @@ -122,7 +96,7 @@ @Service @RestController @RequestMapping("") -public class DemoController extends APIJSONRouterController { // APIJSONController { +public class DemoController extends APIJSONController { private static final String TAG = "DemoController"; public String getRequestBaseURL() { @@ -155,10 +129,11 @@ public String getRequestURL() { return getRequestBaseURL() + getRequestPath(); } -// @Override -// public Parser newParser(HttpSession session, RequestMethod method) { -// return super.newParser(session, method).setNeedVerify(false); -// } + @Override + public APIJSONParser newParser(HttpSession session, RequestMethod method) { + return super.newParser(session, method); // .setNeedVerify(false); + } + /**增删改查统一的类 RESTful API 入口,牺牲一点路由解析性能来提升一些开发效率 * @param method @@ -186,7 +161,7 @@ public String router(@PathVariable("method") String method, @PathVariable("tag") @PostMapping(value = "crud") // 直接 {method} 或 apijson/{method} 会和内置网页的路由有冲突 // @Override public String crudAll(@RequestBody String request, HttpSession session) { - return newParser(session, RequestMethod.CRUD).parse(request); + return super.crudAll(request, session); } /**增删改查统一入口,这个一个方法可替代以下 7 个方法,牺牲一点路由解析性能来提升一些开发效率 * @param method @@ -404,7 +379,7 @@ public String openGet(@PathVariable("request") String request, HttpSession sessi try { request = URLDecoder.decode(request, StringUtil.UTF_8); } catch (Exception e) { - // Parser 会报错 + // Parser 会报错 } if (! Log.DEBUG) { // 一般情况这样简单使用 @@ -416,7 +391,7 @@ public String openGet(@PathVariable("request") String request, HttpSession sessi try { String url = getRequestURL(); - String query = StringUtil.getTrimedString(httpServletRequest.getQueryString()); + String query = StringUtil.trim(httpServletRequest.getQueryString()); if (StringUtil.isNotEmpty(query)) { try { query = "?" + URLEncoder.encode(query, StringUtil.UTF_8); @@ -562,16 +537,16 @@ public JSONObject reload(@RequestBody String request) { phone = requestObject.getString(PHONE); verify = requestObject.getString(VERIFY); } catch (Exception e) { - return DemoParser.extendErrorResult(requestObject, e); + return extendErrorResult(requestObject, e); } JSONResponse response = new JSONResponse(headVerify(Verify.TYPE_RELOAD, phone, verify)); response = response.getJSONResponse(VERIFY_); if (JSONResponse.isExist(response) == false) { - return DemoParser.extendErrorResult(requestObject, new ConditionErrorException("手机号或验证码错误")); + return extendErrorResult(requestObject, new ConditionErrorException("手机号或验证码错误")); } - JSONObject result = DemoParser.newSuccessResult(); + JSONObject result = newSuccessResult(); boolean reloadAll = StringUtil.isEmpty(type, true) || "ALL".equals(type); @@ -580,7 +555,7 @@ public JSONObject reload(@RequestBody String request) { result.put(ACCESS_, DemoVerifier.initAccess(false, null, value)); } catch (ServerException e) { e.printStackTrace(); - result.put(ACCESS_, DemoParser.newErrorResult(e)); + result.put(ACCESS_, newErrorResult(e)); } } @@ -589,7 +564,7 @@ public JSONObject reload(@RequestBody String request) { result.put(FUNCTION_, DemoFunctionParser.init(false, null, value)); } catch (ServerException e) { e.printStackTrace(); - result.put(FUNCTION_, DemoParser.newErrorResult(e)); + result.put(FUNCTION_, newErrorResult(e)); } } @@ -598,7 +573,7 @@ public JSONObject reload(@RequestBody String request) { result.put(REQUEST_, DemoVerifier.initRequest(false, null, value)); } catch (ServerException e) { e.printStackTrace(); - result.put(REQUEST_, DemoParser.newErrorResult(e)); + result.put(REQUEST_, newErrorResult(e)); } } @@ -625,10 +600,10 @@ public JSONObject postVerify(@RequestBody String request) { type = requestObject.getIntValue(TYPE); phone = requestObject.getString(PHONE); } catch (Exception e) { - return DemoParser.extendErrorResult(requestObject, e); + return extendErrorResult(requestObject, e); } - new DemoParser(DELETE, false).parse(newVerifyRequest(type, phone, null)); + new DemoParser(DELETE, false).parse(newVerifyRequest(type, phone)); JSONObject response = new DemoParser(POST, false).parseResponse( newVerifyRequest(type, phone, "" + (new Random().nextInt(9999) + 1000)) @@ -636,7 +611,7 @@ public JSONObject postVerify(@RequestBody String request) { if (JSONResponse.isSuccess(response) == false) { - new DemoParser(DELETE, false).parseResponse(new JSONRequest(new Verify(type, phone))); + new DemoParser(DELETE, false).parseResponse(newVerifyRequest(type, phone)); return response; } @@ -667,9 +642,9 @@ public JSONObject getVerify(@RequestBody String request) { type = requestObject.getIntValue(TYPE); phone = requestObject.getString(PHONE); } catch (Exception e) { - return DemoParser.extendErrorResult(requestObject, e); + return extendErrorResult(requestObject, e); } - return new DemoParser(GETS, false).parseResponse(newVerifyRequest(type, phone, null)); + return new DemoParser(GETS, false).parseResponse(newVerifyRequest(type, phone)); } /**校验验证码 @@ -695,7 +670,7 @@ public JSONObject headVerify(@RequestBody String request) { phone = requestObject.getString(PHONE); verify = requestObject.getString(VERIFY); } catch (Exception e) { - return DemoParser.extendErrorResult(requestObject, e); + return extendErrorResult(requestObject, e); } return headVerify(type, phone, verify); } @@ -710,15 +685,12 @@ public JSONObject headVerify(@RequestBody String request) { public JSONObject headVerify(int type, String phone, String code) { JSONResponse response = new JSONResponse( new DemoParser(GETS, false).parseResponse( - new JSONRequest( - new Verify(type, phone) - .setVerify(code) - ).setTag(VERIFY_) + newVerifyRequest(type, phone, code) ) ); Verify verify = response.getObject(Verify.class); if (verify == null) { - return DemoParser.newErrorResult(StringUtil.isEmpty(code, true) + return newErrorResult(StringUtil.isEmpty(code, true) ? new NotExistException("验证码不存在!") : new ConditionErrorException("手机号或验证码错误!")); } @@ -727,27 +699,36 @@ public JSONObject headVerify(int type, String phone, String code) { long now = System.currentTimeMillis(); if (now > 60*1000 + time) { new DemoParser(DELETE, false).parseResponse( - new JSONRequest(new Verify(type, phone)).setTag(VERIFY_) + newVerifyRequest(type, phone) ); - return DemoParser.newErrorResult(new TimeoutException("验证码已过期!")); + return newErrorResult(new TimeoutException("验证码已过期!")); } - return new JSONResponse( - new DemoParser(HEADS, false).parseResponse( - new JSONRequest(new Verify(type, phone).setVerify(code)).setFormat(true) - ) + return new DemoParser(HEADS, false).parseResponse( + newVerifyRequest(type, phone, code) ); } /**新建一个验证码请求 + * @param phone + * @param phone + * @return + */ + public static JSONObject newVerifyRequest(int type, String phone) { + return newVerifyRequest(type, phone, null); + } + /**新建一个验证码请求 + * @param type * @param phone * @param verify * @return */ - private apijson.JSONRequest newVerifyRequest(int type, String phone, String verify) { - return new JSONRequest(new Verify(type, phone).setVerify(verify)).setTag(VERIFY_).setFormat(true); + public static JSONObject newVerifyRequest(int type, String phone, String verify) { + return new JSONRequest( + new Verify(type, phone).setVerify(verify) + ).setTag(VERIFY_).setFormat(true); } @@ -771,7 +752,7 @@ private apijson.JSONRequest newVerifyRequest(int type, String phone, String veri } * */ - @PostMapping(LOGIN) //TODO 改 SQLConfig 里的 dbAccount, dbPassword,直接用数据库鉴权 + @PostMapping(LOGIN) //TODO 改 SQLConfig 里的 dbAccount, dbPassword,直接用数据库鉴权 public JSONObject login(@RequestBody String request, HttpSession session) { JSONObject requestObject = null; boolean isPassword; @@ -813,22 +794,20 @@ public JSONObject login(@RequestBody String request, HttpSession session) { requestObject.remove(REMEMBER); requestObject.remove(DEFAULTS); } catch (Exception e) { - return DemoParser.extendErrorResult(requestObject, e); + return extendErrorResult(requestObject, e); } //手机号是否已注册 JSONObject phoneResponse = new DemoParser(HEADS, false).parseResponse( - new JSONRequest( - new Privacy().setPhone(phone) - ) + new JSONRequest(new Privacy().setPhone(phone)) ); if (JSONResponse.isSuccess(phoneResponse) == false) { - return DemoParser.newResult(phoneResponse.getIntValue(JSONResponse.KEY_CODE), phoneResponse.getString(JSONResponse.KEY_MSG)); + return newResult(phoneResponse.getIntValue(JSONResponse.KEY_CODE), getString(phoneResponse, JSONResponse.KEY_MSG)); } JSONResponse response = new JSONResponse(phoneResponse).getJSONResponse(PRIVACY_); if(JSONResponse.isExist(response) == false) { - return DemoParser.newErrorResult(new NotExistException("手机号未注册")); + return newErrorResult(new NotExistException("手机号未注册")); } //根据phone获取User @@ -856,26 +835,25 @@ public JSONObject login(@RequestBody String request, HttpSession session) { response = new JSONResponse(headVerify(Verify.TYPE_LOGIN, phone, password)); } if (JSONResponse.isSuccess(response) == false) { - return response; + return response.toObject(JSONObject.class); } response = response.getJSONResponse(isPassword ? PRIVACY_ : VERIFY_); if (JSONResponse.isExist(response) == false) { - return DemoParser.newErrorResult(new ConditionErrorException("账号或密码错误")); + return newErrorResult(new ConditionErrorException("账号或密码错误")); } response = new JSONResponse( new DemoParser(GETS, false).parseResponse( - new JSONRequest( // 兼容 MySQL 5.6 及以下等不支持 json 类型的数据库 - USER_, // User 里在 setContactIdList(List) 后加 setContactIdList(String) 没用 - new apijson.JSONObject( // fastjson 查到一个就不继续了,所以只能加到前面或者只有这一个,但这样反过来不兼容 5.7+ - new User(userId) // 所以就用 @json 来强制转为 JSONArray,保证有效 - ).setJson("contactIdList,pictureList") - ).setFormat(true) + new JSONRequest( // 兼容 MySQL 5.6 及以下等不支持 json 类型的数据库 + USER_, // User 里在 setContactIdList(List) 后加 setContactIdList(String) 没用 + JSONRequest.setJson(JSON.parseObject(new User(userId)),"contactIdList,pictureList") + ) + .setFormat(true) ) ); User user = response.getObject(User.class); if (user == null || BaseModel.value(user.getId()) != userId) { - return DemoParser.newErrorResult(new NullPointerException("服务器内部错误")); + return newErrorResult(new NullPointerException("服务器内部错误")); } //登录状态保存至session @@ -900,7 +878,9 @@ public JSONObject login(@RequestBody String request, HttpSession session) { @PostMapping("logout") @Override public JSONObject logout(HttpSession session) { - SESSION_MAP.remove(session.getId()); + if (session != null) { + SESSION_MAP.remove(session.getId()); + } Long userId; try { @@ -908,11 +888,11 @@ public JSONObject logout(HttpSession session) { Log.d(TAG, "logout userId = " + userId + "; session.getId() = " + (session == null ? null : session.getId())); super.logout(session); } catch (Exception e) { - return DemoParser.newErrorResult(e); + return newErrorResult(e); } - JSONObject result = DemoParser.newSuccessResult(); - JSONObject user = DemoParser.newSuccessResult(); + JSONObject result = newSuccessResult(); + JSONObject user = newSuccessResult(); user.put(ID, userId); user.put(COUNT, 1); result.put(StringUtil.firstCase(USER_), user); @@ -952,7 +932,7 @@ public JSONObject register(@RequestBody String request) { requestObject = DemoParser.parseRequest(request); privacyObj = requestObject.getJSONObject(PRIVACY_); - phone = StringUtil.getString(privacyObj.getString(PHONE)); + phone = StringUtil.get(privacyObj.getString(PHONE)); verify = requestObject.getString(VERIFY); password = privacyObj.getString(_PASSWORD); @@ -966,7 +946,7 @@ public JSONObject register(@RequestBody String request) { return newIllegalArgumentResult(requestObject, VERIFY); } } catch (Exception e) { - return DemoParser.extendErrorResult(requestObject, e); + return extendErrorResult(requestObject, e); } @@ -976,11 +956,9 @@ public JSONObject register(@RequestBody String request) { } //手机号或验证码错误 if (JSONResponse.isExist(response.getJSONResponse(VERIFY_)) == false) { - return DemoParser.extendErrorResult(response, new ConditionErrorException("手机号或验证码错误!")); + return extendErrorResult(response, new ConditionErrorException("手机号或验证码错误!")); } - - //生成User和Privacy if (StringUtil.isEmpty(requestObject.getString(JSONRequest.KEY_TAG), true)) { requestObject.put(JSONRequest.KEY_TAG, REGISTER); @@ -1028,8 +1006,8 @@ public static JSONObject newIllegalArgumentResult(JSONObject requestObject, Stri * @return */ public static JSONObject newIllegalArgumentResult(JSONObject requestObject, String key, String msg) { - return DemoParser.extendErrorResult(requestObject - , new IllegalArgumentException(key + ":value 中value不合法!" + StringUtil.getString(msg))); + return new DemoParser().extendErrorResult(requestObject + , new IllegalArgumentException(key + ":value 中value不合法!" + StringUtil.get(msg))); } @@ -1070,8 +1048,8 @@ public JSONObject putPassword(@RequestBody String request){ String password; try { requestObject = DemoParser.parseRequest(request); - oldPassword = StringUtil.getString(requestObject.getString(OLD_PASSWORD)); - verify = StringUtil.getString(requestObject.getString(VERIFY)); + oldPassword = StringUtil.get(requestObject.getString(OLD_PASSWORD)); + verify = StringUtil.get(requestObject.getString(VERIFY)); requestObject.remove(OLD_PASSWORD); requestObject.remove(VERIFY); @@ -1096,16 +1074,16 @@ public JSONObject putPassword(@RequestBody String request){ } } } catch (Exception e) { - return DemoParser.extendErrorResult(requestObject, e); + return extendErrorResult(requestObject, e); } if (StringUtil.isPassword(oldPassword)) { if (userId <= 0) { //手机号+验证码不需要userId - return DemoParser.extendErrorResult(requestObject, new IllegalArgumentException(ID + ":value 中value不合法!")); + return extendErrorResult(requestObject, new IllegalArgumentException(ID + ":value 中value不合法!")); } if (oldPassword.equals(password)) { - return DemoParser.extendErrorResult(requestObject, new ConflictException("新旧密码不能一样!")); + return extendErrorResult(requestObject, new ConflictException("新旧密码不能一样!")); } //验证旧密码 @@ -1121,7 +1099,7 @@ public JSONObject putPassword(@RequestBody String request){ ) ); if (JSONResponse.isExist(response.getJSONResponse(PRIVACY_)) == false) { - return DemoParser.extendErrorResult(requestObject, new ConditionErrorException("账号或原密码错误,请重新输入!")); + return extendErrorResult(requestObject, new ConditionErrorException("账号或原密码错误,请重新输入!")); } } else if (StringUtil.isPhone(phone) && StringUtil.isVerify(verify)) { @@ -1130,7 +1108,7 @@ else if (StringUtil.isPhone(phone) && StringUtil.isVerify(verify)) { return response; } if (JSONResponse.isExist(response.getJSONResponse(VERIFY_)) == false) { - return DemoParser.extendErrorResult(response, new ConditionErrorException("手机号或验证码错误!")); + return extendErrorResult(response, new ConditionErrorException("手机号或验证码错误!")); } response = new JSONResponse( new DemoParser(GET, false).parseResponse( @@ -1146,7 +1124,7 @@ else if (StringUtil.isPhone(phone) && StringUtil.isVerify(verify)) { requestObject.put(PRIVACY_, privacyObj); } else { - return DemoParser.extendErrorResult(requestObject, new IllegalArgumentException("请输入合法的 旧密码 或 手机号+验证码 !")); + return extendErrorResult(requestObject, new IllegalArgumentException("请输入合法的 旧密码 或 手机号+验证码 !")); } //TODO 上线版加上 password = MD5Util.MD5(password); @@ -1200,7 +1178,7 @@ public JSONObject putBalance(@RequestBody String request, HttpSession session) { throw new IllegalArgumentException(PRIVACY_ + "." + _PAY_PASSWORD + ":value 中value不合法!"); } } catch (Exception e) { - return DemoParser.extendErrorResult(requestObject, e); + return extendErrorResult(requestObject, e); } //验证密码<<<<<<<<<<<<<<<<<<<<<<< @@ -1213,7 +1191,7 @@ public JSONObject putBalance(@RequestBody String request, HttpSession session) { ); response = response.getJSONResponse(PRIVACY_); if (JSONResponse.isExist(response) == false) { - return DemoParser.extendErrorResult(requestObject, new ConditionErrorException("支付密码错误!")); + return extendErrorResult(requestObject, new ConditionErrorException("支付密码错误!")); } //验证密码>>>>>>>>>>>>>>>>>>>>>>>> @@ -1222,10 +1200,10 @@ public JSONObject putBalance(@RequestBody String request, HttpSession session) { //验证金额范围<<<<<<<<<<<<<<<<<<<<<<< if (change == 0) { - return DemoParser.extendErrorResult(requestObject, new OutOfRangeException("balance+的值不能为0!")); + return extendErrorResult(requestObject, new OutOfRangeException("balance+的值不能为0!")); } if (Math.abs(change) > 10000) { - return DemoParser.extendErrorResult(requestObject, new OutOfRangeException("单次 充值/提现 的金额不能超过10000元!")); + return extendErrorResult(requestObject, new OutOfRangeException("单次 充值/提现 的金额不能超过10000元!")); } //验证金额范围>>>>>>>>>>>>>>>>>>>>>>>> @@ -1233,19 +1211,17 @@ public JSONObject putBalance(@RequestBody String request, HttpSession session) { if (change < 0) {//提现 response = new JSONResponse( new DemoParser(GETS, false).parseResponse( - new JSONRequest( - new Privacy(userId) - ) + new JSONRequest(new Privacy(userId)) ) ); - Privacy privacy = response == null ? null : response.getObject(Privacy.class); + Privacy privacy = response.getObject(Privacy.class); long id = privacy == null ? 0 : BaseModel.value(privacy.getId()); if (id != userId) { - return DemoParser.extendErrorResult(requestObject, new Exception("服务器内部错误!")); + return extendErrorResult(requestObject, new Exception("服务器内部错误!")); } if (BaseModel.value(privacy.getBalance()) < -change) { - return DemoParser.extendErrorResult(requestObject, new OutOfRangeException("余额不足!")); + return extendErrorResult(requestObject, new OutOfRangeException("余额不足!")); } } @@ -1323,7 +1299,7 @@ public String delegate( HttpMethod method, HttpSession session ) { if (Log.DEBUG == false) { - return DemoParser.newErrorResult(new IllegalAccessException("非 DEBUG 模式下不允许使用服务器代理!")).toJSONString(); + return JSON.toJSONString(newErrorResult(new IllegalAccessException("非 DEBUG 模式下不允许使用服务器代理!"))); } int recordType = record != null ? record : (REQUEST_RECORD_TYPE != null ? REQUEST_RECORD_TYPE : 0); @@ -1342,7 +1318,7 @@ public String delegate( JSONObject obj = JSON.parseObject(body); if (obj == null) { - obj = new JSONObject(true); + obj = JSON.newJSONObject(); } if (obj.get("endpoint") == null) { endpoint = index < 0 ? endpoint : endpoint.substring(0, index); @@ -1443,10 +1419,10 @@ else if (body != null && "DATA".equals(type)) { // if (StringUtil.isNotEmpty(bod hm.put(name, h); try { - com.alibaba.fastjson.JSON.parse(h); + JSON.parse(h); } catch (Throwable e) { Log.e(TAG, "delegate try {\n" + - " JSON.parse(h);\n" + + " parseJSON(h);\n" + " } catch (Throwable e) = " + e.getMessage()); hs += "\n" + name + ": " + "\"" + h.replaceAll("\"", "\\\"") + "\""; continue; @@ -1485,11 +1461,11 @@ else if (names != null) { hm.put(name, h); try { - com.alibaba.fastjson.JSON.parse(h); + JSON.parse(h); } catch (Throwable e) { Log.e(TAG, "delegate try {\n" + - " JSON.parse(h);\n" + + " parseJSON(h);\n" + " } catch (Throwable e) = " + e.getMessage()); hs += "\n" + name + ": " + "\"" + h.replaceAll("\"", "\\\"") + "\""; continue; @@ -1556,7 +1532,7 @@ else if (names != null) { for (Entry e : set) { if (e != null) { String[] vals = e.getValue(); - url += ((first ? "" : "&") + e.getKey() + "=" + ( vals == null || vals.length <= 0 ? "" : StringUtil.getString(vals[0]) )); + url += ((first ? "" : "&") + e.getKey() + "=" + ( vals == null || vals.length <= 0 ? "" : StringUtil.get(vals[0]) )); first = false; } } @@ -1591,12 +1567,12 @@ else if (names != null) { : (MediaType.MULTIPART_FORM_DATA.equals(contentType) ? "DATA" : "JSON"))) // FIXME 考虑 XML, PNG 等格式? ) : "JSON"; - String sql = isSQL ? StringUtil.getTrimedString(req.getString("sql")) : null; + String sql = isSQL ? StringUtil.trim(req.getString("sql")) : null; String newSql = ""; // String[] lines = sql.split(" \\? "); // StringUtil.split(sql, " \\? ", false); // int len = lines == null ? 0 : lines.length; // if (len > 0) { -// JSONArray args = req.getJSONArray("args"); +// JSONList args = req.getJSONArray("args"); // Set set = hm.keySet(); // Iterator iterator = set.iterator(); // @@ -1656,11 +1632,11 @@ else if (names != null) { sql = newSql.trim(); } - JSONRequest existReq = new JSONRequest(); + JSONObject existReq = JSON.newJSONObject(); if (isUnit) { if (req != null) { // Method <<<<<<<<<<<<<<<<<<<<<<<<<<<<< - apijson.JSONRequest mthd = new apijson.JSONRequest(); + JSONRequest mthd = new JSONRequest(); if (recordType > 0) { mthd.setColumn("id"); } @@ -1681,7 +1657,7 @@ else if (names != null) { } else { // Document <<<<<<<<<<<<<<<<<<<<<<<<<<<<< - apijson.JSONRequest document = new apijson.JSONRequest(); + JSONRequest document = new JSONRequest(); if (recordType > 0) { document.setColumn("id"); } @@ -1701,13 +1677,13 @@ else if (names != null) { long documentId = existRsp2 == null ? 0 : existRsp2.getId(); JSONRequest request = new JSONRequest(); - apijson.JSONRequest testRecord = new apijson.JSONRequest(); + JSONRequest testRecord = new JSONRequest(); if (documentId <= 0) { if (isUnit) { request.setTag("Method"); // Method <<<<<<<<<<<<<<<<<<<<<<<<<<<<< - apijson.JSONRequest mthd = new apijson.JSONRequest(); + JSONRequest mthd = new JSONRequest(); mthd.put("from", 2); // 0-测试工具,1-CI/CD,2-流量录制 mthd.put("language", req.getString("language")); mthd.put(MethodUtil.KEY_UI, req.getInteger(MethodUtil.KEY_UI)); @@ -1728,7 +1704,7 @@ else if (names != null) { else if (recordType > 0) { request.setTag("Document"); // Document <<<<<<<<<<<<<<<<<<<<<<<<<<<<< - JSONObject document = new JSONObject(true); + JSONObject document = JSON.newJSONObject(); document.put("from", 2); // 0-测试工具,1-CI/CD,2-流量录制 document.put("name", "[Record] " + new java.util.Date().toLocaleString()); document.put("type", reqType); @@ -1737,7 +1713,7 @@ else if (recordType > 0) { document.put("request", isSQL ? "{}" : (isBodyEmpty ? JSON.toJSONString(map) : body)); if (isSQL) { // 没有名称,除非 args 传对象而不是数组 - // JSONArray args = req.getJSONArray("args"); + // JSONList args = req.getJSONArray("args"); // String argStr = ""; // if (args != null) { // for (int i = 0; i < args.size(); i++) { @@ -1761,7 +1737,7 @@ else if (recordType > 0) { Map m = isSQL ? null : (isBodyEmpty ? map : JSON.parseObject(body)); String config = isSQL ? hs : parseRandomConfig("", m); - JSONObject random = new JSONObject(true); + JSONObject random = JSON.newJSONObject(); random.put("count", 1); random.put("documentId", documentId); random.put("config", config.trim()); @@ -1788,7 +1764,7 @@ else if (recordType > 0) { isDefault = Objects.equals(reqObj, req); } catch (Throwable e) { - Log.w(TAG, "delegate try { Object reqObj = JSON.parse(reqStr); ..." + + Log.w(TAG, "delegate try { Object reqObj = parseJSON(reqStr); ..." + " } catch (Throwable e) = " + e.getMessage()); } } @@ -1799,7 +1775,7 @@ else if (recordType > 0) { else { long randomId = 0; try { - apijson.JSONRequest randomReq = new apijson.JSONRequest(); + JSONObject randomReq = JSON.newJSONObject(); randomReq.put("Random", random); JSONObject rsp = newParser(session, GET).parseResponse(randomReq); @@ -1807,7 +1783,7 @@ else if (recordType > 0) { randomId = rsp2 == null ? 0 : rsp2.getLongValue("id"); } catch (Throwable e) { - Log.w(TAG, "delegate try { apijson.JSONRequest randomReq = new apijson.JSONRequest(); ..." + + Log.w(TAG, "delegate try { JSONMap randomReq = JSON.newJSONObject(); ..." + " } catch (Throwable e) = " + e.getMessage()); } @@ -1826,7 +1802,7 @@ else if (recordType > 0) { else { // TestRecord <<<<<<<<<<<<<<<<<<<<<<<<<<<<< testRecord.put("from", 2); // 0-接口工具,1-CI/CD,2-流量录制 testRecord.put("host", host); - testRecord.put("response", rspBody); // 用 JSONRequest.put 会转为 JSONObject + testRecord.put("response", rspBody); // 用 JSONRequest.put 会转为 JSONMap } // TestRecord >>>>>>>>>>>>>>>>>>>>>>>>>>>>> request.put("TestRecord", testRecord); @@ -1836,7 +1812,7 @@ else if (recordType > 0) { String response = rsp2 == null ? null : rsp2.getString("response"); if (StringUtil.isNotEmpty(response, true)) { String header = rsp2.getString("header"); - String[] lines = StringUtil.split(StringUtil.getTrimedString(header), "\n"); + String[] lines = StringUtil.split(StringUtil.trim(header), "\n"); if (lines != null) { for (String line : lines) { @@ -1883,6 +1859,14 @@ protected String sendRequest(HttpSession session, HttpMethod method, String url, String rspBody = null; try { RestTemplate client = new RestTemplate(); + try { // 支持 PATCH 方法,需要 Maven 依赖 org.apache.httpcomponents.client5:httpclient5 + HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(); + client.setRequestFactory(requestFactory); + } + catch (Throwable e) { + e.printStackTrace(); + } + HttpEntity requestEntity = new HttpEntity<>(method == HttpMethod.GET ? null : body, headers); ResponseEntity entity = client.exchange(url, method, requestEntity, String.class); @@ -1943,7 +1927,7 @@ private String parseRandomConfig(String path, Object obj) { Map m = (Map) obj; Set> s = m == null ? null : m.entrySet(); if (s != null) { - // TODO APIAuto 得先支持空 key config += "\n" + path + ": {}"; // 避免默认 JSON 中这个数组为 null 导致后面生成的是 JSONArray + // TODO APIAuto 得先支持空 key config += "\n" + path + ": {}"; // 避免默认 JSON 中这个数组为 null 导致后面生成的是 JSONList for (Entry e : s) { Object k = e == null ? null : e.getKey(); @@ -1961,7 +1945,7 @@ private String parseRandomConfig(String path, Object obj) { if (obj instanceof Collection) { Collection c = (Collection) obj; if (c != null) { - config += "\n" + path + ": []"; // 避免默认 JSON 中这个数组为 null 导致后面生成的是 JSONObject + config += "\n" + path + ": []"; // 避免默认 JSON 中这个数组为 null 导致后面生成的是 JSONMap int i = -1; for (Object v : c) { @@ -1976,7 +1960,7 @@ private String parseRandomConfig(String path, Object obj) { if (obj instanceof Array) { Array a = (Array) obj; if (a != null) { - config += "\n" + path + ": []"; // 避免默认 JSON 中这个数组为 null 导致后面生成的是 JSONObject + config += "\n" + path + ": []"; // 避免默认 JSON 中这个数组为 null 导致后面生成的是 JSONMap int len = Array.getLength(a); for (int i = 0; i < len; i++) { @@ -2011,7 +1995,7 @@ private String parseRandomConfig(String path, Object obj) { public String execute(@RequestBody String request, HttpSession session) { try { if (Log.DEBUG == false) { - return DemoParser.newErrorResult(new IllegalAccessException("非 DEBUG 模式下不允许调用 /sql/execute !")).toJSONString(); + return JSON.toJSONString(newErrorResult(new IllegalAccessException("非 DEBUG 模式下不允许调用 /sql/execute !"))); } // DemoVerifier.verifyLogin(session); @@ -2065,8 +2049,6 @@ public String execute(@RequestBody String request, HttpSession session) { account = "test"; // "peter"; password = "test"; // null; } - } else if (DemoSQLExecutor.DATABASE_NEBULA.equalsIgnoreCase(prefix)) { - database = prefix.toUpperCase(); } } @@ -2153,7 +2135,7 @@ public String execute(@RequestBody String request, HttpSession session) { while (rs != null && rs.next()) { cursorDuration += System.currentTimeMillis() - cursorStartTime; - JSONObject obj = new JSONObject(true); + JSONObject obj = JSON.newJSONObject(); for (int i = 1; i <= length; i++) { long sqlStartTime = System.currentTimeMillis(); String name = rsmd.getColumnName(i); // rsmd.getColumnLable(i); @@ -2173,7 +2155,7 @@ public String execute(@RequestBody String request, HttpSession session) { // } } - JSONObject result = DemoParser.newSuccessResult(); + JSONObject result = newSuccessResult(); result.put("sql", sql); result.put("args", arg); if (isWrite) { @@ -2189,129 +2171,9 @@ public String execute(@RequestBody String request, HttpSession session) { result.put("time:start|duration|end|parse|sql", startTime + "|" + duration + "|" + endTime + "|" + parseDuration + "|" + sqlDuration); - if (DemoSQLExecutor.DATABASE_NEBULA.equalsIgnoreCase(database) == false) { - return result.toJSONString(); - } - - return com.alibaba.fastjson.JSON.toJSONString(result, new ValueFilter() { - @Override - public Object process(Object o, String key, Object val) { -// if (val instanceof ValueWrapper) { -// return process(o, key, ((ValueWrapper) val).getValue()); -// } -// -// if (val instanceof Value) { -// return process(o, key, ((Value) val).getFieldValue()); -// } -// -// if (val instanceof Vertex) { -// JSONObject obj = new JSONObject(true); -// obj.put("vid", new String(((Vertex) val).getVid().getSVal())); -// obj.put("str", val.toString()); -// -// List tags = ((Vertex) val).getTags(); -// -// if (tags != null) { -// JSONArray arr = new JSONArray(); -// for (int i = 0; i < tags.size(); i++) { -// arr.add(process(o, String.valueOf(i), tags.get(i))); -// } -// obj.put("tags", arr); -// } -// -// return obj; -// } -// -// if (val instanceof Tag) { -// JSONObject obj = new JSONObject(true); -// obj.put("name", new String(((Tag) val).getName())); -// obj.put("str", val.toString()); -// -// Map props = ((Tag) val).getProps(); -// -// if (props != null) { -// JSONObject propsObj = new JSONObject(true); -// props.forEach(new BiConsumer() { -// @Override -// public void accept(byte[] bytes, Value value) { -// String k = new String(bytes); -// propsObj.put(k, process(propsObj, k, value)); -// } -// }); -// obj.put("props", propsObj); -// } -// -// return obj; -// } -// -// if (val instanceof Edge) { -// JSONObject obj = new JSONObject(true); -// obj.put("name", new String(((Edge) val).getName())); -// obj.put("str", val.toString()); -// -// Map props = ((Edge) val).getProps(); -// -// if (props != null) { -// JSONObject propsObj = new JSONObject(true); -// props.forEach(new BiConsumer() { -// @Override -// public void accept(byte[] bytes, Value value) { -// String k = new String(bytes); -// propsObj.put(k, process(propsObj, k, value)); -// } -// }); -// obj.put("props", propsObj); -// } -// -// return obj; -// } -// -// if (val instanceof NullType) { -// return null; -// } -// -// if (val instanceof DateWrapper) { -// return ((DateWrapper) val).toString(); -// } -// -// if (val instanceof TimeWrapper) { -// return ((TimeWrapper) val).getLocalTimeStr(); -// } -// -// if (val instanceof DateTimeWrapper) { -// return ((DateTimeWrapper) val).getLocalDateTimeStr(); -// } -// -// if (val instanceof DurationWrapper) { -// return ((DurationWrapper) val).getMicroseconds(); -// } -// -// if (val instanceof Date) { -// Date d = (Date) val; -// return new java.sql.Date(d.getYear() - 1900, d.getMonth(), d.getDay()).toString(); -// } -// -// if (val instanceof Time) { -// Time t = (Time) val; -// return new java.sql.Time(t.getHour(), t.getMinute(), t.getSec()).toString(); -// } -// -// if (val instanceof DateTime) { -// DateTime dt = (DateTime) val; -// // return new java.util.Date(dt.getYear(), dt.getNonth(), dt.getDayO, dt.getHour(), dt.getMinute(), dt.getSec0).toGnTString(); -// return new java.sql.Date(dt.getYear() - 1988, dt.getMonth(), dt.getDay()) -// + " " + new java.sql.Time(dt.getHour(), dt.getMinute(), dt.getSec()); -// } -// -// if (val instanceof Duration) { -// return ((Duration) val).getMicroseconds(); -// } - - return val; - } - }, SerializerFeature.WriteMapNullValue); + return result.toJSONString(); } catch (Exception e) { - JSONObject result = DemoParser.newErrorResult(e); + JSONObject result = newErrorResult(e); result.put("throw", e.getClass().getName()); result.put("trace:stack", e.getStackTrace()); @@ -2322,7 +2184,7 @@ public Object process(Object o, String key, Object val) { return result.toJSONString(); } } catch (Exception e) { - JSONObject result = DemoParser.newErrorResult(e); + JSONObject result = newErrorResult(e); result.put("throw", e.getClass().getName()); result.put("trace:stack", e.getStackTrace()); return result.toJSONString(); @@ -2797,15 +2659,15 @@ public String ui() { // 为 UnitAuto 提供的单元测试接口 https://github.com/TommyLemon/UnitAuto <<<<<<<<<<<<<<<<<<<<<<<<<<< - @PostMapping("method/list") - public JSONObject listMethod(@RequestBody String request) { - return super.listMethod(request); - } - - @PostMapping("method/invoke") - public void invokeMethod(@RequestBody String request, HttpServletRequest servletRequest) { - super.invokeMethod(request, servletRequest); - } + //@PostMapping("method/list") + //public JSONMap listMethod(@RequestBody String request) { + // return super.listMethod(request); + //} + // + //@PostMapping("method/invoke") + //public void invokeMethod(@RequestBody String request, HttpServletRequest servletRequest) { + // super.invokeMethod(request, servletRequest); + //} // 为 UnitAuto 提供的单元测试接口 https://github.com/TommyLemon/UnitAuto >>>>>>>>>>>>>>>>>>>>>>>>>>>>>> diff --git a/APIJSON-Java-Server/APIJSONBoot-MultiDataSource/src/main/java/apijson/boot/FileController.java b/APIJSON-Java-Server/APIJSONBoot-MultiDataSource/src/main/java/apijson/boot/FileController.java index 7687633d..98948702 100755 --- a/APIJSON-Java-Server/APIJSONBoot-MultiDataSource/src/main/java/apijson/boot/FileController.java +++ b/APIJSON-Java-Server/APIJSONBoot-MultiDataSource/src/main/java/apijson/boot/FileController.java @@ -21,7 +21,7 @@ import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.multipart.MultipartFile; -import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson2.JSONObject; import apijson.demo.DemoParser; @@ -78,7 +78,7 @@ public void initFileRepository(){ public JSONObject files() { JSONObject res = new JSONObject(); res.put("data", fileRepository); - return DemoParser.extendSuccessResult(res); + return new DemoParser().extendSuccessResult(res); } @PostMapping(value = "/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) @@ -96,11 +96,11 @@ public JSONObject upload(@RequestParam("file") MultipartFile file) { JSONObject res = new JSONObject(); res.put("path", file.getOriginalFilename()); res.put("size", file.getBytes().length); - return DemoParser.extendSuccessResult(res); + return new DemoParser().extendSuccessResult(res); } catch (Exception e) { e.printStackTrace(); - return DemoParser.newErrorResult(e); + return new DemoParser().newErrorResult(e); } } diff --git a/APIJSON-Java-Server/APIJSONBoot-MultiDataSource/src/main/java/apijson/demo/DemoFunctionParser.java b/APIJSON-Java-Server/APIJSONBoot-MultiDataSource/src/main/java/apijson/demo/DemoFunctionParser.java index 0f58395a..b0262156 100644 --- a/APIJSON-Java-Server/APIJSONBoot-MultiDataSource/src/main/java/apijson/demo/DemoFunctionParser.java +++ b/APIJSON-Java-Server/APIJSONBoot-MultiDataSource/src/main/java/apijson/demo/DemoFunctionParser.java @@ -16,20 +16,20 @@ import java.util.*; +import apijson.NotNull; +import apijson.RequestMethod; +import apijson.StringUtil; +import apijson.fastjson2.JSON; +import apijson.fastjson2.JSONRequest; +import apijson.fastjson2.JSONResponse; import jakarta.servlet.http.HttpSession; import apijson.orm.script.JavaScriptExecutor; -import com.alibaba.fastjson.JSON; -import com.alibaba.fastjson.JSONArray; -import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson2.JSONArray; +import com.alibaba.fastjson2.JSONObject; -import apijson.JSONResponse; -import apijson.NotNull; -import apijson.RequestMethod; -import apijson.StringUtil; -import apijson.framework.APIJSONFunctionParser; +import apijson.fastjson2.APIJSONFunctionParser; import apijson.orm.AbstractVerifier; -import apijson.orm.JSONRequest; import apijson.orm.Visitor; @@ -41,7 +41,7 @@ public class DemoFunctionParser extends APIJSONFunctionParser { public static final String TAG = "DemoFunctionParser"; static { - SCRIPT_EXECUTOR_MAP.put("js", new JavaScriptExecutor()); + SCRIPT_EXECUTOR_MAP.put("js", new JavaScriptExecutor()); } public DemoFunctionParser() { @@ -100,13 +100,6 @@ public void verifyIdList(@NotNull JSONObject curObj, @NotNull String idList) thr } } - @Override - public boolean isContain(JSONObject curObj, String array, String value) { - List list = apijson.JSON.parseArray(getArgStr(array), String.class); - Object val = getArgVal(value); - return list != null && list.contains(val == null ? null : String.valueOf(val)); - } - /** * @param curObj * @param urlList @@ -148,10 +141,10 @@ public int deleteCommentOfMoment(@NotNull JSONObject curObj, @NotNull String mom return 0; } - JSONRequest request = new JSONRequest(); + JSONObject request = JSON.newJSONObject(); //Comment<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - JSONRequest comment = new JSONRequest(); + JSONObject comment = JSON.newJSONObject(); comment.put("momentId", mid); request.put("Comment", comment); @@ -177,10 +170,10 @@ public int deleteChildComment(@NotNull JSONObject curObj, @NotNull String toId) //递归获取到全部子评论id - JSONRequest request = new JSONRequest(); + JSONObject request = JSON.newJSONObject(); //Comment<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - JSONRequest comment = new JSONRequest(); + JSONObject comment = JSON.newJSONObject();; comment.put("id{}", getChildCommentIdList(tid)); request.put("Comment", comment); @@ -196,7 +189,7 @@ public int deleteChildComment(@NotNull JSONObject curObj, @NotNull String toId) private JSONArray getChildCommentIdList(long tid) { JSONArray arr = new JSONArray(); - JSONRequest request = new JSONRequest(); + JSONObject request = JSON.newJSONObject(); //Comment-id[]<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< JSONRequest idItem = new JSONRequest(); @@ -205,10 +198,10 @@ private JSONArray getChildCommentIdList(long tid) { JSONRequest comment = new JSONRequest(); comment.put("toId", tid); comment.setColumn("id"); - idItem.put("Comment", comment); + idItem.put("Comment", JSON.newJSONObject(comment)); //Comment>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - request.putAll(idItem.toArray(0, 0, "Comment-id")); + request.putAll(JSON.newJSONObject(idItem.toArray(0, 0, "Comment-id"))); //Comment-id[]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> JSONObject rp = new DemoParser().setNeedVerify(false).parseResponse(request); @@ -217,10 +210,9 @@ private JSONArray getChildCommentIdList(long tid) { if (a != null) { arr.addAll(a); - JSONArray a2; for (int i = 0; i < a.size(); i++) { - a2 = getChildCommentIdList(a.getLongValue(i)); + JSONArray a2 = getChildCommentIdList(a.getLongValue(i)); if (a2 != null) { arr.addAll(a2); } @@ -233,8 +225,7 @@ private JSONArray getChildCommentIdList(long tid) { /**TODO 仅用来测试 "key-()":"getIdList()" 和 "key()":"getIdList()" * @param curObj - * @return JSONArray 只能用JSONArray,用long[]会在SQLConfig解析崩溃 - * @throws Exception + * @return JSONList 只能用JSONArray,用long[]会在SQLConfig解析崩溃 */ public JSONArray getIdList(@NotNull JSONObject curObj) { return new JSONArray(new ArrayList(Arrays.asList(12, 15, 301, 82001, 82002, 38710))); @@ -256,10 +247,10 @@ public Object verifyAccess(@NotNull JSONObject curObj) throws Exception { } // apijson-framework 5.4.0 以下取消注释,兼容 Function 表中 name = getMethodDefinition 的记录(或者删除这条记录,如果使用 UnitAuto,则版本要在 2.7.2 以下) - // public String getMethodDefinition(JSONObject request) throws IllegalArgumentException, ClassNotFoundException, IOException { + // public String getMethodDefinition(JSONMap request) throws IllegalArgumentException, ClassNotFoundException, IOException { // return super.getMethodDefination(request); // } - // public String getMethodDefinition(JSONObject request, String method, String arguments, String type, String exceptions, String language) throws IllegalArgumentException, ClassNotFoundException, IOException { + // public String getMethodDefinition(JSONMap request, String method, String arguments, String type, String exceptions, String language) throws IllegalArgumentException, ClassNotFoundException, IOException { // return super.getMethodDefination(request, method, arguments, type, exceptions, language); // } @@ -280,4 +271,5 @@ public void verifyGroupUrlLike(@NotNull JSONObject curObj, String urlLike) throw throw new IllegalArgumentException(urlLike + "必须以包含有效 URL 字符!"); } } + } \ No newline at end of file diff --git a/APIJSON-Java-Server/APIJSONBoot-MultiDataSource/src/main/java/apijson/demo/DemoObjectParser.java b/APIJSON-Java-Server/APIJSONBoot-MultiDataSource/src/main/java/apijson/demo/DemoObjectParser.java index b4ef70fb..960cfba3 100644 --- a/APIJSON-Java-Server/APIJSONBoot-MultiDataSource/src/main/java/apijson/demo/DemoObjectParser.java +++ b/APIJSON-Java-Server/APIJSONBoot-MultiDataSource/src/main/java/apijson/demo/DemoObjectParser.java @@ -14,7 +14,8 @@ package apijson.demo; -import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson2.JSONArray; +import com.alibaba.fastjson2.JSONObject; import java.util.List; @@ -22,7 +23,7 @@ import apijson.NotNull; import apijson.RequestMethod; -import apijson.framework.APIJSONObjectParser; +import apijson.fastjson2.APIJSONObjectParser; import apijson.orm.Join; import apijson.orm.SQLConfig; @@ -32,13 +33,15 @@ */ public class DemoObjectParser extends APIJSONObjectParser { - public DemoObjectParser(HttpSession session, @NotNull JSONObject request, String parentPath, SQLConfig arrayConfig + public DemoObjectParser(HttpSession session, @NotNull JSONObject request, String parentPath + , SQLConfig arrayConfig , boolean isSubquery, boolean isTable, boolean isArrayMainTable) throws Exception { super(session, request, parentPath, arrayConfig, isSubquery, isTable, isArrayMainTable); } @Override - public SQLConfig newSQLConfig(RequestMethod method, String table, String alias, JSONObject request, List joinList, boolean isProcedure) throws Exception { + public SQLConfig newSQLConfig(RequestMethod method, String table, String alias + , JSONObject request, List> joinList, boolean isProcedure) throws Exception { return DemoSQLConfig.newSQLConfig(method, table, alias, request, joinList, isProcedure); } diff --git a/APIJSON-Java-Server/APIJSONBoot-MultiDataSource/src/main/java/apijson/demo/DemoParser.java b/APIJSON-Java-Server/APIJSONBoot-MultiDataSource/src/main/java/apijson/demo/DemoParser.java index c0a3e348..3cfd27e0 100644 --- a/APIJSON-Java-Server/APIJSONBoot-MultiDataSource/src/main/java/apijson/demo/DemoParser.java +++ b/APIJSON-Java-Server/APIJSONBoot-MultiDataSource/src/main/java/apijson/demo/DemoParser.java @@ -14,7 +14,9 @@ package apijson.demo; -import com.alibaba.fastjson.JSONObject; + +import com.alibaba.fastjson2.JSONArray; +import com.alibaba.fastjson2.JSONObject; import java.util.HashMap; import java.util.Map; @@ -25,10 +27,8 @@ import apijson.StringUtil; import apijson.boot.DemoController; import apijson.demo.model.Privacy; -import apijson.demo.model.User; -import apijson.framework.APIJSONObjectParser; -import apijson.framework.APIJSONParser; -import apijson.framework.APIJSONVerifier; +import apijson.fastjson2.APIJSONObjectParser; +import apijson.fastjson2.APIJSONParser; import apijson.orm.SQLConfig; @@ -53,34 +53,40 @@ public DemoParser(RequestMethod method, boolean needVerify) { super(method, needVerify); } -// // 可重写来设置分页页码是否从 1 开始,true - 从 1 开始;false - 从 0 开始 + + @Override + public DemoParser setNeedVerify(boolean needVerify) { + super.setNeedVerify(needVerify); + return this; + } + + // // 可重写来设置分页页码是否从 1 开始,true - 从 1 开始;false - 从 0 开始 // @Override // public boolean isStartFrom1() { // return true; // } private int maxQueryCount = 2000; -// // 可重写来设置最大查询数量 -// @Override -// public int getMaxQueryCount() { -// return maxQueryCount; -// } -// -// @Override -// public int getMaxUpdateCount() { -// return 2000; -// } -// -// @Override -// public int getMaxObjectCount() { -// return getMaxUpdateCount(); -// } -// -// @Override -// public int getMaxSQLCount() { -// return getMaxUpdateCount(); -// } + // 可重写来设置最大查询数量 + @Override + public int getMaxQueryCount() { + return maxQueryCount; + } + + @Override + public int getMaxUpdateCount() { + return 2000; + } + @Override + public int getMaxObjectCount() { + return getMaxUpdateCount(); + } + + @Override + public int getMaxSQLCount() { + return getMaxUpdateCount(); + } @Override public JSONObject parseResponse(JSONObject request) { @@ -96,8 +102,10 @@ public JSONObject parseResponse(JSONObject request) { return super.parseResponse(request); } + @Override - public APIJSONObjectParser createObjectParser(JSONObject request, String parentPath, SQLConfig arrayConfig + public APIJSONObjectParser createObjectParser(JSONObject request, String parentPath + , SQLConfig arrayConfig , boolean isSubquery, boolean isTable, boolean isArrayMainTable) throws Exception { return new DemoObjectParser(getSession(), request, parentPath, arrayConfig , isSubquery, isTable, isArrayMainTable).setMethod(getMethod()).setParser(this); @@ -109,12 +117,12 @@ public APIJSONObjectParser createObjectParser(JSONObject request, String p private String dbPassword; @Override public APIJSONParser setSession(HttpSession session) { - Boolean asDBAccount = (Boolean) session.getAttribute(DemoController.AS_DB_ACCOUNT); + Boolean asDBAccount = session == null ? null : (Boolean) session.getAttribute(DemoController.AS_DB_ACCOUNT); this.asDBAccount = asDBAccount != null && asDBAccount; if (this.asDBAccount) { // User user = (User) session.getAttribute(DemoController.USER_); // this.dbAccount = user.getName(); - Privacy privacy = (Privacy) session.getAttribute(DemoController.PRIVACY_); + Privacy privacy = session == null ? null : (Privacy) session.getAttribute(DemoController.PRIVACY_); this.dbAccount = privacy.getPhone(); this.dbPassword = privacy.get__password(); } @@ -123,13 +131,13 @@ public APIJSONParser setSession(HttpSession session) { } @Override - public JSONObject executeSQL(SQLConfig config, boolean isSubquery) throws Exception { + public JSONObject executeSQL(SQLConfig config, boolean isSubquery) throws Exception { if (asDBAccount && config instanceof DemoSQLConfig) { DemoSQLConfig cfg = (DemoSQLConfig) config; - if (StringUtil.isEmpty(cfg.getDBAccount())) { + if (StringUtil.isEmpty(cfg.gainDBAccount())) { cfg.setDBAccount(dbAccount); } - if (StringUtil.isEmpty(cfg.getDBPassword())) { + if (StringUtil.isEmpty(cfg.gainDBPassword())) { cfg.setDBPassword(dbPassword); } } diff --git a/APIJSON-Java-Server/APIJSONBoot-MultiDataSource/src/main/java/apijson/demo/DemoSQLConfig.java b/APIJSON-Java-Server/APIJSONBoot-MultiDataSource/src/main/java/apijson/demo/DemoSQLConfig.java index ca8cba32..ad09e0e1 100755 --- a/APIJSON-Java-Server/APIJSONBoot-MultiDataSource/src/main/java/apijson/demo/DemoSQLConfig.java +++ b/APIJSON-Java-Server/APIJSONBoot-MultiDataSource/src/main/java/apijson/demo/DemoSQLConfig.java @@ -22,16 +22,20 @@ import java.text.SimpleDateFormat; import java.util.*; -import apijson.*; //import apijson.influxdb.InfluxDBUtil; //import apijson.iotdb.IoTDBUtil; +import apijson.RequestMethod; +import apijson.StringUtil; import apijson.orm.AbstractParser; import apijson.orm.AbstractSQLConfig; import apijson.orm.Parser; +//import apijson.surrealdb.SurrealDBUtil; +import com.alibaba.fastjson2.JSONArray; +import com.alibaba.fastjson2.JSONObject; import com.alibaba.fastjson.annotation.JSONField; -import apijson.column.ColumnUtil; -import apijson.framework.APIJSONSQLConfig; +import apijson.framework.ColumnUtil; +import apijson.fastjson2.APIJSONSQLConfig; import apijson.orm.Join; import apijson.orm.Join.On; //import org.influxdb.InfluxDB; @@ -54,7 +58,9 @@ public DemoSQLConfig(RequestMethod method, String table) { static { DEFAULT_DATABASE = DATABASE_MYSQL; //TODO 默认数据库类型,改成你自己的。TiDB, MariaDB, OceanBase 这类兼容 MySQL 的可当做 MySQL 使用 - DEFAULT_SCHEMA = "sys"; // ""apijson"; //TODO 默认数据库名/模式,改成你自己的,默认情况是 MySQL: sys, PostgreSQL: sys, SQL Server: dbo, Oracle: + // DEFAULT_NAMESPACE = "root"; //TODO 默认数据库名/模式,改成你自己的,仅对 SurrealDB: root 等数据库有效 + // DEFAULT_CATALOG = "postgres"; //TODO 默认数据库名/模式,改成你自己的,仅对 PostgreSQL: posgres 等数据库有效 + DEFAULT_SCHEMA = "sys"; // "apijson"; //TODO 默认数据库名/模式,改成你自己的,默认情况是 MySQL: sys, PostgreSQL: sys, SQL Server: dbo, Manticore: Manticore, Oracle: // 表名和数据库不一致的,需要配置映射关系。只使用 APIJSONORM 时才需要; // 这个 Demo 用了 apijson-framework 且调用了 APIJSONApplication.init 则不需要 @@ -70,16 +76,18 @@ public DemoSQLConfig(RequestMethod method, String table) { SIMPLE_CALLBACK = new SimpleCallback() { @Override - public AbstractSQLConfig getSQLConfig(RequestMethod method, String database, String schema, String datasource, String table) { + public AbstractSQLConfig getSQLConfig( + RequestMethod method, String database, String schema, String datasource, String table) { return new DemoSQLConfig(method, table); } //取消注释来实现自定义各个表的主键名 // @Override // public String getIdKey(String database, String schema, String datasource, String table) { + // // return "_id"; // SurrealDB 强制用 id 作为主键名,surrealdb.java 查不到也改不了,所以需要另外加主键 // return StringUtil.firstCase(table + "Id"); // userId, comemntId ... - // // return StringUtil.toLowerCase(t) + "_id"; // user_id, comemnt_id ... - // // return StringUtil.toUpperCase(t) + "_ID"; // USER_ID, COMMENT_ID ... + // // return StringUtil.toLowerCase(t) + "_id"; // user_id, comemnt_id ... + // // return StringUtil.toUpperCase(t) + "_ID"; // USER_ID, COMMENT_ID ... // } @Override @@ -94,7 +102,7 @@ public String getUserIdKey(String database, String schema, String datasource, St // } // @Override - // public void onMissingKey4Combine(String name, JSONObject request, String combine, String item, String key) throws Exception { + // public void onMissingKey4Combine(String name, JSONMap request, String combine, String item, String key) throws Exception { //// super.onMissingKey4Combine(name, request, combine, item, key); // } }; @@ -103,6 +111,7 @@ public String getUserIdKey(String database, String schema, String datasource, St RAW_MAP.put("`to`.`id`", ""); // 空字符串 "" 表示用 key 的值 `to`.`id` RAW_MAP.put("toDate", ""); // "@column": "date;date_format('2020-01-01','%Y-%m-%d'):toDate", "@having": "(date > toDate)", "@raw": "@column,@having" RAW_MAP.put("to.momentId", "`to`.`momentId`"); // 最终以 `to`.`userId` 拼接 SQL,相比以上写法可以让前端写起来更简单 + RAW_MAP.put("Comment:to.momentId", "`Comment__to`.`momentId`"); // 最终以 `Comment__to`.`userId` 拼接 SQL,相比以上写法可以让前端写起来更简单 RAW_MAP.put("(`Comment`.`userId`=`to`.`userId`)", ""); // 已经是一个条件表达式了,用 () 包裹是为了避免 JSON 中的 key 拼接在前面导致 SQL 出错 RAW_MAP.put("sum(if(userId%2=0,1,0))", ""); // 超过单个函数的 SQL 表达式 RAW_MAP.put("sumUserIdIsEven", "sum(if(`userId`%2=0,1,0)) AS sumUserIdIsEven"); // 简化前端传参 @@ -136,13 +145,39 @@ public String getUserIdKey(String database, String schema, String datasource, St RAW_MAP.put("(CASE WHEN package LIKE '*%' THEN substr(package,2) ELSE package END) `url`", ""); // UnitAuto 获取分组 RAW_MAP.put("(CASE WHEN package LIKE '*%' THEN substr(package,2) ELSE package END) `groupUrl`", ""); // UnitAuto 获取分组 RAW_MAP.put("(CASE WHEN package LIKE '*%' THEN substr(package,2) ELSE package END):groupUrl", "(CASE WHEN package LIKE '*%' THEN substr(package,2) ELSE package END) `groupUrl`"); // UnitAuto 获取分组 + + // 反选字段配置 + Map> tableColumnMap = new HashMap<>(); + tableColumnMap.put("User", Arrays.asList(StringUtil.split("id,sex,name,tag,head,contactIdList,pictureList,date"))); + // 需要对应方法传参也是这样拼接才行,例如 ColumnUtil.compatInputColumn(column, getSQLDatabase() + "-" + getSQLSchema() + "-" + getTable(), getMethod()); + tableColumnMap.put("MYSQL-sys-Privacy", Arrays.asList(StringUtil.split("id,certified,phone,balance,_password,_payPassword"))); + ColumnUtil.VERSIONED_TABLE_COLUMN_MAP.put(null, tableColumnMap); + + // 字段名映射配置 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + Map> tableKeyColumnMap = new HashMap<>(); + + Map userKeyColumnMap = new HashMap<>(); + userKeyColumnMap.put("gender", "sex"); + userKeyColumnMap.put("createTime", "date"); + tableKeyColumnMap.put("User", userKeyColumnMap); + + Map privacyKeyColumnMap = new HashMap<>(); + privacyKeyColumnMap.put("rest", "balance"); + // 需要对应方法传参也是这样拼接才行,例如 ColumnUtil.compatInputKey(super.getKey(key), getSQLDatabase() + "-" + getSQLSchema() + "-" + getTable(), getMethod()); + tableKeyColumnMap.put("MYSQL-sys-Privacy", privacyKeyColumnMap); + + ColumnUtil.VERSIONED_KEY_COLUMN_MAP.put(null, tableKeyColumnMap); + // 字段名映射配置 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + + ColumnUtil.init(); + } // 如果 DemoSQLExecutor.getConnection 能拿到连接池的有效 Connection,则这里不需要配置 dbVersion, dbUri, dbAccount, dbPassword @Override - public String getDBVersion() { + public String gainDBVersion() { if (isMySQL()) { // return "5.7.22"; // return "8.0.11"; //TODO 改成你自己的 MySQL 或 PostgreSQL 数据库版本号 //MYSQL 8 和 7 使用的 JDBC 配置不一样 @@ -159,9 +194,9 @@ public String getDBVersion() { if (isDb2()) { return "11.5"; //TODO 改成你自己的 } - //if (isSQLite()) { - // return "3.39.3"; //TODO 改成你自己的 - //} + // if (isSQLite()) { + // return "3.39.3"; //TODO 改成你自己的 + // } if (isDameng()) { return "8.1.2.141"; //TODO 改成你自己的 } @@ -171,15 +206,24 @@ public String getDBVersion() { if (isMilvus()) { return "2.3.4"; //TODO 改成你自己的 } - if (isIoTDB()) { - return "1.3.1"; //TODO 改成你自己的 - } + // if (isIoTDB()) { + // return "1.3.1"; //TODO 改成你自己的 + // } if (isMongoDB()) { return "6.0.12"; //TODO 改成你自己的 } if (isCassandra()) { return "4.0.1"; //TODO 改成你自己的 } + // if (isDuckDB()) { + // return "1.1.3"; //TODO 改成你自己的 + // } + // if (isSurrealDB()) { + // return "2.0.0"; //TODO 改成你自己的 + // } + // if (isOpenGauss()) { + // return "5.0.0"; //TODO 改成你自己的 + // } return null; } @@ -189,22 +233,25 @@ public DemoSQLConfig setDBUri(String dbUri) { this.dbUri = dbUri; return this; } - @JSONField(serialize = false) // 不在日志打印 账号/密码 等敏感信息,用了 UnitAuto 则一定要加 @Override - public String getDBUri() { + public String gainDBUri() { if (StringUtil.isNotEmpty(dbUri)) { return dbUri; } if (isMySQL()) { // 这个是 MySQL 8.0 及以上,要加 userSSL=false -// return "jdbc:mysql://47.122.25.116:3306?userSSL=false&serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=UTF-8"; + // return "jdbc:mysql://47.122.25.116:3306?userSSL=false&serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=UTF-8"; // 以下是 MySQL 5.7 及以下 return "jdbc:mysql://localhost:3306?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=UTF-8"; //TODO 改成你自己的,TiDB 可以当成 MySQL 使用,默认端口为 4000 } - if (isPostgreSQL()) { + if (isPostgreSQL()) { // PG JDBC 必须在 URI 传 catalog return "jdbc:postgresql://localhost:5432/postgres?stringtype=unspecified"; //TODO 改成你自己的 } + //if (isCockroachDB()) { // PG JDBC 必须在 URI 传 catalog + // return "jdbc:postgresql://localhost:26257/movr?sslmode=require"; //TODO 改成你自己的 brew install cockroachdb/tap/cockroach && cockroach demo + // // return "jdbc:postgresql://localhost:26258/postgres?sslmode=disable"; //TODO 改成你自己的 brew install cockroachdb/tap/cockroach # && start 3 nodes and init cluster + //} if (isSQLServer()) { return "jdbc:jtds:sqlserver://localhost:1433/pubs;instance=SQLEXPRESS"; //TODO 改成你自己的 } @@ -214,9 +261,9 @@ public String getDBUri() { if (isDb2()) { return "jdbc:db2://localhost:50000/BLUDB"; //TODO 改成你自己的 } - //if (isSQLite()) { - // return "jdbc:sqlite:sample.db"; //TODO 改成你自己的 - //} + // if (isSQLite()) { + // return "jdbc:sqlite:sample.db"; //TODO 改成你自己的 + // } if (isDameng()) { return "jdbc:dm://localhost:5236"; //TODO 改成你自己的 } @@ -224,23 +271,46 @@ public String getDBUri() { // return "jdbc:TAOS://localhost:6030"; //TODO 改成你自己的 return "jdbc:TAOS-RS://localhost:6041"; //TODO 改成你自己的 } - if (isInfluxDB()) { - return "http://203.189.6.3:8086"; + if (isTimescaleDB()) { // PG JDBC 必须在 URI 传 catalog + return "jdbc:postgresql://localhost:5432/postgres?stringtype=unspecified"; //TODO 改成你自己的 } - if (isMilvus()) { - return "http://localhost:19530"; + if (isQuestDB()) { // PG JDBC 必须在 URI 传 catalog + return "jdbc:postgresql://localhost:8812/qdb"; //TODO 改成你自己的 } - if (isIoTDB()) { - return "jdbc:iotdb://localhost:6667"; // ?charset=GB18030 加参数会报错 URI 格式错误 + if (isInfluxDB()) { + return "http://203.189.6.3:8086"; //TODO 改成你自己的 } + if (isMilvus()) { + return "http://localhost:19530"; //TODO 改成你自己的 + } + //if (isManticore()) { + // return "jdbc:mysql://localhost:9306?characterEncoding=utf8&maxAllowedPacket=512000"; //TODO 改成你自己的 + //} + //if (isIoTDB()) { + // return "jdbc:iotdb://localhost:6667"; // ?charset=GB18030 加参数会报错 URI 格式错误 //TODO 改成你自己的 + //} if (isMongoDB()) { - return "jdbc:mongodb://atlas-sql-6593c65c296c5865121e6ebe-xxskv.a.query.mongodb.net/myVirtualDatabase?ssl=true&authSource=admin"; + return "jdbc:mongodb://atlas-sql-6593c65c296c5865121e6ebe-xxskv.a.query.mongodb.net/myVirtualDatabase?ssl=true&authSource=admin"; //TODO 改成你自己的 } if (isCassandra()) { - return "http://localhost:7001"; - } - - return null; + return "http://localhost:7001"; //TODO 改成你自己的 + } + //if (isDuckDB()) { + // return "jdbc:duckdb:/Users/tommylemon/my_database.duckdb"; //TODO 改成你自己的 + //} + //if (isSurrealDB()) { + // // return "memory"; //TODO 改成你自己的 + // // return "surrealkv://localhost:8000"; //TODO 改成你自己的 + // return "ws://localhost:8000"; //TODO 改成你自己的 + //} + //if (isOpenGauss()) { + // return "jdbc:opengauss://127.0.0.1:5432/postgres?currentSchema=" + DEFAULT_SCHEMA; //TODO 改成你自己的 + //} + //if (isDoris()) { + // return "jdbc:mysql://localhost:9030"; //TODO 改成你自己的,TiDB 可以当成 MySQL 使用,默认端口为 4000 + //} + + return super.gainDBUri(); } private String dbAccount; @@ -248,9 +318,8 @@ public DemoSQLConfig setDBAccount(String dbAccount) { this.dbAccount = dbAccount; return this; } - @JSONField(serialize = false) // 不在日志打印 账号/密码 等敏感信息,用了 UnitAuto 则一定要加 @Override - public String getDBAccount() { + public String gainDBAccount() { if (StringUtil.isNotEmpty(dbAccount)) { return dbAccount; } @@ -261,6 +330,10 @@ public String getDBAccount() { if (isPostgreSQL()) { return "postgres"; //TODO 改成你自己的 } + //if (isCockroachDB()) { // PG JDBC 必须在 URI 传 catalog + // return "demo"; //TODO 改成你自己的 + // //return "postgres"; //TODO 改成你自己的 + //} if (isSQLServer()) { return "sa"; //TODO 改成你自己的 } @@ -270,32 +343,54 @@ public String getDBAccount() { if (isDb2()) { return "db2admin"; //TODO 改成你自己的 } - //if (isSQLite()) { - // return "root"; //TODO 改成你自己的 - //} + // if (isSQLite()) { + // return "root"; //TODO 改成你自己的 + // } if (isDameng()) { return "SYSDBA"; } if (isTDengine()) { return "root"; //TODO 改成你自己的 } + //if (isTimescaleDB()) { + // return "postgres"; //TODO 改成你自己的 + //} + if (isQuestDB()) { + return "admin"; //TODO 改成你自己的 + } if (isInfluxDB()) { return "iotos"; } if (isMilvus()) { return "root"; } - if (isIoTDB()) { - return "root"; - } + //if (isManticore()) { + // return null; // "root"; + //} + //if (isIoTDB()) { + // return "root"; + //} if (isMongoDB()) { return "root"; //TODO 改成你自己的 } if (isCassandra()) { return "root"; //TODO 改成你自己的 } - - return null; + //if (isDuckDB()) { + // return "root"; //TODO 改成你自己的 + //} + //if (isSurrealDB()) { + // return "root"; //TODO 改成你自己的 + //} + //if (isOpenGauss()) { + // return "postgres"; //TODO 改成你自己的 + // // 不允许用初始账号,需要 CREATE USER 创建新账号并 GRANT 授权 return "opengauss"; //TODO 改成你自己的 + //} + //if (isDoris()) { + // return "root"; + //} + + return super.gainDBAccount(); } private String dbPassword; @@ -303,9 +398,8 @@ public DemoSQLConfig setDBPassword(String dbPassword) { this.dbPassword = dbPassword; return this; } - @JSONField(serialize = false) // 不在日志打印 账号/密码 等敏感信息,用了 UnitAuto 则一定要加 @Override - public String getDBPassword() { + public String gainDBPassword() { if (StringUtil.isNotEmpty(dbPassword)) { return dbPassword; } @@ -316,6 +410,10 @@ public String getDBPassword() { if (isPostgreSQL()) { return null; //TODO 改成你自己的 } + //if (isCockroachDB()) { // PG JDBC 必须在 URI 传 catalog + // return "demo39865"; //TODO 改成你自己的 + // // return null; //TODO 改成你自己的 + //} if (isSQLServer()) { return "apijson@123"; //TODO 改成你自己的 } @@ -325,44 +423,65 @@ public String getDBPassword() { if (isDb2()) { return "123"; //TODO 改成你自己的 } - //if (isSQLite()) { - // return "apijson"; //TODO 改成你自己的 - //} + // if (isSQLite()) { + // return "apijson"; //TODO 改成你自己的 + // } if (isDameng()) { return "SYSDBA"; } if (isTDengine()) { return "taosdata"; //TODO 改成你自己的 } + if (isTimescaleDB()) { + return "password"; //TODO 改成你自己的 + } + if (isQuestDB()) { + return "quest"; //TODO 改成你自己的 + } if (isInfluxDB()) { return "apijson@123"; //TODO 改成你自己的 } if (isMilvus()) { return "apijson"; //TODO 改成你自己的 } - if (isIoTDB()) { - return "root"; - } + //if (isManticore()) { + // return null; + //} + //if (isIoTDB()) { + // return "root"; + //} if (isMongoDB()) { return "apijson"; //TODO 改成你自己的 } if (isCassandra()) { return "apijson"; //TODO 改成你自己的 } - - return null; + //if (isDuckDB()) { + // return ""; //TODO 改成你自己的 + //} + //if (isSurrealDB()) { + // return "root"; //TODO 改成你自己的 + //} + //if (isOpenGauss()) { + // return "openGauss@123"; //TODO 改成你自己的 + //} + //if (isDoris()) { + // return "apijson"; + //} + + return super.gainDBPassword(); } private String sql; - public String getSQL() throws Exception { - return getSQL(isPrepared()); + public String gainSQL() throws Exception { + return gainSQL(isPrepared()); } @Override - public String getSQL(boolean prepared) throws Exception { + public String gainSQL(boolean prepared) throws Exception { if (StringUtil.isNotEmpty(sql)) { return sql; } - return super.getSQL(prepared); + return super.gainSQL(prepared); } public void setSql(String sql) { @@ -434,15 +553,15 @@ public void setSql(String sql) { @Override - protected void onGetCrossJoinString(Join join) throws UnsupportedOperationException { + protected void onGainCrossJoinString(Join join) throws UnsupportedOperationException { // 开启 CROSS JOIN 笛卡尔积联表 super.onGetCrossJoinString(join); } @Override - protected void onJoinNotRelation(String sql, String quote, Join join, String table, List onList, On on) { + protected void onJoinNotRelation(String sql, String quote, Join join, String table, List onList, On on) { // 开启 JOIN ON t1.c1 != t2.c2 等不等式关联 super.onJoinNotRelation(sql, quote, join, table, onList, on); } @Override - protected void onJoinComplexRelation(String sql, String quote, Join join, String table, List onList, On on) { + protected void onJoinComplexRelation(String sql, String quote, Join join, String table, List onList, On on) { // 开启 JOIN ON t1.c1 LIKE concat('%', t2.c2, '%') 等复杂关联 super.onJoinComplexRelation(sql, quote, join, table, onList, on); } @@ -452,29 +571,44 @@ protected int getMaxCombineCount() { return 10; } -// @Override -// public String getSchema() { -// return InfluxDBUtil.getSchema(super.getSchema(), DEFAULT_SCHEMA, isIoTDB()); -//// return IoTDBUtil.getSchema(super.getSchema(), DEFAULT_SCHEMA, isIoTDB()); -// } -// -// @Override -// public String getSQLSchema() { -// return InfluxDBUtil.getSQLSchema(super.getSQLSchema(), isIoTDB()); -//// return IoTDBUtil.getSQLSchema(super.getSQLSchema().replaceAll("-", "."), isIoTDB()); -// } + // @Override + // public String getNamespace() { + // return SurrealDBUtil.getNamespace(super.getNamespace(), DEFAULT_NAMESPACE, isSurrealDB()); + // } + // + // @Override + // public String getSQLNamespace() { + // return SurrealDBUtil.getSQLNamespace(super.getSQLNamespace(), isSurrealDB()); + // } + // + // @Override + // public String getSchema() { + // return SurrealDBUtil.getSchema(super.getSchema(), DEFAULT_SCHEMA, isSurrealDB()); + //// return InfluxDBUtil.getSchema(super.getSchema(), DEFAULT_SCHEMA, isIoTDB()); + //// return IoTDBUtil.getSchema(super.getSchema(), DEFAULT_SCHEMA, isIoTDB()); + // } + // + // @Override + // public String getSQLSchema() { + // return isOpenGauss() ? "public" : super.getSQLSchema(); + // // return SurrealDBUtil.getSQLSchema(super.getSQLSchema(), isSurrealDB()); + //// return InfluxDBUtil.getSQLSchema(super.getSQLSchema(), isIoTDB()); + //// return IoTDBUtil.getSQLSchema(super.getSQLSchema().replaceAll("-", "."), isIoTDB()); + // } @Override - public String getSQLTable() { - String t = super.getSQLTable(); - return isInfluxDB() || isIoTDB() ? t.toLowerCase() : t; - // return isInfluxDB() ? t.toLowerCase() : StringUtil.firstCase(JSONRequest.recoverUnderline(t, false), false); + public String gainSQLTable() { + String t = super.gainSQLTable(); + return isInfluxDB() ? t.toLowerCase() : t; + //return isInfluxDB() || isManticore() ? t.toLowerCase() : t; + // return isInfluxDB() || isIoTDB() ? t.toLowerCase() : t; + // return isInfluxDB() ? t.toLowerCase() : StringUtil.firstCase(JSONRequest.recoverUnderline(t, false), false); } -// @Override -// public String getTablePath() { -// return IoTDBUtil.getTablePath(super.getTablePath(), isIoTDB()); -// } + // @Override + // public String getTablePath() { + // return IoTDBUtil.getTablePath(super.getTablePath(), isIoTDB()); + // } // 取消注释可将前端传参驼峰命名转为蛇形命名 aBCdEfg => upper ? A_B_CD_EFG : a_b_cd_efg // @Override diff --git a/APIJSON-Java-Server/APIJSONBoot-MultiDataSource/src/main/java/apijson/demo/DemoSQLExecutor.java b/APIJSON-Java-Server/APIJSONBoot-MultiDataSource/src/main/java/apijson/demo/DemoSQLExecutor.java index 386d6c2f..3fcd7658 100644 --- a/APIJSON-Java-Server/APIJSONBoot-MultiDataSource/src/main/java/apijson/demo/DemoSQLExecutor.java +++ b/APIJSON-Java-Server/APIJSONBoot-MultiDataSource/src/main/java/apijson/demo/DemoSQLExecutor.java @@ -17,14 +17,17 @@ import apijson.*; import apijson.boot.DemoApplication; //import apijson.cassandra.CassandraUtil; -import apijson.framework.APIJSONSQLExecutor; +import apijson.fastjson2.APIJSONSQLExecutor; //import apijson.influxdb.InfluxDBUtil; //import apijson.milvus.MilvusUtil; //import apijson.mongodb.MongoUtil; //import apijson.iotdb.IoTDBUtil; import apijson.orm.SQLConfig; +//import apijson.surrealdb.SurrealDBUtil; import com.alibaba.druid.pool.DruidDataSource; -import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson2.JSONObject; +import com.alibaba.fastjson2.JSONArray; +//import org.duckdb.JsonNode; import org.springframework.data.redis.connection.RedisStandaloneConfiguration; import org.springframework.data.redis.connection.jedis.JedisConnectionFactory; import org.springframework.data.redis.core.RedisTemplate; @@ -65,7 +68,7 @@ public class DemoSQLExecutor extends APIJSONSQLExecutor { REDIS_TEMPLATE.setKeySerializer(new StringRedisSerializer()); REDIS_TEMPLATE.setHashValueSerializer(new GenericToStringSerializer<>(Serializable.class)); REDIS_TEMPLATE.setValueSerializer(new GenericToStringSerializer<>(Serializable.class)); - // REDIS_TEMPLATE.setValueSerializer(new FastJsonRedisSerializer>(List.class)); + // REDIS_TEMPLATE.setValueSerializer(new FastJsonRedisSerializer>(List.class)); REDIS_TEMPLATE.afterPropertiesSet(); } catch (Throwable e) { e.printStackTrace(); @@ -74,7 +77,7 @@ public class DemoSQLExecutor extends APIJSONSQLExecutor { // 可重写以下方法,支持 Redis 等单机全局缓存或分布式缓存 @Override - public List getCache(String sql, SQLConfig config) { + public List getCache(String sql, SQLConfig config) { List list = super.getCache(sql, config); if (list == null) { try { @@ -87,7 +90,7 @@ public List getCache(String sql, SQLConfig config) { } @Override - public synchronized void putCache(String sql, List list, SQLConfig config) { + public synchronized void putCache(String sql, List list, SQLConfig config) { super.putCache(sql, list, config); String table = config != null && config.isMain() ? config.getTable() : null; @@ -105,7 +108,7 @@ public synchronized void putCache(String sql, List list, SQLConfig config) { + public synchronized void removeCache(String sql, SQLConfig config) { super.removeCache(sql, config); try { if (config.getMethod() == RequestMethod.DELETE) { // 避免缓存击穿 @@ -120,35 +123,15 @@ public synchronized void removeCache(String sql, SQLConfig config) { // Redis 缓存 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - public static final String DATABASE_NEBULA = "NEBULA"; - // 适配连接池,如果这里能拿到连接池的有效 Connection,则 SQLConfig 不需要配置 dbVersion, dbUri, dbAccount, dbPassword + // 适配连接池,如果这里能拿到连接池的有效 Connection,则 SQLConfig 不需要配置 dbVersion, dbUri, dbAccount, dbPassword @Override - public Connection getConnection(SQLConfig config) throws Exception { -// if (DATABASE_NEBULA.equals(config.getDatabase())) { // 3.0.0 及以下要这样连接 -// String uri = config.getDBUri(); -// -// int start = uri.indexOf("://"); -// String prefix = uri.substring(0, start); -// -// uri = uri.substring(start + "://".length()); -// int end = uri.indexOf("/"); -// String space = uri.substring(end + 1); -// -// Properties props = new Properties(); -// props.put("url", prefix + "://" + space); -// props.put("graphSpace", space); -// -// NebulaDriver driver = new NebulaDriver(uri.substring(0, end)); -// return driver.connect(prefix + "://" + space, props); -// // return DriverManager.getConnection("jdbc:nebula://JDBC_TEST_SPACE", "root", "nebula"); -// } - + public Connection getConnection(SQLConfig config) throws Exception { String datasource = config.getDatasource(); Log.d(TAG, "getConnection config.getDatasource() = " + datasource); String key = datasource + "-" + config.getDatabase(); - Connection c = connectionMap.get(key); + Connection c = getConnection(key); if (datasource != null && (c == null || c.isClosed())) { try { DataSource ds; @@ -177,7 +160,7 @@ public Connection getConnection(SQLConfig config) throws Exception { break; } - connectionMap.put(key, ds == null ? null : ds.getConnection()); + putConnection(key, ds == null ? null : ds.getConnection()); } catch (Exception e) { Log.e(TAG, "getConnection try { " + "DataSource ds = DemoApplication.getApplicationContext().getBean(DataSource.class); .." @@ -191,15 +174,16 @@ public Connection getConnection(SQLConfig config) throws Exception { } @Override - public JSONObject execute(@NotNull SQLConfig config, boolean unknownType) throws Exception { + public JSONObject execute(@NotNull SQLConfig config, boolean unknownType) throws Exception { boolean isMilvus = config.isMilvus(); // DATABASE_MILVUS.equals(config.getDatabase()); // APIJSON 6.4.0+ 可用 config.isMilvus(); - boolean isCassandra = config.isCassandra(); - boolean isInfluxDB = config.isInfluxDB(); - boolean isIoTDB = config.isIoTDB(); // DemoSQLConfig.DATABASE_IOTDB.equals(config.getDatabase()); + boolean isCassandra = config.isCassandra(); // DemoSQLConfig.DATABASE_CASSANDRA.equals(config.getDatabase()); + boolean isInfluxDB = config.isInfluxDB(); // DemoSQLConfig.DATABASE_INFLUXDB.equals(config.getDatabase()); + // boolean isIoTDB = config.isIoTDB(); // DemoSQLConfig.DATABASE_IOTDB.equals(config.getDatabase()); + // boolean isSurrealDB = config.isSurrealDB(); // DemoSQLConfig.DATABASE_SURREALDB.equals(config.getDatabase()); - if (isMilvus || isCassandra || isInfluxDB || isIoTDB) { + if (isMilvus || isCassandra || isInfluxDB) { // || isIoTDB || isSurrealDB) { // TODO 把 execute 内与缓存无关只与数据库读写逻辑相关的代码抽取到 executeSQL 函数 - String sql = config.getSQL(false); // config.isPrepared()); + String sql = config.gainSQL(false); // config.isPrepared()); if (sql != null && config.getMethod() == null) { String trimmedSQL = sql.trim(); String sqlPrefix = trimmedSQL.length() < 7 ? "" : trimmedSQL.substring(0, 7).toUpperCase(); @@ -256,6 +240,13 @@ else if (sqlPrefix.startsWith("DELETE ")) { // } // // resultList = IoTDBUtil.executeQuery(config, sql, unknownType); +// } +// else if (isSurrealDB) { +// if (isWrite) { +// return SurrealDBUtil.executeUpdate(config, sql); +// } +// +// resultList = SurrealDBUtil.executeQuery(config, sql, unknownType); // } // TODO 把 execute 内与缓存无关只与数据库读写逻辑相关的代码抽取到 executeSQL 函数 @@ -283,14 +274,14 @@ public void close() { // 不需要隐藏字段这个功能时,取消注释来提升性能 // @Override - // protected boolean isHideColumn(SQLConfig config, java.sql.ResultSet rs, ResultSetMetaData rsmd, int tablePosition, - // JSONObject table, int columnIndex, Map childMap) throws SQLException { + // protected boolean isHideColumn(SQLConfig config, java.sql.ResultSet rs, ResultSetMetaData rsmd, int tablePosition, + // JSONMap table, int columnIndex, Map childMap) throws SQLException { // return false; // } // 取消注释可将前端传参驼峰命名转为蛇形命名 aBCdEfg => upper ? A_B_CD_EFG : a_b_cd_efg // @Override - // protected String getKey(SQLConfig config, java.sql.ResultSet rs, ResultSetMetaData rsmd, int tablePosition, JSONObject table, int columnIndex, Map childMap) throws Exception { + // protected String getKey(SQLConfig config, java.sql.ResultSet rs, ResultSetMetaData rsmd, int tablePosition, JSONMap table, int columnIndex, Map childMap) throws Exception { // String key = super.getKey(config, rs, rsmd, tablePosition, table, columnIndex, childMap); // String tbl = StringUtil.firstCase(JSONResponse.formatUnderline(rsmd.getTableName(columnIndex), true), true); // if (DemoVerifier.SYSTEM_ACCESS_MAP.containsKey(tbl)) { @@ -300,9 +291,15 @@ public void close() { // } -// @Override -// protected Object getValue(SQLConfig config, ResultSet rs, ResultSetMetaData rsmd, int tablePosition, JSONObject table, int columnIndex, String lable, Map childMap) throws Exception { -// Object v = super.getValue(config, rs, rsmd, tablePosition, table, columnIndex, lable, childMap); -// return MongoUtil.getValue(v); -// } + @Override + protected Object getValue( + SQLConfig config, ResultSet rs, ResultSetMetaData rsmd, int row, JSONObject table, int columnIndex + , String label, Map childMap, Map keyMap) throws Exception { + Object v = super.getValue(config, rs, rsmd, row, table, columnIndex, label, childMap, keyMap); +// if (v instanceof JsonNode) { // DuckDB json 类型需要转换 +// JsonNode jn = (JsonNode) v; +// v = jn.isNull() ? null : parseJSON(jn.toString()); +// } + return v; // MongoUtil.getValue(v); + } } diff --git a/APIJSON-Java-Server/APIJSONBoot-MultiDataSource/src/main/java/apijson/demo/DemoVerifier.java b/APIJSON-Java-Server/APIJSONBoot-MultiDataSource/src/main/java/apijson/demo/DemoVerifier.java index afc3a7b4..60d3fbff 100644 --- a/APIJSON-Java-Server/APIJSONBoot-MultiDataSource/src/main/java/apijson/demo/DemoVerifier.java +++ b/APIJSON-Java-Server/APIJSONBoot-MultiDataSource/src/main/java/apijson/demo/DemoVerifier.java @@ -14,7 +14,7 @@ package apijson.demo; -import apijson.router.APIJSONRouterVerifier; +import apijson.fastjson2.APIJSONVerifier; import java.util.regex.Pattern; @@ -23,7 +23,7 @@ * 具体见 https://github.com/Tencent/APIJSON/issues/12 * @author Lemon */ -public class DemoVerifier extends APIJSONRouterVerifier { // APIJSONVerifier { +public class DemoVerifier extends APIJSONVerifier { public static final String TAG = "DemoVerifier"; static { @@ -39,7 +39,7 @@ public class DemoVerifier extends APIJSONRouterVerifier { // APIJSONVerif // 重写方法来自定义字段名等 // @Override - // public String getVisitorIdKey(SQLConfig config) { + // public String getVisitorIdKey(SQLConfig config) { // return super.getVisitorIdKey(config); // return "userid"; // return "uid" 等自定义的字段名 // } diff --git a/APIJSON-Java-Server/APIJSONBoot-MultiDataSource/src/main/resources/application.yml b/APIJSON-Java-Server/APIJSONBoot-MultiDataSource/src/main/resources/application.yml index bb4ece1c..b0aaa876 100644 --- a/APIJSON-Java-Server/APIJSONBoot-MultiDataSource/src/main/resources/application.yml +++ b/APIJSON-Java-Server/APIJSONBoot-MultiDataSource/src/main/resources/application.yml @@ -1,4 +1,8 @@ spring: + servlet: + multipart: + max-file-size: 10MB + max-request-size: 10MB # If using flyway-core dependency, either comment this out or use @FlywayDatasource in DemoDataSourceConfig # flyway: # url: ${spring.datasource.hikari.jdbc-url} diff --git a/APIJSON-Java-Server/APIJSONBoot-MultiDataSource/src/main/resources/static/api/README.md b/APIJSON-Java-Server/APIJSONBoot-MultiDataSource/src/main/resources/static/api/README.md index 530f2d66..1523203d 100755 --- a/APIJSON-Java-Server/APIJSONBoot-MultiDataSource/src/main/resources/static/api/README.md +++ b/APIJSON-Java-Server/APIJSONBoot-MultiDataSource/src/main/resources/static/api/README.md @@ -16,13 +16,14 @@ --- 敏捷开发最强大易用的 HTTP 接口工具,机器学习零代码测试、生成代码与静态检查、生成文档与光标悬浮注释。
-集 文档、测试、Mock、调试、管理 于一体的一站式体验,还有一键 格式化、注释/取消注释 等高效易用的快捷键。
+集合 文档、测试、Mock、调试、管理 的一站式体验,还有 **AI 问答** 和一键 格式化、注释/取消注释 等高效快捷键。
在常用功能上远超 Postman, Swagger, YApi 等各种 开源、商业 的 API 文档/测试 工具,并能一键导入用例和文档。
支持 GET, POST, PUT, PATCH, DELETE, HEAD 等各种 HTTP Method 及 Content-Type, URL /{Path}/{Variable}。
不仅适用于 RESTful、类 RESTful、GRPC 的 API,还是腾讯 [APIJSON](https://github.com/Tencent/APIJSON) 官方建议的文档与测试工具。
腾讯内部用户包括 IEG 互动娱乐事业群、TEG 技术工程事业群、CSIG 云与智慧事业群 的多个部门及团队,
外部用户包含 华为、工商银行某地分行、500 强上市公司传音、跨境电商巨头 SHEIN、行业领头羊社保科技 等。 +![image](https://github.com/user-attachments/assets/24460af3-0001-46e7-aa2a-df28b711a8cf) ![](https://user-images.githubusercontent.com/5738175/145665502-94231804-5ea8-4784-b30d-d5558aad0f8d.jpeg)

@@ -115,7 +116,9 @@ Bilibili:https://search.bilibili.com/all?keyword=APIAuto ### 相关推荐 -[别再生成测试代码了!](https://mp.weixin.qq.com/s/G1GVNhhFbSX5GoyRU6GURg) +[别再生成测试代码了!](https://mp.weixin.qq.com/s/G1GVNhhFbSX5GoyRU6GURg)
+[APIAuto: 最先进的HTTP接口工具](https://blog.csdn.net/Nifc666/article/details/141966487) + ### 百度、搜狗、抖音公网接口调用演示
因为这些接口不支持 CORS 跨域,所以需要开启托管服务代理。
@@ -252,6 +255,24 @@ https://github.com/TommyLemon/APIAuto/issues
+### Roadmap 路线图 +1.Translate document to English/Italian/Franch/Spanish...
+ +2.新增功能
+1) 断言结果 新增按钮 变-\{原因},点击后右侧展示 JSON diff view;
+2) 右下角列表展示具体每个断言有问题的字段,点击后 JSON view 只显示该字段对应值
+其他待补充...
+
+3.完善自动断言,支持更多格式的匹配
+
+4.解决 bug
+
+5.提升性能
+
+6.其他待补充...
+ +
+ ### 感谢开源 * jsonon * editor.md diff --git a/APIJSON-Java-Server/APIJSONBoot-MultiDataSource/src/main/resources/static/api/apijson/CodeUtil.js b/APIJSON-Java-Server/APIJSONBoot-MultiDataSource/src/main/resources/static/api/apijson/CodeUtil.js index 4a5a4ed3..3190babd 100644 --- a/APIJSON-Java-Server/APIJSONBoot-MultiDataSource/src/main/resources/static/api/apijson/CodeUtil.js +++ b/APIJSON-Java-Server/APIJSONBoot-MultiDataSource/src/main/resources/static/api/apijson/CodeUtil.js @@ -54,7 +54,7 @@ var CodeUtil = { DATABASE_KINGBASE: 'KINGBASE', DATABASE_TIDB: 'TIDB', DATABASE_TDENGINE: 'TDENGINE', - DATABASE_NEBULA: 'NEBULA', + DATABASE_SURREALDB: 'SURREALDB', DATABASE_PRESTO: 'PRESTO', DATABASE_TRINO: 'TRINO', DATABASE_INFLUXDB: 'INFLUXDB', @@ -64,6 +64,13 @@ var CodeUtil = { DATABASE_KAFKA: 'KAFKA', DATABASE_MARIADB: 'MARIADB', DATABASE_HIVE: 'HIVE', + DATABASE_SNOWFLAKE: 'SNOWFLAKE', + DATABASE_DATABRICKS: 'DATABRICKS', + DATABASE_MILVUS: 'MILVUS', + DATABASE_IOTDB: 'IOTDB', + DATABASE_DUCKDB: 'DUCKDB', + DATABASE_CASSANDRA: 'CASSANDRA', + DATABASE_MONGODB: 'MONGODB', type: 'JSON', database: 'MYSQL', @@ -259,7 +266,7 @@ var CodeUtil = { } else { try { - value = JSON.parse(value) + value = parseJSON(value) } catch (e) { console.log(e) @@ -1839,7 +1846,7 @@ var CodeUtil = { return CodeUtil.parseCode(name, resObj, { onParseParentStart: function () { - return depth > 0 || StringUtil.isEmpty(name_, true) == false ? '' : CodeUtil.getBlank(depth) + varKey + ' ' + name + ' = JSON.parse(resultJson) \n'; + return depth > 0 || StringUtil.isEmpty(name_, true) == false ? '' : CodeUtil.getBlank(depth) + varKey + ' ' + name + ' = parseJSON(resultJson) \n'; }, onParseParentEnd: function () { @@ -2688,7 +2695,7 @@ res_data = rep.json() else if (format instanceof Array == false && format instanceof Object) { s += prefix2 + varName + '_json = json.loads(' + varName + ')' try { - var realObj = JSON.parse(real); + var realObj = parseJSON(real); var cs = CodeUtil.parsePythonResponseByStandard(varName + '_json', key, format, realObj, depth, isSmart, true, funDefs, funNames); if (StringUtil.isNotEmpty(cs, true)) { s += '\n' + padding + cs.trim(); @@ -2752,7 +2759,7 @@ res_data = rep.json() return CodeUtil.parseCode(name, resObj, { onParseParentStart: function () { - return depth > 0 || StringUtil.isEmpty(name_, true) == false ? '' : CodeUtil.getBlank(depth) + varKey + ' ' + name + ': object = JSON.parse(resultJson); \n'; + return depth > 0 || StringUtil.isEmpty(name_, true) == false ? '' : CodeUtil.getBlank(depth) + varKey + ' ' + name + ': object = parseJSON(resultJson); \n'; }, onParseParentEnd: function () { @@ -6222,7 +6229,7 @@ res_data = rep.json() OWNER: '拥有者', ADMIN: '管理员' }, - DATABASE_KEYS: ['MYSQL', 'POSTGRESQL', 'SQLSERVER', 'ORACLE', 'DB2', 'DAMENG', 'KINGBASE', 'MARIADB', 'SQLITE', 'INFLUXDB', 'TDENGINE', 'PRESTO', 'TRINO', 'HIVE', 'TIDB', 'CLICKHOUSE', 'ELASTICSEARCH', 'REDIS'], // , 'KAFKA'], + DATABASE_KEYS: ['MYSQL', 'POSTGRESQL', 'SQLSERVER', 'ORACLE', 'DB2', 'DAMENG', 'KINGBASE', 'MARIADB', 'SQLITE', 'INFLUXDB', 'TDENGINE', 'PRESTO', 'TRINO', 'HIVE', 'TIDB', 'CLICKHOUSE', 'ELASTICSEARCH', 'REDIS', 'IOTDB', 'SURREALDB', 'DUCKDB', 'CASSANDRA', 'MONGODB', 'SNOWFLAKE', 'DATABRICKS', 'MILVUS'], // , 'KAFKA'], getComment4Function: function (funCallStr, method, language) { if (typeof funCallStr != 'string') { @@ -6776,7 +6783,7 @@ res_data = rep.json() var typeOfValue = CodeUtil.getType4Request(value); var isValueNotArray = typeOfValue != 'array'; var isValueNotObject = typeOfValue != 'object'; - + if (standardObj != null) { var parentObj = pathKeys == null || pathKeys.length <= 0 ? null : JSONResponse.getStandardByPath(standardObj, pathKeys.slice(0, pathKeys.length - 1)); var targetValues = parentObj == null ? null : parentObj.values; @@ -7287,7 +7294,7 @@ res_data = rep.json() }, getType4Request: function (value) { - // return t != 'string' ? t : typeof JSON.parse(value); + // return t != 'string' ? t : typeof parseJSON(value); if (value instanceof Array) { return 'array' } diff --git a/APIJSON-Java-Server/APIJSONBoot-MultiDataSource/src/main/resources/static/api/apijson/JSONRequest.js b/APIJSON-Java-Server/APIJSONBoot-MultiDataSource/src/main/resources/static/api/apijson/JSONRequest.js index 20b97bac..927403fe 100644 --- a/APIJSON-Java-Server/APIJSONBoot-MultiDataSource/src/main/resources/static/api/apijson/JSONRequest.js +++ b/APIJSON-Java-Server/APIJSONBoot-MultiDataSource/src/main/resources/static/api/apijson/JSONRequest.js @@ -215,7 +215,7 @@ function format(json) { } try { - return JSON.stringify(JSON.parse(json), null, "\t"); + return JSON.stringify(parseJSON(json), null, "\t"); } catch(e) { log(TAG_REQUEST_UTIL, 'format try { ... } catch (err) { \n ' + e); return json; @@ -234,9 +234,9 @@ function format(json) { // var jsonObj; // if (typeof json == 'string'){ // try { - // jsonObj = JSON.parse(json); + // jsonObj = parseJSON(json); // } catch (err) { - // console.log('format try { jsonObj = JSON.parse(json); } catch (err) { \n ' + err); + // console.log('format try { jsonObj = parseJSON(json); } catch (err) { \n ' + err); // return json; // } // } diff --git a/APIJSON-Java-Server/APIJSONBoot-MultiDataSource/src/main/resources/static/api/apijson/JSONResponse.js b/APIJSON-Java-Server/APIJSONBoot-MultiDataSource/src/main/resources/static/api/apijson/JSONResponse.js index 21a43215..065396f6 100644 --- a/APIJSON-Java-Server/APIJSONBoot-MultiDataSource/src/main/resources/static/api/apijson/JSONResponse.js +++ b/APIJSON-Java-Server/APIJSONBoot-MultiDataSource/src/main/resources/static/api/apijson/JSONResponse.js @@ -829,7 +829,7 @@ var JSONResponse = { } if (right instanceof Object) { - var m = JSON.parse(JSON.stringify(left)); + var m = parseJSON(JSON.stringify(left)); for (var k in right) { m[k] = JSONResponse.deepMerge(m[k], right[k]); } @@ -1036,7 +1036,7 @@ var JSONResponse = { } else if (format instanceof Array == false && format instanceof Object) { try { - var realObj = JSON.parse(real); + var realObj = parseJSON(real); var result = JSONResponse.compareWithStandard(format, realObj, folder, exceptKeys, ignoreTrend); if (guess == true) { result.code -= 1; @@ -1601,7 +1601,7 @@ var JSONResponse = { } catch (e) { log(e) try { - var realObj = JSON.parse(real); + var realObj = parseJSON(real); var format2 = JSONResponse.updateStandard(target.format, realObj, exceptKeys, ignoreTrend, key); if (format2 != null) { target.format = format2; diff --git a/APIJSON-Java-Server/APIJSONBoot-MultiDataSource/src/main/resources/static/api/index.html b/APIJSON-Java-Server/APIJSONBoot-MultiDataSource/src/main/resources/static/api/index.html index 17d4e567..ead8ad05 100755 --- a/APIJSON-Java-Server/APIJSONBoot-MultiDataSource/src/main/resources/static/api/index.html +++ b/APIJSON-Java-Server/APIJSONBoot-MultiDataSource/src/main/resources/static/api/index.html @@ -203,7 +203,7 @@
  • - +
    • - {{ isCaseGroupEditable ? '' : item.Chain.groupName }}{{' (' + (item.Chain.count - 1) + ') '}} + {{ isCaseGroupEditable ? '' : item.Chain.groupName }}{{' (' + (item.Chain.count - 1) + ') '}} @@ -256,7 +256,7 @@
      - +
      • @@ -743,14 +743,20 @@
        -
        - - - - - 每页 - - +
        + + + + + + 每页 + + + +
        + + +