Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

添加异常信息控制静态变量,改造两层错误码问题,文档修正 #212

Merged
merged 4 commits into from
Apr 6, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion APIJSONORM/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

<groupId>apijson.orm</groupId>
<artifactId>apijson-orm</artifactId>
<version>4.6.6</version>
<version>4.6.7</version>
<packaging>jar</packaging>

<name>APIJSONORM</name>
Expand Down
8 changes: 6 additions & 2 deletions APIJSONORM/src/main/java/apijson/orm/AbstractParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,9 @@ public JSONObject parseResponse(String request) {

private int queryDepth;

// 打印异常日志的标识。线上环境比较敏感,可以通过切换该变量来控制异常栈抛出、错误日志打印。保守起见,该值默认为false。
public static boolean isPrintErrorLog = false;

/**解析请求json并获取对应结果
* @param request
* @return requestObject
Expand Down Expand Up @@ -383,11 +386,12 @@ public JSONObject parseResponse(JSONObject request) {
long endTime = System.currentTimeMillis();
long duration = endTime - startTime;

if (Log.DEBUG) { //用 | 替代 /,避免 APIJSON ORM,APIAuto 等解析路径错误
if (isPrintErrorLog) { //用 | 替代 /,避免 APIJSON ORM,APIAuto 等解析路径错误
requestObject.put("sql:generate|cache|execute|maxExecute", getSQLExecutor().getGeneratedSQLCount() + "|" + getSQLExecutor().getCachedSQLCount() + "|" + getSQLExecutor().getExecutedSQLCount() + "|" + getMaxSQLCount());
requestObject.put("depth:count|max", queryDepth + "|" + getMaxQueryDepth());
requestObject.put("time:start|duration|end", startTime + "|" + duration + "|" + endTime);
if (error != null) {
Log.d(TAG, String.format("onObjectParse error, error is %s", error.getMessage()));
requestObject.put("throw", error.getClass().getName());
requestObject.put("trace", error.getStackTrace());
}
Expand All @@ -397,7 +401,7 @@ public JSONObject parseResponse(JSONObject request) {

//会不会导致原来的session = null? session = null;

if (Log.DEBUG) {
if (isPrintErrorLog) {
Log.d(TAG, "\n\n\n\n<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n "
+ requestMethod + "/parseResponse request = \n" + requestString + "\n\n");

Expand Down
16 changes: 10 additions & 6 deletions APIJSONORM/src/main/java/apijson/orm/AbstractSQLExecutor.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import java.util.Map.Entry;
import java.util.Set;

import apijson.orm.exception.NotExistException;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

Expand Down Expand Up @@ -209,9 +210,12 @@ public JSONObject execute(@NotNull SQLConfig config, boolean unknowType) throws
executedSQLCount ++;

int updateCount = executeUpdate(config);
if (updateCount <= 0) {
throw new NotExistException("没权限访问或对象不存在!");
}

result = AbstractParser.newResult(updateCount > 0 ? JSONResponse.CODE_SUCCESS : JSONResponse.CODE_NOT_FOUND
, updateCount > 0 ? JSONResponse.MSG_SUCCEED : "没权限访问或对象不存在!");
// updateCount>0时收集结果。例如更新操作成功时,返回count(affected rows)、id字段
result = new JSONObject(true);

//id,id{}至少一个会有,一定会返回,不用抛异常来阻止关联写操作时前面错误导致后面无条件执行!
result.put(JSONResponse.KEY_COUNT, updateCount);//返回修改的记录数
Expand Down Expand Up @@ -717,8 +721,8 @@ public Connection getConnection(@NotNull SQLConfig config) throws Exception {
connection = connectionMap.get(config.getDatabase());
if (connection == null || connection.isClosed()) {
Log.i(TAG, "select connection " + (connection == null ? " = null" : ("isClosed = " + connection.isClosed()))) ;
// PostgreSQL 不允许 cross-database
connection = DriverManager.getConnection(config.getDBUri(), config.getDBAccount(), config.getDBPassword());
// PostgreSQL 不允许 cross-database
connection = DriverManager.getConnection(config.getDBUri(), config.getDBAccount(), config.getDBPassword());
connectionMap.put(config.getDatabase(), connection);
}

Expand Down Expand Up @@ -823,14 +827,14 @@ public ResultSet executeQuery(@NotNull SQLConfig config) throws Exception {
public int executeUpdate(@NotNull SQLConfig config) throws Exception {
PreparedStatement s = getStatement(config);
int count = s.executeUpdate(); //PreparedStatement 不用传 SQL

if (config.getMethod() == RequestMethod.POST && config.getId() == null) { //自增id
ResultSet rs = s.getGeneratedKeys();
if (rs != null && rs.next()) {
config.setId(rs.getLong(1));//返回插入的主键id
}
}

return count;
}

Expand Down
4 changes: 2 additions & 2 deletions Document.md
Original file line number Diff line number Diff line change
Expand Up @@ -318,7 +318,7 @@
3.请求中的 / 需要转义。JSONRequest.java已经用URLEncoder.encode转义,不需要再写;但如果是浏览器或Postman等直接输入url/request,需要把request中的所有 / 都改成 %252F 。下同。<br >
4.code,指返回结果中的状态码,200表示成功,其它都是错误码,值全部都是HTTP标准状态码。下同。<br >
5.msg,指返回结果中的状态信息,对成功结果或错误原因的详细说明。下同。<br >
6.code和msg总是在返回结果的同一层级成对出现。对所有请求的返回结果都会在最外层有一对总结式code和msg。对非GET类型的请求,返回结果里面的每个JSONObject里都会有一对code和msg说明这个JSONObject的状态。下同。<br >
6.code和msg总是在返回结果的同一层级成对出现。对所有请求的返回结果都会在最外层有一对总结式code和msg。下同。<br >
7.id等字段对应的值仅供说明,不一定是数据库里存在的,请求里用的是真实存在的值。下同。

<br />
Expand All @@ -334,7 +334,7 @@ GET: <br > 普通获取数据,<br > 可用浏览器调试 | base_url/get/ | {<
HEAD: <br > 普通获取数量,<br > 可用浏览器调试 | base_url/head/ | {<br > &nbsp;&nbsp; TableName:{<br > &nbsp;&nbsp;&nbsp;&nbsp; …<br > &nbsp;&nbsp; }<br > } <br > {…}内为限制条件 <br ><br > 例如获取一个 id = 38710 的 User 所发布的 Moment 总数:<br >{<br > &nbsp;&nbsp; "Moment":{<br > &nbsp;&nbsp;&nbsp;&nbsp; "userId":38710<br > &nbsp;&nbsp; }<br >} <br > 后端校验通过后自动解析为 SQL 并执行:<br >`SELECT count(*) FROM Moment WHERE userId=38710 LIMIT 1` | {<br > &nbsp;&nbsp; TableName:{<br > &nbsp;&nbsp;&nbsp;&nbsp; "code":200,<br > &nbsp;&nbsp;&nbsp;&nbsp; "msg":"success",<br > &nbsp;&nbsp;&nbsp;&nbsp; "count":10<br > &nbsp;&nbsp; },<br > &nbsp;&nbsp; "code":200,<br > &nbsp;&nbsp; "msg":"success"<br >} <br > 例如<br >{<br > &nbsp;&nbsp; "Moment":{<br > &nbsp;&nbsp;&nbsp;&nbsp; "code":200,<br > &nbsp;&nbsp;&nbsp;&nbsp; "msg":"success",<br > &nbsp;&nbsp;&nbsp;&nbsp; "count":10<br > &nbsp;&nbsp; },<br > &nbsp;&nbsp; "code":200,<br > &nbsp;&nbsp; "msg":"success"<br >}
GETS: <br > 安全/私密获取数据,<br > 用于获取钱包等<br >对安全性要求高的数据 | base_url/gets/ | 最外层加一个 "tag":tag,其它同GET | 同GET
HEADS: <br > 安全/私密获取数量,<br > 用于获取银行卡数量等<br >对安全性要求高的数据总数 | base_url/heads/ | 最外层加一个 "tag":tag,其它同HEAD | 同HEAD
POST: <br > 新增数据 | base_url/post/ | 单个: <br > {<br > &nbsp;&nbsp; TableName:{<br > &nbsp;&nbsp;&nbsp;&nbsp; …<br > &nbsp;&nbsp; },<br > &nbsp;&nbsp; "tag":tag<br >} <br > {…}中id由后端生成,不能传 <br ><br >例如当前登录用户 38710 发布一个新 Comment:<br >{<br > &nbsp;&nbsp; "Comment":{<br > &nbsp;&nbsp;&nbsp;&nbsp; "momentId":12,<br > &nbsp;&nbsp;&nbsp;&nbsp; "content":"APIJSON,let interfaces and documents go to hell !", <br > &nbsp;&nbsp; },<br > &nbsp;&nbsp; "tag":"Comment"<br >} <br > 后端校验通过后自动解析为 SQL 并执行:<br >`INSERT INTO Comment(userId,momentId,content) VALUES(38710,12,'APIJSON,let interfaces and documents go to hell !')` <br > <br > 批量: <br > {<br > &nbsp;&nbsp; TableName\[]:\[{<br > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; …<br > &nbsp;&nbsp;&nbsp;&nbsp; }, {<br > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; …<br > &nbsp;&nbsp;&nbsp;&nbsp; }<br > &nbsp;&nbsp;&nbsp;&nbsp; …<br > &nbsp;&nbsp; ],<br > &nbsp;&nbsp; "tag":tag<br >} <br > {…}中id由后端生成,不能传 <br ><br >例如当前登录用户 82001 发布 2 个 Comment:<br >{<br > &nbsp;&nbsp; "Comment\[]":\[{<br > &nbsp;&nbsp;&nbsp;&nbsp; "momentId":12,<br > &nbsp;&nbsp;&nbsp;&nbsp; "content":"APIJSON,let interfaces and documents go to hell !"<br > &nbsp;&nbsp;&nbsp;&nbsp; }, {<br > &nbsp;&nbsp;&nbsp;&nbsp; "momentId":15,<br > &nbsp;&nbsp;&nbsp;&nbsp; "content":"APIJSON is a JSON transmision protocol."<br > &nbsp;&nbsp; }],<br > &nbsp;&nbsp; "tag":"Comment:[]"<br >}<br > 后端校验通过后自动解析为 SQL 并执行:<br >`INSERT INTO Comment(userId,momentId,content) VALUES(82001,12,'APIJSON,let interfaces and documents go to hell !')`<br >`INSERT INTO Comment(userId,momentId,content) VALUES(82001,15,'APIJSON is a JSON transmision protocol.')` | 单个: <br > {<br > &nbsp;&nbsp; TableName:{<br > &nbsp;&nbsp;&nbsp;&nbsp; "code":200,<br > &nbsp;&nbsp;&nbsp;&nbsp; "msg":"success",<br > &nbsp;&nbsp;&nbsp;&nbsp; "id":38710<br > &nbsp;&nbsp; },<br > &nbsp;&nbsp; "code":200,<br > &nbsp;&nbsp; "msg":"success"<br >}<br >例如<br >{<br > &nbsp;&nbsp; "Comment":{<br > &nbsp;&nbsp;&nbsp;&nbsp; "code":200,<br > &nbsp;&nbsp;&nbsp;&nbsp; "msg":"success",<br > &nbsp;&nbsp;&nbsp;&nbsp; "id":120<br > &nbsp;&nbsp; },<br > &nbsp;&nbsp; "code":200,<br > &nbsp;&nbsp; "msg":"success"<br >} <br > <br > 批量: <br > {<br > &nbsp;&nbsp; TableName:{<br > &nbsp;&nbsp;&nbsp;&nbsp; "code":200,<br > &nbsp;&nbsp;&nbsp;&nbsp; "msg":"success",<br > &nbsp;&nbsp;&nbsp;&nbsp; "count":5,<br > &nbsp;&nbsp;&nbsp;&nbsp; "id[]":[1, 2, 3, 4, 5]<br > &nbsp;&nbsp; },<br > &nbsp;&nbsp; "code":200,<br > &nbsp;&nbsp; "msg":"success"<br >}<br >例如<br >{<br > &nbsp;&nbsp; "Comment":{<br > &nbsp;&nbsp;&nbsp;&nbsp; "code":200,<br > &nbsp;&nbsp;&nbsp;&nbsp; "msg":"success",<br > &nbsp;&nbsp;&nbsp;&nbsp; "count":2,<br > &nbsp;&nbsp;&nbsp;&nbsp; "id[]":\[1, 2]<br > &nbsp;&nbsp; },<br > &nbsp;&nbsp; "code":200,<br > &nbsp;&nbsp; "msg":"success"<br >}
POST: <br > 新增数据 | base_url/post/ | 单个: <br > {<br > &nbsp;&nbsp; TableName:{<br > &nbsp;&nbsp;&nbsp;&nbsp; …<br > &nbsp;&nbsp; },<br > &nbsp;&nbsp; "tag":tag<br >} <br > {…}中id由后端生成,不能传 <br ><br >例如当前登录用户 38710 发布一个新 Comment:<br >{<br > &nbsp;&nbsp; "Comment":{<br > &nbsp;&nbsp;&nbsp;&nbsp; "momentId":12,<br > &nbsp;&nbsp;&nbsp;&nbsp; "content":"APIJSON,let interfaces and documents go to hell !" <br > &nbsp;&nbsp; },<br > &nbsp;&nbsp; "tag":"Comment"<br >} <br > 后端校验通过后自动解析为 SQL 并执行:<br >`INSERT INTO Comment(userId,momentId,content) VALUES(38710,12,'APIJSON,let interfaces and documents go to hell !')` <br > <br > 批量: <br > {<br > &nbsp;&nbsp; TableName\[]:\[{<br > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; …<br > &nbsp;&nbsp;&nbsp;&nbsp; }, {<br > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; …<br > &nbsp;&nbsp;&nbsp;&nbsp; }<br > &nbsp;&nbsp;&nbsp;&nbsp; …<br > &nbsp;&nbsp; ],<br > &nbsp;&nbsp; "tag":tag<br >} <br > {…}中id由后端生成,不能传 <br ><br >例如当前登录用户 82001 发布 2 个 Comment:<br >{<br > &nbsp;&nbsp; "Comment\[]":\[{<br > &nbsp;&nbsp;&nbsp;&nbsp; "momentId":12,<br > &nbsp;&nbsp;&nbsp;&nbsp; "content":"APIJSON,let interfaces and documents go to hell !"<br > &nbsp;&nbsp;&nbsp;&nbsp; }, {<br > &nbsp;&nbsp;&nbsp;&nbsp; "momentId":15,<br > &nbsp;&nbsp;&nbsp;&nbsp; "content":"APIJSON is a JSON transmision protocol."<br > &nbsp;&nbsp; }],<br > &nbsp;&nbsp; "tag":"Comment:[]"<br >}<br > 后端校验通过后自动解析为 SQL 并执行:<br >`INSERT INTO Comment(userId,momentId,content) VALUES(82001,12,'APIJSON,let interfaces and documents go to hell !')`<br >`INSERT INTO Comment(userId,momentId,content) VALUES(82001,15,'APIJSON is a JSON transmision protocol.')` | 单个: <br > {<br > &nbsp;&nbsp; TableName:{<br > &nbsp;&nbsp;&nbsp;&nbsp; "code":200,<br > &nbsp;&nbsp;&nbsp;&nbsp; "msg":"success",<br > &nbsp;&nbsp;&nbsp;&nbsp; "id":38710<br > &nbsp;&nbsp; },<br > &nbsp;&nbsp; "code":200,<br > &nbsp;&nbsp; "msg":"success"<br >}<br >例如<br >{<br > &nbsp;&nbsp; "Comment":{<br > &nbsp;&nbsp;&nbsp;&nbsp; "code":200,<br > &nbsp;&nbsp;&nbsp;&nbsp; "msg":"success",<br > &nbsp;&nbsp;&nbsp;&nbsp; "id":120<br > &nbsp;&nbsp; },<br > &nbsp;&nbsp; "code":200,<br > &nbsp;&nbsp; "msg":"success"<br >} <br > <br > 批量: <br > {<br > &nbsp;&nbsp; TableName:{<br > &nbsp;&nbsp;&nbsp;&nbsp; "code":200,<br > &nbsp;&nbsp;&nbsp;&nbsp; "msg":"success",<br > &nbsp;&nbsp;&nbsp;&nbsp; "count":5,<br > &nbsp;&nbsp;&nbsp;&nbsp; "id[]":[1, 2, 3, 4, 5]<br > &nbsp;&nbsp; },<br > &nbsp;&nbsp; "code":200,<br > &nbsp;&nbsp; "msg":"success"<br >}<br >例如<br >{<br > &nbsp;&nbsp; "Comment":{<br > &nbsp;&nbsp;&nbsp;&nbsp; "code":200,<br > &nbsp;&nbsp;&nbsp;&nbsp; "msg":"success",<br > &nbsp;&nbsp;&nbsp;&nbsp; "count":2,<br > &nbsp;&nbsp;&nbsp;&nbsp; "id[]":\[1, 2]<br > &nbsp;&nbsp; },<br > &nbsp;&nbsp; "code":200,<br > &nbsp;&nbsp; "msg":"success"<br >}
PUT: <br > 修改数据,<br > 只修改所传的字段 | base_url/put/ | {<br > &nbsp;&nbsp; TableName:{<br > &nbsp;&nbsp;&nbsp;&nbsp; "id":id,<br > &nbsp;&nbsp;&nbsp;&nbsp; …<br > &nbsp;&nbsp; },<br > &nbsp;&nbsp; "tag":tag<br >} <br > {…} 中 id 或 id{} 至少传一个 <br ><br >例如当前登录用户 82001 修改 id = 235 的 Moment 的 content:<br >{<br > &nbsp;&nbsp; "Moment":{<br > &nbsp;&nbsp;&nbsp;&nbsp; "id":235,<br > &nbsp;&nbsp;&nbsp;&nbsp; "content":"APIJSON,let interfaces and documents go to hell !"<br > &nbsp;&nbsp; },<br > &nbsp;&nbsp; "tag":"Moment"<br >} <br > 后端校验通过后自动解析为 SQL 并执行:<br >`UPDATE Moment SET content='APIJSON,let interfaces and documents go to hell !' WHERE id=235 AND userId=82001 LIMIT 1` <br ><br > 批量除了 id{}:\[] 也可类似批量 POST,只是每个 {...} 里面都必须有 id。<br >"tag":"Comment[]" 对应对象 "Comment":{"id{}":[1,2,3]},表示指定记录全部统一设置;<br >"tag":"Comment:[]" 多了冒号,对应数组 "Comment[]":[{"id":1},{"id":2},{"id":3}],表示每项单独设置 | 同POST
DELETE: <br > 删除数据 | base_url/delete/ | {<br > &nbsp;&nbsp; TableName:{<br > &nbsp;&nbsp;&nbsp;&nbsp; "id":id<br > &nbsp;&nbsp; },<br > &nbsp;&nbsp; "tag":tag<br >} <br > {…} 中 id 或 id{} 至少传一个,一般只传 id 或 id{} <br ><br >例如当前登录用户 82001 批量删除 id = 100,110,120 的 Comment:<br >{<br > &nbsp;&nbsp; "Comment":{<br > &nbsp;&nbsp;&nbsp;&nbsp; "id{}":[100,110,120]<br > &nbsp;&nbsp; },<br > &nbsp;&nbsp; "tag":"Comment[]"<br >} <br > 后端校验通过后自动解析为 SQL 并执行:<br >`DELETE FROM Comment WHERE id IN(100,110,120) AND userId=82001 LIMIT 3` | {<br > &nbsp;&nbsp; TableName:{<br > &nbsp;&nbsp;&nbsp;&nbsp; "code":200,<br > &nbsp;&nbsp;&nbsp;&nbsp; "msg":"success",<br > &nbsp;&nbsp;&nbsp;&nbsp; "id[]":[100,110,120]<br >&nbsp;&nbsp; &nbsp;&nbsp; "count":3<br > &nbsp;&nbsp; },<br > &nbsp;&nbsp; "code":200,<br > &nbsp;&nbsp; "msg":"success"<br >}<br >例如<br >{<br >&nbsp;&nbsp; "Comment":{<br >&nbsp;&nbsp; &nbsp;&nbsp; "code":200,<br >&nbsp;&nbsp; &nbsp;&nbsp; "msg":"success",<br >&nbsp;&nbsp; &nbsp;&nbsp; "id[]":[100,110,120],<br >&nbsp;&nbsp; &nbsp;&nbsp; "count":3<br >&nbsp;&nbsp; },<br >&nbsp;&nbsp; "code":200,<br >&nbsp;&nbsp; "msg":"success"<br >}

Expand Down