99import static apijson .RequestMethod .GET ;
1010
1111import java .io .UnsupportedEncodingException ;
12+ import java .lang .management .ManagementFactory ;
13+ import java .net .InetAddress ;
1214import java .net .URLEncoder ;
1315import java .sql .Connection ;
1416import java .sql .SQLException ;
2628import java .util .concurrent .TimeoutException ;
2729
2830import javax .activation .UnsupportedDataTypeException ;
31+ import javax .management .MBeanServer ;
32+ import javax .management .ObjectName ;
33+ import javax .management .Query ;
2934
3035import com .alibaba .fastjson .JSONArray ;
3136import com .alibaba .fastjson .JSONObject ;
@@ -153,6 +158,15 @@ public AbstractParser<T> setTag(String tag) {
153158 return this ;
154159 }
155160
161+ protected String requestURL ;
162+ public String getRequestURL () {
163+ return requestURL ;
164+ }
165+ public AbstractParser <T > setRequestURL (String requestURL ) {
166+ this .requestURL = requestURL ;
167+ return this ;
168+ }
169+
156170 protected JSONObject requestObject ;
157171 @ Override
158172 public JSONObject getRequest () {
@@ -354,7 +368,7 @@ public JSONObject parseResponse(JSONObject request) {
354368 onVerifyContent ();
355369 }
356370 } catch (Exception e ) {
357- return extendErrorResult (requestObject , e );
371+ return extendErrorResult (requestObject , e , requestMethod , getRequestURL () );
358372 }
359373 }
360374
@@ -364,7 +378,7 @@ public JSONObject parseResponse(JSONObject request) {
364378 setGlobleRole (requestObject .getString (JSONRequest .KEY_ROLE ));
365379 requestObject .remove (JSONRequest .KEY_ROLE );
366380 } catch (Exception e ) {
367- return extendErrorResult (requestObject , e );
381+ return extendErrorResult (requestObject , e , requestMethod , getRequestURL () );
368382 }
369383 }
370384
@@ -383,7 +397,7 @@ public JSONObject parseResponse(JSONObject request) {
383397 requestObject .remove (JSONRequest .KEY_EXPLAIN );
384398 requestObject .remove (JSONRequest .KEY_CACHE );
385399 } catch (Exception e ) {
386- return extendErrorResult (requestObject , e );
400+ return extendErrorResult (requestObject , e , requestMethod , getRequestURL () );
387401 }
388402
389403 final String requestString = JSON .toJSONString (request );//request传进去解析后已经变了
@@ -407,7 +421,7 @@ public JSONObject parseResponse(JSONObject request) {
407421 onRollback ();
408422 }
409423
410- requestObject = error == null ? extendSuccessResult (requestObject ) : extendErrorResult (requestObject , error );
424+ requestObject = error == null ? extendSuccessResult (requestObject ) : extendErrorResult (requestObject , error , requestMethod , getRequestURL () );
411425
412426 JSONObject res = (globleFormat != null && globleFormat ) && JSONResponse .isSuccess (requestObject ) ? new JSONResponse (requestObject ) : requestObject ;
413427
@@ -608,8 +622,9 @@ public static JSONObject extendResult(JSONObject object, int code, String msg) {
608622 if (object == null ) {
609623 object = new JSONObject (true );
610624 }
625+ boolean isOk = JSONResponse .isSuccess (code );
611626 if (object .containsKey (JSONResponse .KEY_OK ) == false ) {
612- object .put (JSONResponse .KEY_OK , JSONResponse . isSuccess ( code ) );
627+ object .put (JSONResponse .KEY_OK , isOk );
613628 }
614629 if (object .containsKey (JSONResponse .KEY_CODE ) == false ) {
615630 object .put (JSONResponse .KEY_CODE , code );
@@ -619,6 +634,7 @@ public static JSONObject extendResult(JSONObject object, int code, String msg) {
619634 if (m .isEmpty () == false ) {
620635 msg = m + " ;\n " + StringUtil .getString (msg );
621636 }
637+
622638 object .put (JSONResponse .KEY_MSG , msg );
623639 return object ;
624640 }
@@ -642,36 +658,84 @@ public static JSONObject newSuccessResult() {
642658 * @return
643659 */
644660 public static JSONObject extendErrorResult (JSONObject object , Exception e ) {
661+ return extendErrorResult (object , e , null , null );
662+ }
663+ /**添加请求成功的状态内容
664+ * @param object
665+ * @return
666+ */
667+ public static JSONObject extendErrorResult (JSONObject object , Exception e , RequestMethod requestMethod , String url ) {
645668 String msg = e .getMessage ();
646-
669+
647670 if (Log .DEBUG ) {
648671 try {
649672 int index = msg .lastIndexOf (Log .KEY_SYSTEM_INFO_DIVIDER );
650673 String info = index >= 0 ? msg .substring (index + Log .KEY_SYSTEM_INFO_DIVIDER .length ()).trim ()
651674 : "\n **环境信息** "
652675 + "\n 系统: " + System .getProperty ("os.name" ) + " " + System .getProperty ("os.version" )
653- + "\n JDK: " + System .getProperty ("java.version" ) + " " + System .getProperty ("os.arch" )
654676 + "\n 数据库: <!-- 请填写,例如 MySQL 5.7 -->"
677+ + "\n JDK: " + System .getProperty ("java.version" ) + " " + System .getProperty ("os.arch" )
655678 + "\n APIJSON: " + Log .VERSION ;
656679
657680 msg = index < 0 ? msg : msg .substring (0 , index ).trim ();
658681 String encodedMsg = URLEncoder .encode (msg , "UTF-8" );
682+
683+ if (StringUtil .isEmpty (url , true )) {
684+ String host = "localhost" ;
685+ try {
686+ host = InetAddress .getLocalHost ().getHostAddress ();
687+ } catch (Throwable e2 ) {}
688+
689+ String port = "8080" ;
690+ try {
691+ MBeanServer beanServer = ManagementFactory .getPlatformMBeanServer ();
692+
693+ Set <ObjectName > objectNames = beanServer .queryNames (
694+ new ObjectName ("*:type=Connector,*" ),
695+ Query .match (Query .attr ("protocol" ), Query .value ("HTTP/1.1" ))
696+ );
697+ String p = objectNames .iterator ().next ().getKeyProperty ("port" );
698+ port = StringUtil .isEmpty (p , true ) ? port : p ;
699+ } catch (Throwable e2 ) {}
700+
701+ url = "http://" + host + ":" + port + "/" + (requestMethod == null ? RequestMethod .GET : requestMethod ).name ().toLowerCase ();
702+ }
703+
704+ String req = JSON .toJSONString (object );
705+ try {
706+ req = URLEncoder .encode (req , "UTF-8" );
707+ } catch (Throwable e2 ) {}
708+
709+
710+ boolean isSQLException = e instanceof SQLException ; // SQL 报错一般都是通用问题,优先搜索引擎
711+ String apiatuoAndGitHubLink = "\n 【APIAuto】: \n http://apijson.cn/api?type=JSON&url=" + URLEncoder .encode (url , "UTF-8" ) + "&json=" + req
712+ + " \n \n 【GitHub】: \n https://www.google.com/search?q=site%3Agithub.com%2FTencent%2FAPIJSON+++" + encodedMsg ;
659713
660- msg += " \n \n \n 浏览器打开以下链接搜索答案\n GitHub: https://github.com/Tencent/APIJSON/issues?q=is%3Aissue+" + encodedMsg
661- + " \n \n Google:https://www.google.com/search?q=" + encodedMsg
662- + " \n \n Baidu:https://www.baidu.com/s?ie=UTF-8&wd=" + encodedMsg
663- + " \n \n 都没找到答案?打开这个链接 https://github.com/Tencent/APIJSON/issues/new?assignees=&labels=&template=--bug.md "
714+ msg += " \n \n \n 浏览器打开以下链接查看解答"
715+ + (isSQLException ? "" : apiatuoAndGitHubLink )
716+ // GitHub Issue 搜索貌似是精准包含,不易找到答案 + " \n\nGitHub: \n https://github.com/Tencent/APIJSON/issues?q=is%3Aissue+" + encodedMsg
717+ + " \n \n 【Google】:\n https://www.google.com/search?q=" + encodedMsg
718+ + " \n \n 【百度】:\n https://www.baidu.com/s?ie=UTF-8&wd=" + encodedMsg
719+ + (isSQLException ? apiatuoAndGitHubLink : "" )
720+ + " \n \n 都没找到答案?打开这个链接 \n https://github.com/Tencent/APIJSON/issues/new?assignees=&labels=&template=--bug.md "
664721 + "\n 然后提交问题,推荐用以下模板修改,注意要换行保持清晰可读。"
665722 + "\n 【标题】:" + msg
666- + "\n 【内容】:" + info + "\n \n **问题描述**\n " + msg ;
667- } catch (Throwable e2 ) {
668- e2 .printStackTrace ();
669- }
723+ + "\n 【内容】:" + info + "\n \n **问题描述**\n " + msg
724+ + "\n \n <!-- 尽量完整截屏(至少包含请求和回包结果,还可以加上控制台报错日志),然后复制粘贴到这里 -->"
725+ + "\n \n POST " + url
726+ + "\n 请求 Request JSON:\n ```js"
727+ + "\n 请填写,例如 { \" Users\" :{} }"
728+ + "\n ```"
729+ + "\n \n 返回结果 Response JSON:\n ```js"
730+ + "\n 请填写,例如 { \" Users\" : {}, \" code\" : 401, \" msg\" : \" Users 不允许 UNKNOWN 用户的 GET 请求!\" }"
731+ + "\n ```" ;
732+ } catch (Throwable e2 ) {}
670733 }
671-
734+
672735 JSONObject error = newErrorResult (e );
673736 return extendResult (object , error .getIntValue (JSONResponse .KEY_CODE ), msg );
674737 }
738+
675739 /**新建错误状态内容
676740 * @param e
677741 * @return
@@ -1000,7 +1064,7 @@ public JSONArray onArrayParse(JSONObject request, String parentPath, String name
10001064 //不能改变,因为后面可能继续用到,导致1以上都改变 []:{0:{Comment[]:{0:{Comment:{}},1:{...},...}},1:{...},...}
10011065 final String query = request .getString (JSONRequest .KEY_QUERY );
10021066 final Integer count = request .getInteger (JSONRequest .KEY_COUNT ); //TODO 如果不想用默认数量可以改成 getIntValue(JSONRequest.KEY_COUNT);
1003- final int page = request .getIntValue (JSONRequest .KEY_PAGE );
1067+ final Integer page = request .getInteger (JSONRequest .KEY_PAGE );
10041068 final Object join = request .get (JSONRequest .KEY_JOIN );
10051069
10061070 int query2 ;
@@ -1026,8 +1090,9 @@ public JSONArray onArrayParse(JSONObject request, String parentPath, String name
10261090 }
10271091 }
10281092
1093+ int page2 = page == null ? 0 : page ;
10291094 int maxPage = getMaxQueryPage ();
1030- if (page < 0 || page > maxPage ) {
1095+ if (page2 < 0 || page2 > maxPage ) {
10311096 throw new IllegalArgumentException (path + "/" + JSONRequest .KEY_PAGE + ":value 中 value 的值不合法!必须在 0-" + maxPage + " 内 !" );
10321097 }
10331098
@@ -1052,8 +1117,8 @@ public JSONArray onArrayParse(JSONObject request, String parentPath, String name
10521117
10531118 JSONArray response = null ;
10541119 try {
1055- int size = count2 == 0 ? max : count2 ;//count为每页数量,size为第page页实际数量,max(size) = count
1056- Log .d (TAG , "onArrayParse size = " + size + "; page = " + page );
1120+ int size = count2 == 0 ? max : count2 ; //count为每页数量,size为第page页实际数量,max(size) = count
1121+ Log .d (TAG , "onArrayParse size = " + size + "; page = " + page2 );
10571122
10581123
10591124 //key[]:{Table:{}}中key equals Table时 提取Table
@@ -1076,13 +1141,13 @@ else if (childKeys.length == 1 && JSONRequest.isTableKey(childKeys[0])) { //
10761141 SQLConfig config = createSQLConfig ()
10771142 .setMethod (requestMethod )
10781143 .setCount (size )
1079- .setPage (page )
1144+ .setPage (page2 )
10801145 .setQuery (query2 )
10811146 .setTable (arrTableKey )
10821147 .setJoinList (onJoinParse (join , request ));
10831148
10841149 JSONObject parent ;
1085-
1150+
10861151 boolean isExtract = true ;
10871152
10881153 //生成size个
@@ -1091,7 +1156,7 @@ else if (childKeys.length == 1 && JSONRequest.isTableKey(childKeys[0])) { //
10911156 if (parent == null || parent .isEmpty ()) {
10921157 break ;
10931158 }
1094-
1159+
10951160 long startTime = System .currentTimeMillis ();
10961161
10971162 /* 这里优化了 Table[]: { Table:{} } 这种情况下的性能
@@ -1101,13 +1166,13 @@ else if (childKeys.length == 1 && JSONRequest.isTableKey(childKeys[0])) { //
11011166 JSONObject fo = i != 0 || arrTableKey == null ? null : parent .getJSONObject (arrTableKey );
11021167 @ SuppressWarnings ("unchecked" )
11031168 List <JSONObject > list = fo == null ? null : (List <JSONObject >) fo .remove (SQLExecutor .KEY_RAW_LIST );
1104-
1169+
11051170 if (list != null && list .isEmpty () == false ) {
11061171 isExtract = false ;
1107-
1172+
11081173 list .set (0 , fo ); // 不知道为啥第 0 项也加了 @RAW@LIST
11091174 response .addAll (list ); // List<JSONObject> cannot match List<Object> response = new JSONArray(list);
1110-
1175+
11111176 long endTime = System .currentTimeMillis (); // 0ms
11121177 Log .d (TAG , "\n onArrayParse <<<<<<<<<<<<<<<<<<<<<<<<<<<<\n for (int i = 0; i < (isSubquery ? 1 : size); i++) "
11131178 + " startTime = " + startTime + "; endTime = " + endTime + "; duration = " + (endTime - startTime ) + "\n >>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n " );
@@ -1117,7 +1182,7 @@ else if (childKeys.length == 1 && JSONRequest.isTableKey(childKeys[0])) { //
11171182 //key[]:{Table:{}}中key equals Table时 提取Table
11181183 response .add (getValue (parent , childKeys )); //null有意义
11191184 }
1120-
1185+
11211186 //Table>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
11221187
11231188
@@ -1143,7 +1208,7 @@ else if (childKeys.length == 1 && JSONRequest.isTableKey(childKeys[0])) { //
11431208 if (fo instanceof Boolean || fo instanceof Number || fo instanceof String ) { //[{}] 和 [[]] 都没意义
11441209 putQueryResult (path , response );
11451210 }
1146-
1211+
11471212 long endTime = System .currentTimeMillis ();
11481213 Log .d (TAG , "\n onArrayParse <<<<<<<<<<<<<<<<<<<<<<<<<<<<\n isExtract >> putQueryResult "
11491214 + " startTime = " + startTime + "; endTime = " + endTime + "; duration = " + (endTime - startTime ) + "\n >>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n " );
@@ -1739,13 +1804,13 @@ else if (config.isClickHouse()) {
17391804 e .getMessage ()
17401805 + " " + Log .KEY_SYSTEM_INFO_DIVIDER + " \n **环境信息** "
17411806 + "\n 系统: " + System .getProperty ("os.name" ) + " " + System .getProperty ("os.version" )
1742- + "\n JDK: " + System .getProperty ("java.version" ) + " " + System .getProperty ("os.arch" )
17431807 + "\n 数据库: " + db + " " + config .getDBVersion ()
1808+ + "\n JDK: " + System .getProperty ("java.version" ) + " " + System .getProperty ("os.arch" )
17441809 + "\n APIJSON: " + Log .VERSION
17451810 );
17461811 } catch (Throwable e2 ) {}
17471812 }
1748-
1813+
17491814 if (Log .DEBUG == false && e instanceof SQLException ) {
17501815 throw new SQLException ("数据库驱动执行异常SQLException,非 Log.DEBUG 模式下不显示详情,避免泄漏真实模式名、表名等隐私信息" , e );
17511816 }
0 commit comments