2121import static zuo .biao .apijson .RequestMethod .PUT ;
2222import static zuo .biao .apijson .server .SQLConfig .TYPE_ITEM ;
2323
24+ import java .rmi .ServerException ;
2425import java .util .ArrayList ;
2526import java .util .Arrays ;
2627import java .util .HashMap ;
3637import com .alibaba .fastjson .JSONArray ;
3738import com .alibaba .fastjson .JSONObject ;
3839
40+ import zuo .biao .apijson .JSONResponse ;
3941import zuo .biao .apijson .Log ;
4042import zuo .biao .apijson .NotNull ;
4143import zuo .biao .apijson .RequestMethod ;
@@ -52,8 +54,8 @@ public abstract class AbstractObjectParser implements ObjectParser {
5254 private static final String TAG = "AbstractObjectParser" ;
5355
5456 @ NotNull
55- protected Parser <?> parser ;
56- public AbstractObjectParser setParser (Parser <?> parser ) {
57+ protected AbstractParser <?> parser ;
58+ public AbstractObjectParser setParser (AbstractParser <?> parser ) {
5759 this .parser = parser ;
5860 return this ;
5961 }
@@ -233,43 +235,53 @@ public AbstractObjectParser parse() throws Exception {
233235 key = entry .getKey ();
234236
235237 try {
236- if (value instanceof JSONObject && key .startsWith ("@" ) == false && key .endsWith ("@" ) == false ) {//JSONObject,往下一级提取
238+ if (value instanceof JSONObject && key .startsWith ("@" ) == false && key .endsWith ("@" ) == false ) { //JSONObject,往下一级提取
237239 if (childMap != null ) {//添加到childMap,最后再解析
238240 childMap .put (key , (JSONObject )value );
239241 }
240- else {//直接解析并替换原来的,[]:{} 内必须直接解析,否则会因为丢掉count等属性,并且total@:"/[]/total"必须在[]:{} 后!
242+ else { //直接解析并替换原来的,[]:{} 内必须直接解析,否则会因为丢掉count等属性,并且total@:"/[]/total"必须在[]:{} 后!
241243 response .put (key , onChildParse (index , key , (JSONObject )value ));
242244 index ++;
243245 }
244- } else if (value instanceof JSONArray && method == POST &&
245- key .startsWith ("@" ) == false && key .endsWith ("@" ) == false ) {//JSONArray,批量新增,往下一级提取
246- JSONArray valueArray = (JSONArray )value ;
247-
248- for (int i = 0 ; i < valueArray .size (); i ++) {
249- if (childMap != null ) {//添加到childMap,最后再解析
250- childMap .put (key , valueArray .getJSONObject (i ));
251- }
252- else {//直接解析并替换原来的,[]:{} 内必须直接解析,否则会因为丢掉count等属性,并且total@:"/[]/total"必须在[]:{} 后!
253- JSONObject result = (JSONObject )onChildParse (index , key , valueArray .getJSONObject (i ));
254- //合并结果
255- JSONObject before = (JSONObject )response .get (key );
256- if (result .get ("code" ).equals (200 )){
257- if (before !=null ){
258- before .put ("count" ,before .getInteger ("count" )+result .getInteger ("count" ));
259- response .put (key , before );
260- }else {
261- response .put (key , result );
262- }
263- } else {
264- //只要有一条失败,则抛出异常,全部失败
265- throw new RuntimeException (key + "," + valueArray .getJSONObject (i ) +",新增失败!" );
266- }
246+ }
247+ else if (method == PUT && value instanceof JSONArray
248+ && (whereList == null || whereList .contains (key ) == false )) { //PUT JSONArray
249+ onPUTArrayParse (key , (JSONArray ) value );
250+ }
251+ else if (method == POST && value instanceof JSONArray && key .endsWith ("[]" ) && JSONRequest .isTableKey (key .substring (0 , key .length () - 2 ))) { //JSONArray,批量新增,往下一级提取
252+ String childKey = key .substring (0 , key .length () - 2 );
253+ JSONArray valueArray = (JSONArray ) value ;
254+
255+ int allCount = 0 ;
256+ JSONArray ids = new JSONArray ();
257+
258+ int version = parser .getVersion ();
259+ int maxUpdateCount = parser .getMaxUpdateCount ();
260+
261+ for (int i = 0 ; i < valueArray .size (); i ++) { //只要有一条失败,则抛出异常,全部失败
262+ //TODO 改成一条多 VALUES 的 SQL 性能更高,报错也更会更好处理,更人性化
263+ JSONRequest req = new JSONRequest (childKey , valueArray .getJSONObject (i ));
264+
265+ //parser.getMaxSQLCount() ? 可能恶意调用接口,把数据库拖死
266+ JSONObject result = (JSONObject ) onChildParse (0 , "" + i , parser .parseCorrectRequest (method , childKey , version , "" , req , maxUpdateCount , parser ));
267+ result = result .getJSONObject (childKey );
268+ //
269+ boolean success = JSONResponse .isSuccess (result );
270+ int count = result == null ? null : result .getIntValue (JSONResponse .KEY_COUNT );
271+
272+ if (success == false || count != 1 ) { //如果 code = 200 但 count != 1,不能算成功,掩盖了错误为不好排查问题
273+ throw new ServerException ("批量新增失败!" + key + "/" + i + ":" + (success ? "成功但 count != 1 !" : (result == null ? "null" : result .getString (JSONResponse .KEY_MSG ))));
267274 }
275+
276+ allCount += count ;
277+ ids .add (result .get (JSONResponse .KEY_ID ));
268278 }
269- index ++;
270- } else if (method == PUT && value instanceof JSONArray
271- && (whereList == null || whereList .contains (key ) == false )) {//PUT JSONArray
272- onPUTArrayParse (key , (JSONArray ) value );
279+
280+ JSONObject allResult = AbstractParser .newSuccessResult ();
281+ allResult .put (JSONResponse .KEY_ID_IN , ids );
282+ allResult .put (JSONResponse .KEY_COUNT , allCount );
283+
284+ response .put (key , allResult ); //不按原样返回,避免数据量过大
273285 }
274286 else {//JSONArray或其它Object,直接填充
275287 if (onParse (key , value ) == false ) {
0 commit comments