287 Commits
1.0.0 ... 1.3.0

Author SHA1 Message Date
Redkale
ee712c55a0 2016-11-24 15:24:14 +08:00
Redkale
79f70266e4 2016-11-24 12:05:17 +08:00
Redkale
3ffb8d510d 2016-11-24 11:59:35 +08:00
Redkale
e55fc1a421 2016-11-14 15:49:03 +08:00
Redkale
ee9fb4a9b8 2016-11-13 10:54:12 +08:00
Redkale
ef3536beed 2016-11-11 11:37:19 +08:00
Redkale
fbababaf40 2016-11-11 10:43:16 +08:00
Redkale
4548cf78d6 2016-11-10 16:29:42 +08:00
Redkale
86a219e3e1 2016-11-10 16:27:41 +08:00
Redkale
9e0876dee2 2016-11-10 16:22:04 +08:00
Redkale
e9096372d3 2016-11-09 13:15:00 +08:00
Redkale
cef367c693 2016-11-08 16:25:26 +08:00
Redkale
2634524439 2016-11-08 09:40:54 +08:00
Redkale
10d27bf78c 2016-11-07 21:07:56 +08:00
Redkale
5b7739b26b 2016-11-07 19:15:27 +08:00
Redkale
11f895a0ca 2016-11-07 14:12:44 +08:00
Redkale
63099b72be 2016-11-07 12:42:02 +08:00
Redkale
0d8f7a4fa2 2016-11-07 12:28:26 +08:00
Redkale
83f460660b 2016-11-07 09:28:23 +08:00
Redkale
786d25678b 2016-11-04 09:29:30 +08:00
Redkale
f57d8325b3 2016-10-31 16:43:47 +08:00
Redkale
22adab4f93 2016-10-31 16:28:24 +08:00
Redkale
805e3910c4 增加ColumnValue功能 2016-10-31 14:09:21 +08:00
Redkale
ecd827e3b4 增加ColumnValue功能 2016-10-31 14:04:45 +08:00
Redkale
19150e9f9c 增加ColumnValue功能 2016-10-31 13:32:08 +08:00
Redkale
de5a725acc 2016-10-31 09:35:28 +08:00
Redkale
aae2305274 2016-10-28 11:54:10 +08:00
Redkale
00ba1ecee9 2016-10-28 09:32:27 +08:00
Redkale
e59465eaf9 2016-10-27 19:36:39 +08:00
Redkale
6f0b4604fc 2016-10-27 16:43:55 +08:00
Redkale
9f97f81bae 2016-10-24 11:46:48 +08:00
Redkale
ffcd04a626 2016-10-22 10:23:53 +08:00
Redkale
ecf102aff3 2016-10-21 10:53:37 +08:00
Redkale
c16b0b520d 2016-10-21 10:35:19 +08:00
Redkale
2f25ee1c05 2016-10-21 10:11:32 +08:00
Redkale
b5011fa069 2016-10-19 17:37:37 +08:00
Redkale
55e2109764 2016-10-19 10:09:44 +08:00
Redkale
5cf4c8a95a 2016-10-19 10:08:09 +08:00
Redkale
6b319caa28 2016-10-18 14:45:11 +08:00
Redkale
b97a23930a 2016-10-18 13:34:12 +08:00
Redkale
6c918a6c95 2016-10-18 10:49:36 +08:00
Redkale
20ba119f93 2016-10-18 10:48:36 +08:00
Redkale
95ca74f9f9 2016-10-17 18:11:03 +08:00
Redkale
f28cbb4ac5 2016-10-14 14:31:56 +08:00
Redkale
e3f851ed1f 2016-10-13 17:35:05 +08:00
Redkale
d3cf414c51 2016-10-13 16:43:55 +08:00
Redkale
ea98bb814f 2016-10-11 12:30:02 +08:00
Redkale
515e8256cc Update README.md 2016-10-10 20:33:42 +08:00
Redkale
903c58b239 2016-10-10 20:28:04 +08:00
Redkale
1c59c86ba2 2016-10-10 19:20:19 +08:00
Redkale
b2c6dd2db2 2016-10-10 19:19:56 +08:00
Redkale
beffe53d4d 2016-10-10 19:02:35 +08:00
Redkale
4eb5edaef2 2016-10-10 17:53:18 +08:00
Redkale
ba07d343ae 2016-10-10 17:52:15 +08:00
Redkale
c887a9dc4c 2016-10-10 17:44:57 +08:00
Redkale
689cdca004 2016-10-10 17:15:51 +08:00
Redkale
54b7863be6 2016-10-10 16:40:41 +08:00
Redkale
26453fe4c5 2016-10-10 16:40:00 +08:00
Redkale
036b248092 2016-10-10 15:48:57 +08:00
Redkale
8ca79face5 2016-10-10 15:45:13 +08:00
Redkale
6fd3250fba 2016-10-10 15:33:18 +08:00
Redkale
93a213448a 2016-10-10 15:23:58 +08:00
Redkale
e12cf185d9 2016-10-10 15:17:32 +08:00
Redkale
ca6c90eacd 2016-10-10 14:35:04 +08:00
Redkale
8901dd9a07 2016-10-10 14:20:49 +08:00
Redkale
93fef97c56 2016-10-10 13:52:20 +08:00
Redkale
ddef9018e2 2016-10-10 09:50:56 +08:00
Redkale
fb51997c6b 2016-10-08 18:42:01 +08:00
Redkale
65da7118fc 2016-10-08 17:35:37 +08:00
Redkale
fc2dfa1a8a 2016-10-08 12:30:45 +08:00
Redkale
68db4e37e2 2016-09-28 21:36:15 +08:00
Redkale
28c9b2606a 2016-09-26 20:51:01 +08:00
Redkale
d47b63e47b 2016-09-26 20:21:14 +08:00
Redkale
7f86972fa1 2016-09-26 19:48:38 +08:00
Redkale
92eefc872a 2016-09-26 14:01:20 +08:00
Redkale
c43e516d14 2016-09-26 13:51:14 +08:00
Redkale
8884fabf90 2016-09-26 13:41:35 +08:00
Redkale
1720470424 2016-09-26 13:19:09 +08:00
Redkale
1da2e95f46 2016-09-26 10:22:46 +08:00
Redkale
940af0b251 2016-09-26 10:18:21 +08:00
Redkale
43102b9d35 2016-09-26 09:41:40 +08:00
Redkale
fa601c69e7 2016-09-26 09:23:35 +08:00
Redkale
b365b18be0 2016-09-26 09:05:44 +08:00
Redkale
bc8a52eef8 2016-09-25 14:11:42 +08:00
Redkale
afa45498d4 2016-09-24 18:22:01 +08:00
Redkale
6f056bbcb6 2016-09-23 10:03:49 +08:00
Redkale
4fb218fd18 2016-09-18 19:51:34 +08:00
Redkale
1e7575c7b7 2016-09-18 19:50:17 +08:00
Redkale
02fd74f6de 2016-09-18 10:53:16 +08:00
Redkale
77732347d0 2016-09-18 10:41:54 +08:00
Redkale
53eaad17ea 2016-09-18 09:01:14 +08:00
Redkale
4cdc1f82c5 2016-09-14 14:41:30 +08:00
Redkale
77c2f72b42 2016-09-14 14:39:15 +08:00
Redkale
469069d2ac 2016-09-14 14:04:39 +08:00
Redkale
d7542a0c0a 2016-09-14 14:03:05 +08:00
Redkale
15d36735da 2016-09-14 13:11:08 +08:00
Redkale
d3163a6e0d 2016-09-14 12:08:10 +08:00
Redkale
23fd664eef 2016-09-14 11:32:05 +08:00
Redkale
f21cb2c233 2016-09-14 11:22:25 +08:00
Redkale
0a2a9f0e80 2016-09-14 10:48:16 +08:00
Redkale
9b74f46b22 2016-09-14 10:44:54 +08:00
Redkale
59ca4afd8b 2016-09-14 10:41:15 +08:00
Redkale
bc1c749152 2016-09-14 10:39:56 +08:00
Redkale
d35987612d 2016-09-14 10:24:24 +08:00
Redkale
04b5b361ad 2016-09-14 10:08:16 +08:00
Redkale
a81c9f7d21 2016-09-14 09:36:33 +08:00
Redkale
2c75c04b7e 2016-09-13 17:38:46 +08:00
Redkale
9bf5044654 2016-09-13 17:19:18 +08:00
Redkale
e99fd3c049 2016-09-13 16:09:50 +08:00
Redkale
4e9b3f45fc 2016-09-13 16:07:26 +08:00
Redkale
95f4cd0634 2016-09-12 21:08:10 +08:00
Redkale
a43f9a0121 2016-09-09 15:21:57 +08:00
Redkale
6f6952ad2c 2016-09-09 11:59:10 +08:00
Redkale
21cfbebe26 2016-09-08 09:21:28 +08:00
Redkale
f16beca680 2016-09-08 09:18:46 +08:00
Redkale
1341e81361 2016-09-08 09:18:18 +08:00
Redkale
f08a29b15a 2016-09-07 22:22:09 +08:00
Redkale
fea5123915 2016-09-07 21:32:41 +08:00
Redkale
cd45cafec5 2016-09-07 19:16:30 +08:00
Redkale
bed86d44a1 2016-09-07 18:33:32 +08:00
Redkale
bd3ae4bb41 2016-09-07 18:01:37 +08:00
Redkale
589d34d8a4 2016-09-07 17:29:58 +08:00
Redkale
a455795703 2016-09-07 16:32:11 +08:00
Redkale
fbb9cdefe1 2016-09-07 16:19:14 +08:00
Redkale
d202b2fbad 2016-09-07 13:53:33 +08:00
Redkale
9d82ca84a4 2016-09-06 14:34:55 +08:00
Redkale
1f0e0accb1 2016-09-06 13:45:56 +08:00
Redkale
fa8e40f6c0 2016-09-06 12:21:30 +08:00
Redkale
1a22cd0fe1 2016-09-06 12:00:49 +08:00
Redkale
8422173411 2016-09-06 09:46:37 +08:00
Redkale
c63248ba7f 2016-09-06 08:40:39 +08:00
Redkale
de4dda7c73 2016-09-06 08:37:00 +08:00
Redkale
e546ff74a5 2016-09-06 08:29:44 +08:00
Redkale
506f930320 2016-09-06 08:23:10 +08:00
Redkale
09beaedee8 2016-09-05 21:26:32 +08:00
Redkale
40845f5f60 2016-09-05 18:29:50 +08:00
Redkale
f3f001d72d 2016-09-05 18:29:21 +08:00
Redkale
b49a4d2c83 2016-09-05 15:07:57 +08:00
Redkale
90884f4621 2016-09-04 08:19:13 +08:00
Redkale
c2fd7be5e2 2016-09-02 19:41:26 +08:00
Redkale
b1773107a1 2016-09-02 19:27:05 +08:00
Redkale
f6aa646ea4 2016-09-02 18:07:04 +08:00
Redkale
72887106ea 2016-09-02 17:56:14 +08:00
Redkale
aa6126ddec 2016-09-02 10:16:14 +08:00
Redkale
a98a35b4af 2016-09-01 10:00:28 +08:00
Redkale
07253b1f17 2016-08-31 19:10:20 +08:00
Redkale
48a4c6d53c 2016-08-31 19:06:57 +08:00
Redkale
d78c08878c 2016-08-31 13:42:32 +08:00
Redkale
d40ea81fc3 2016-08-31 09:21:12 +08:00
Redkale
78ac88b57c 2016-08-31 09:20:49 +08:00
Redkale
3595f8b6bc 2016-08-30 15:06:56 +08:00
Redkale
1421b83e49 2016-08-30 14:22:11 +08:00
Redkale
90361edba1 2016-08-30 13:01:03 +08:00
Redkale
3d3347b64f 2016-08-30 08:59:06 +08:00
Redkale
f8a439e21f 2016-08-30 02:16:33 +08:00
Redkale
9d76e693fb 2016-08-30 02:14:59 +08:00
Redkale
a206ecd76b 2016-08-30 02:13:56 +08:00
Redkale
81f386dcdb 2016-08-29 20:27:54 +08:00
Redkale
e8e6459679 2016-08-29 17:21:02 +08:00
Redkale
9f5ab4b068 2016-08-29 14:48:29 +08:00
Redkale
1ea816a60e 2016-08-29 13:50:05 +08:00
Redkale
2c5876ba3e 2016-08-27 15:29:40 +08:00
Redkale
cffe181344 删除Source异步版接口 2016-08-27 15:25:03 +08:00
Redkale
4647545ff5 2016-08-27 15:07:34 +08:00
Redkale
bfe78a805e 2016-08-27 14:52:34 +08:00
Redkale
c480b2b18e 2016-08-27 14:30:25 +08:00
Redkale
7e9885de2e 2016-08-27 14:25:57 +08:00
Redkale
db32656c8a 2016-08-27 13:50:24 +08:00
Redkale
b981307768 2016-08-26 21:38:24 +08:00
Redkale
b0e0a341ec 2016-08-26 14:12:28 +08:00
Redkale
40ef40b813 2016-08-26 09:51:36 +08:00
Redkale
dfacd49a70 2016-08-26 08:09:03 +08:00
Redkale
470a82b6e6 2016-08-26 07:16:47 +08:00
Redkale
d5a752dea0 2016-08-26 06:51:06 +08:00
Redkale
554932201b 2016-08-26 06:37:47 +08:00
Redkale
54462e8c26 2016-08-25 14:21:09 +08:00
Redkale
d9807148db 2016-08-25 13:50:13 +08:00
Redkale
66a5fc2447 2016-08-25 12:32:41 +08:00
Redkale
4f9c8ce145 2016-08-25 09:13:20 +08:00
Redkale
884cc930c8 2016-08-25 09:00:20 +08:00
Redkale
cd4b18ad45 2016-08-25 08:52:51 +08:00
Redkale
707fc783b5 2016-08-25 08:52:18 +08:00
Redkale
3ca6ad6e12 2016-08-25 07:22:48 +08:00
Redkale
4972f5804e 2016-08-24 22:34:31 +08:00
Redkale
aec69d2973 2016-08-24 22:27:27 +08:00
Redkale
3f2a7f684f 2016-08-24 22:00:48 +08:00
Redkale
ce9f517244 2016-08-24 21:53:07 +08:00
Redkale
192e52f18f 2016-08-24 18:25:49 +08:00
Redkale
cdbe53d3d9 2016-08-24 17:50:30 +08:00
Redkale
58f4f28e14 2016-08-24 17:39:53 +08:00
Redkale
bc19d75422 2016-08-24 17:34:17 +08:00
Redkale
bb77681445 2016-08-24 16:08:12 +08:00
Redkale
d2a3291f13 删除@DistributeTables功能 2016-08-24 15:46:29 +08:00
Redkale
116e82115b 2016-08-24 14:00:57 +08:00
Redkale
e0b5067949 2016-08-24 13:58:31 +08:00
Redkale
8e639e32a3 2016-08-24 13:55:44 +08:00
Redkale
5a1586bc6a 2016-08-24 13:48:52 +08:00
Redkale
30b6ddc4f4 2016-08-24 08:00:32 +08:00
Redkale
0667c6a12e 2016-08-24 07:11:30 +08:00
Redkale
6eb9429b68 2016-08-23 14:06:25 +08:00
Redkale
91f32684ef 2016-08-23 13:28:01 +08:00
Redkale
fc475d6253 2016-08-20 17:38:23 +08:00
Redkale
3df13a3b17 2016-08-20 12:34:55 +08:00
Redkale
3d0bd3a5c2 2016-08-20 12:33:23 +08:00
Redkale
42c188867a 2016-08-18 14:21:23 +08:00
Redkale
a3647f79ac 2016-08-16 20:11:40 +08:00
Redkale
f83fded877 2016-08-16 20:00:34 +08:00
Redkale
df42be86d6 2016-08-16 19:42:17 +08:00
Redkale
d22b44f1f9 2016-08-16 19:32:07 +08:00
Redkale
1592938d99 2016-08-16 19:04:02 +08:00
Redkale
a3681ca698 2016-08-15 11:32:12 +08:00
Redkale
5f1556e5cb 2016-08-15 11:20:33 +08:00
Redkale
64bc543df2 2016-08-14 16:14:51 +08:00
Redkale
36f03344bd 2016-08-10 15:17:50 +08:00
Redkale
d764b741d4 2016-08-08 11:54:22 +08:00
Redkale
e5a83c51f3 2016-08-08 11:01:37 +08:00
Redkale
42e7ac298e 2016-08-08 10:48:46 +08:00
Redkale
bf9098df86 2016-08-01 21:58:27 +08:00
Redkale
d44e45166e 2016-08-01 20:39:17 +08:00
Redkale
07304e61d9 2016-07-31 22:08:11 +08:00
Redkale
c69fcc25db 2016-07-30 22:06:36 +08:00
Redkale
72e25d653b 2016-07-27 16:51:46 +08:00
Redkale
c3fde23d77 2016-07-26 11:21:03 +08:00
Redkale
1369bd3e9e 2016-07-26 10:47:47 +08:00
Redkale
2c70162798 2016-07-26 10:38:14 +08:00
Redkale
5db8426553 2016-07-26 10:36:22 +08:00
Redkale
3c667d88aa 2016-07-26 09:58:37 +08:00
Redkale
7a11b7887c 2016-07-26 09:43:25 +08:00
Redkale
bfbc48a597 2016-07-25 19:21:18 +08:00
Redkale
ba14c59baa 2016-07-25 17:56:40 +08:00
Redkale
63d7e85fb4 2016-07-25 17:48:58 +08:00
Redkale
66c2f0970f 2016-07-25 17:38:00 +08:00
Redkale
e78d590fc2 2016-07-25 17:36:00 +08:00
Redkale
8f7ca376a9 2016-07-25 17:07:26 +08:00
Redkale
82b041e6d5 2016-07-24 12:15:44 +08:00
Redkale
5ae6afa20e 2016-07-24 12:05:01 +08:00
Redkale
1aeae47a89 2016-07-24 11:57:16 +08:00
Redkale
7bf73b60b5 2016-07-24 11:47:36 +08:00
Redkale
7e26ddddd5 2016-07-23 10:28:13 +08:00
Redkale
593ed3e7e0 2016-07-23 10:14:20 +08:00
Redkale
c0ff67df73 2016-07-23 09:55:57 +08:00
Redkale
5489e01987 2016-07-23 09:44:58 +08:00
Redkale
65910f8b66 2016-07-23 09:26:20 +08:00
Redkale
ea277f4ea3 2016-07-22 16:15:50 +08:00
Redkale
02fc248fcf 2016-07-22 11:41:59 +08:00
Redkale
1b42a4241a 2016-07-21 15:39:32 +08:00
Redkale
7ed0020b1d 2016-07-18 21:15:55 +08:00
Redkale
94bb11329d 2016-07-18 21:14:56 +08:00
Redkale
fccf314282 2016-07-18 21:09:47 +08:00
Redkale
35029ad796 2016-07-18 21:06:19 +08:00
Redkale
ea059594f0 2016-07-18 21:05:48 +08:00
Redkale
839c742423 2016-07-12 23:44:41 +08:00
Redkale
00b6910986 2016-07-12 14:08:14 +08:00
Redkale
01da67dbf8 2016-07-11 14:13:27 +08:00
Redkale
73a7864e09 2016-07-08 21:41:15 +08:00
Redkale
a996ab5eb5 2016-07-07 09:46:33 +08:00
Redkale
0d6a778d9c 2016-07-06 22:45:11 +08:00
Redkale
34ddd0d65e 2016-07-06 22:40:24 +08:00
Redkale
4f950d5874 2016-07-06 22:05:39 +08:00
Redkale
6b228f1fc9 2016-07-06 22:04:32 +08:00
Redkale
521a0d4cbb Update README.md 2016-07-05 22:31:11 +08:00
Redkale
9ba2571ed1 2016-07-05 13:57:32 +08:00
Redkale
cfcdb093e7 2016-07-05 09:03:41 +08:00
Redkale
9c3c7e414a 2016-07-03 14:02:42 +08:00
Redkale
a7781322c7 2016-07-03 12:27:05 +08:00
Redkale
34a0fef035 2016-07-03 12:04:31 +08:00
Redkale
4dfda3ec51 2016-07-03 12:01:13 +08:00
Redkale
fd0a6b94e9 2016-07-03 09:40:24 +08:00
Redkale
1af2457cc7 2016-07-03 09:33:26 +08:00
Redkale
f4bd6074f1 2016-07-02 21:27:52 +08:00
Redkale
5b6e01ecb8 2016-07-02 20:48:59 +08:00
Redkale
85844276ed 2016-07-02 19:15:33 +08:00
Redkale
af74bad593 2016-07-02 17:47:43 +08:00
Redkale
f82becfe62 2016-07-02 16:58:19 +08:00
Redkale
a98d5f32a1 2016-07-02 16:41:58 +08:00
Redkale
a2d4b6ec37 2016-07-02 10:49:11 +08:00
RedKale
29a80e95c7 2016-06-29 17:43:26 +08:00
RedKale
41c1ea32d1 将Flipper中的page页号换成start记录号,将影响到HttpServlet中findFlipper的实现 2016-06-28 16:24:35 +08:00
RedKale
c100207302 2016-06-27 16:48:15 +08:00
RedKale
5b4b08b6ce 2016-06-27 16:30:19 +08:00
RedKale
a6a3890e70 2016-06-27 16:08:51 +08:00
RedKale
d3d24529a6 2016-06-27 09:28:35 +08:00
RedKale
5593a518fc 2016-06-26 22:25:24 +08:00
RedKale
511a31bf95 2016-06-26 14:08:35 +08:00
RedKale
999f55222b 2016-06-26 11:15:55 +08:00
RedKale
56cd881a99 2016-06-26 10:24:46 +08:00
RedKale
a0439518f3 2016-06-26 10:18:32 +08:00
247 changed files with 7098 additions and 3169 deletions

View File

@@ -21,4 +21,4 @@
&nbsp;&nbsp;&nbsp;由于RedKale使用了JDK 8 内置的ASM包所以需要在源码工程中的编译器选项中加入 <b>-XDignore.symbol.file=true</b>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<h5>详情请访问:&nbsp;&nbsp;&nbsp;&nbsp;<a href='http://www.redkale.org' target='_blank'>http://www.redkale.org</a></h5>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<h5>详情请访问:&nbsp;&nbsp;&nbsp;&nbsp;<a href='https://redkale.org' target='_blank'>https://redkale.org</a></h5>

7
bin/apidoc.bat Normal file
View File

@@ -0,0 +1,7 @@
@ECHO OFF
SET APP_HOME=%~dp0
IF NOT EXIST "%APP_HOME%\conf\application.xml" SET APP_HOME=%~dp0..
java -DCMD=APIDOC -DAPP_HOME=%APP_HOME% -classpath %APP_HOME%\lib\* org.redkale.boot.Application

18
bin/apidoc.sh Normal file
View File

@@ -0,0 +1,18 @@
#!/bin/sh
export LC_ALL="zh_CN.UTF-8"
APP_HOME=`dirname "$0"`
if [ ! -a "$APP_HOME"/conf/application.xml ]; then
APP_HOME="$APP_HOME"/..
fi
lib='.'
for jar in `ls $APP_HOME/lib/*.jar`
do
lib=$lib:$jar
done
export CLASSPATH=$CLASSPATH:$lib
echo "$APP_HOME"
java -DCMD=APIDOC -DAPP_HOME="$APP_HOME" org.redkale.boot.Application

View File

@@ -4,4 +4,4 @@ SET APP_HOME=%~dp0
IF NOT EXIST "%APP_HOME%\conf\application.xml" SET APP_HOME=%~dp0..
java -DSHUTDOWN=true -DAPP_HOME=%APP_HOME% -classpath %APP_HOME%\lib\* org.redkale.boot.Application
java -DCMD=SHUTDOWN -DAPP_HOME=%APP_HOME% -classpath %APP_HOME%\lib\* org.redkale.boot.Application

View File

@@ -15,4 +15,4 @@ do
done
export CLASSPATH=$CLASSPATH:$lib
echo "$APP_HOME"
java -DSHUTDOWN=true -DAPP_HOME="$APP_HOME" org.redkale.boot.Application
java -DCMD=SHUTDOWN -DAPP_HOME="$APP_HOME" org.redkale.boot.Application

View File

@@ -5,10 +5,12 @@ handlers = java.util.logging.ConsoleHandler
############################################################
.level = FINE
org.level = INFO
java.level = INFO
javax.level = INFO
com.sun.level = INFO
sun.level = INFO
jdk.level = INFO
java.util.logging.FileHandler.level = FINE
#10M

158
pom.xml
View File

@@ -1,158 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.redkale</groupId>
<artifactId>redkale</artifactId>
<name>Redkale</name>
<packaging>jar</packaging>
<url>http://redkale.org</url>
<!-- -SNAPSHOT
mvn clean deploy -P release -Dgpg.passphrase=password
mvn release:clean release:prepare release:perform
-->
<version>1.0.0-rc1</version>
<description>Redkale is a Microservices Framework written in Java</description>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<encoding>UTF-8</encoding>
<compilerArguments>
<verbose />
<bootclasspath>${java.home}/lib/rt.jar</bootclasspath>
</compilerArguments>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.6</version>
<configuration>
<archive>
<manifest>
<mainClass>org.redkale.boot.Application</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.10.3</version>
<configuration>
<charset>${file_encoding}</charset>
<encoding>${file_encoding}</encoding>
</configuration>
<executions>
<execution>
<id>attach-javadocs</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-compiler-javac</artifactId>
<version>2.7</version>
</dependency>
<dependency>
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-utils</artifactId>
<version>3.0.22</version>
</dependency>
</dependencies>
<profiles>
<profile>
<id>release-sign-artifacts</id>
<activation>
<property>
<name>performRelease</name>
<value>true</value>
</property>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-gpg-plugin</artifactId>
<version>1.6</version>
<executions>
<execution>
<id>sign-artifacts</id>
<phase>verify</phase>
<goals>
<goal>sign</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
<scm>
<url>https://github.com/redkale/redkale/tags/redkale-1.0.0-rc1</url>
<connection>scm:svn:https://github.com/redkale/redkale/tags/redkale-1.0.0-rc1</connection>
</scm>
<developers>
<developer>
<id>redkale</id>
<name>redkale</name>
<email>redkale@qq.com</email>
</developer>
</developers>
<licenses>
<license>
<name>Apache 2</name>
<url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
<distribution>repo</distribution>
<comments>A business-friendly OSS license</comments>
</license>
</licenses>
<distributionManagement>
<snapshotRepository>
<id>ossrh</id>
<url>https://oss.sonatype.org/content/repositories/snapshots</url>
</snapshotRepository>
<repository>
<id>ossrh</id>
<url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
</repository>
</distributionManagement>
</project>

View File

@@ -2,6 +2,7 @@
<!--
文件说明:
${APP_HOME} 指当前程序的根目录APP_HOME
没注明唯一的节点可多个存在
required 被声明required的属性值不能为空
group
@@ -18,27 +19,31 @@
serviceid1_name1 serviceid1_name2 serviceid2_name1 serviceid2_name2
-->
<!--
address: 本地的IP地址 默认值为默认网卡的ip当不使用默认值需要指定值如127.0.0.1
address: 本地局域网的IP地址 默认值为默认网卡的ip当不使用默认值需要指定值如192.168.1.22
port: required 程序的管理Server的端口用于关闭或者与监管系统进行数据交互
host: 程序的管理Server的地址; 默认为127.0.0.1。
lib: 加上额外的lib路径,多个路径用分号;隔开; 默认为空。 例如: ${APP_HOME}/lib/a.jar;${APP_HOME}/lib2/b.jar;
-->
<application port="6560" lib="">
<!-- 所有服务所需的资源 -->
<!--
【节点全局唯一】
所有服务所需的资源
-->
<resources>
<!--
【节点全局唯一】
transport节点只能有一个用于配置所有Transport的池参数没配置该节点将自动创建一个。
threads 线程总数, 默认: <group>节点数*CPU核数*8
bufferCapacity: ByteBuffer的初始化大小 默认: 8K;
bufferPoolSize ByteBuffer池的大小默认: <group>节点数*CPU核数*8
-->
<transport capacity="8192" bufferPoolSize="32" threads="32"/>
<transport bufferCapacity="8K" bufferPoolSize="32" threads="32"/>
<!--
一个组包含多个NODE 同一Service服务可以由多个进程提供这些进程称为一个GROUP且同一GROUP内的进程必须在同一机房或局域网内
一个group节点对应一个 Transport 对象。
name: 服务组ID长度不能超过11个字节. 默认为空字符串。 注意: name不能包含$符号。
protocol值只能是UDP TCP 默认TCP
kind: 与SNCP服务连接时的数据传输类型可选值有:rest(不区分大小写);值为空或空字符串表示按SNCP协议传输; 为rest表示按REST传输。默认值为空
注意: 一个node只能所属一个group。只要存在protocol=SNCP的Server节点信息 就必须有group节点信息。
-->
<group name="" protocol="TCP">
@@ -53,6 +58,7 @@
<node addr="127.0.0.1" port="7070"/>
</group>
<!--
【节点全局唯一】
全局的参数配置, 可以通过@Resource(name="property.xxxxxx") 进行注入, 被注解的字段类型只能是String、primitive class
如果name是system.property.开头的值将会在进程启动时进行System.setProperty("yyyy", "YYYYYY")操作。
如果name是mimetype.property.开头的值将会在进程启动时进行MimeType.add("yyyy", "YYYYYY")操作。
@@ -78,7 +84,8 @@
host: 服务所占address 默认: 0.0.0.0
port: required 服务所占端口
root: 如果是web类型服务则包含页面 默认:{APP_HOME}/root
lib: server额外的class目录 默认为空
lib: server额外的class目录 默认为空
excludelibs: 排除lib.path与excludes中的正则表达式匹配的路径, 多个正则表达式用分号;隔开
charset: 文本编码, 默认: UTF-8
backlog: 默认10K
threads 线程总数, 默认: CPU核数*16
@@ -88,7 +95,7 @@
responsePoolSize Response池的大小默认: CPU核数*256
readTimeoutSecond: 读操作超时秒数, 默认0 表示永久不超时
writeTimeoutSecond: 写操作超时秒数, 默认0 表示永久不超时
nodeInterceptor: 启动/关闭NodeServer时被调用的拦截器实现类必须是org.redkale.boot.NodeInterceptor的子类默认为null
interceptor: 启动/关闭NodeServer时被调用的拦截器实现类必须是org.redkale.boot.NodeInterceptor的子类默认为null
-->
<server protocol="HTTP" host="127.0.0.1" port="6060" root="root" lib="">
@@ -114,13 +121,32 @@
-->
<service value="com.xxx.XXX2Service" name="" groups="xxx;yyy"/>
<!-- 给Service增加配置属性 -->
<service value="com.xxx.XXX1Service">
<property name="xxxxxx" value="XXXXXXXX"/>
<service value="com.xxx.XXX1Service">
<!-- property节点值在 public void init(AnyValue conf) 方法中可以通过 AnyValue properties = conf.getAnyValue("properties");获取 -->
<property name="xxxxxx" value="XXXXXXXX"/>
<property name="xxxxxx" value="XXXXXXXX"/>
</service>
</services>
<!--
REST的核心配置项
当Server为HTTP协议时, rest节点才有效。存在[rest]节点则Server启动时会加载REST服务, 节点可以多个
base: REST服务的BaseServlet必须是 org.redkale.net.http.RestHttpServlet 的子类,该属性值默认值为 org.redkale.net.http.DefaultRestServlet。
autoload默认值"true" 默认值. 加载当前server所能使用的Servce对象;
mustsign默认值"true" 是否只加载标记为RestService的Service类默认只加载标记RestService且ignore=false的Service
includes当autoload="true" 拉取类名与includes中的正则表达式匹配的类, 多个正则表达式用分号;隔开
excludes当autoload="true" 排除类名与excludes中的正则表达式匹配的类, 多个正则表达式用分号;隔开
-->
<rest base="org.redkale.net.http.DefaultRestServlet" mustsign="false" autoload="true" includes="" excludes="">
<!--
value: Service类名列出的表示必须被加载的Service对象
ignore: 是否忽略设置为true则不会加载该Service对象默认值为false
-->
<service value="com.xxx.XXXXService"/>
</rest>
<!--
【节点在<server>中唯一】
当Server为HTTP协议时, request节点才有效。
remoteaddr 节点: 替换请求方节点的IP地址 通常请求方是由nginx等web静态服务器转发过的则需要配置该节点。
且value值只能是以request.headers.开头表示从request.headers中获取对应的header值。
@@ -131,6 +157,7 @@
</request>
<!--
【节点在<server>中唯一】
当Server为HTTP协议时, response节点才有效。
defcookie 节点: 当response里输出的cookie没有指定domain 和path时使用该节点的默认值。
如果addheader、setheader 的value值以request.parameters.开头则表示从request.parameters中获取对应的parameter值
@@ -143,6 +170,31 @@
<setheader name="Access-Control-Allow-Credentials" value="true"/>
</response>
<!--
【节点在<server>中唯一】
当Server为HTTP协议时ResourceServlet才有效. 默认存在一个有默认属性的resource-servlet节点
webroot: web资源的根目录, 默认取server节点中的root值
servlet: 静态资源HttpServlet的实现默认使用HttpResourceServlet
index : 启始页默认值index.html
-->
<resource-servlet webroot="root" index="index.html">
<!--
【节点在<resource-servlet>中唯一】
资源缓存的配置, 默认存在一个含默认属性的caches节点
limit: 资源缓存最大容量, 默认: 0, 为0表示不缓存 单位可以是B、K、M、G不区分大小写
lengthmax: 可缓存的文件大小上限, 默认: 1M超过1M的文件不会被缓存
watch: 是否监控缓存文件的变化, 默认为false不监控
-->
<cache limit="0M" lengthmax="1M" watch="false"/>
<!--
支持类似nginx中的rewrite 目前只支持静态资源对静态资源的跳转。
type: 匹配的类型, 目前只支持location(匹配requestURI), 默认: location
match: 匹配的正则表达式
forward: 需跳转后的资源链接
例如下面例子是将/xxx-yyy.html的页面全部跳转到/xxx.html
-->
<rewrite type="location" match="^/([^-]+)-[^-\.]+\.html(.*)" forward="/$1.html"/>
</resource-servlet>
<!--
加载所有的Servlet服务;
path: servlet的ContextPath前缀 默认为空
@@ -153,26 +205,6 @@
excludes 当autoload="true" 排除类名与excludes中的正则表达式匹配的类, 多个正则表达式用分号;隔开
-->
<servlets path="/pipes" autoload="true" includes="" excludes="">
<!--
当Server为HTTP协议时ResourceServlet才有效. 默认存在一个有默认属性的resource-servlet节点
webroot: web资源的根目录, 默认取server节点中的root值
-->
<resource-servlet webroot="root">
<!--
资源缓存的配置, 默认存在一个含默认属性的caches节点
limit: 资源缓存最大容量, 默认: 0, 为0表示不缓存 单位可以是B、K、M、G不区分大小写
lengthmax: 可缓存的文件大小上限, 默认: 1M超过1M的文件不会被缓存
-->
<caches limit="0M" lengthmax="1M" />
<!--
支持类似nginx中的rewrite 目前只支持静态资源对静态资源的跳转。
type: 匹配的类型, 目前只支持location(匹配requestURI), 默认: location
match: 匹配的正则表达式
forward: 需跳转后的资源链接
例如下面例子是将/xxx-yyy.html的页面全部跳转到/xxx.html
-->
<rewrite type="location" match="^/([^-]+)-[^-\.]+\.html(.*)" forward="/$1.html"/>
</resource-servlet>
<!-- 显著加载指定的Servlet -->
<servlet value="com.xxx.XXX1Servlet" />
<servlet value="com.xxx.XXX2Servlet" />

View File

@@ -5,7 +5,6 @@ handlers = java.util.logging.ConsoleHandler,java.util.logging.FileHandler
############################################################
.level = FINE
org.level = INFO
sun.level = INFO
java.level = INFO
javax.level = INFO

View File

@@ -0,0 +1,48 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- 其配置算是标准的JPA配置文件的缩略版 -->
<persistence>
<!-- 系统基本库 -->
<persistence-unit name="demouser">
<!-- 为NONE表示不启动缓存@Cacheable 失效; 非NONE值(通常用ALL)表示开启缓存。 -->
<shared-cache-mode>NONE</shared-cache-mode>
<properties>
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://127.0.0.1:3306/dbuser?characterEncoding=utf8"/>
<!--
javax.persistence.jdbc.driver在JPA的值是JDBC驱动Redkale有所不同值应该是javax.sql.DataSource的子类。
为了兼容用户习惯Redkale内置常见JDBC驱动到javax.sql.DataSource的映射关系
org.mariadb.jdbc.Driver —————— org.mariadb.jdbc.MySQLDataSource
org.postgresql.Driver —————— org.postgresql.ds.PGConnectionPoolDataSource
com.mysql.jdbc.Driver —————— com.mysql.jdbc.jdbc2.optional.MysqlConnectionPoolDataSource
oracle.jdbc.driver.OracleDriver —————— oracle.jdbc.pool.OracleConnectionPoolDataSource
com.microsoft.sqlserver.jdbc.SQLServerDriver —————— com.microsoft.sqlserver.jdbc.SQLServerConnectionPoolDataSource
因此 com.mysql.jdbc.Driver 会被自动转换成 com.mysql.jdbc.jdbc2.optional.MysqlConnectionPoolDataSource
-->
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
<property name="javax.persistence.jdbc.user" value="root"/>
<property name="javax.persistence.jdbc.password" value="123456"/>
<!-- 最大连接数默认值CPU数*16 -->
<property name="javax.persistence.connections.limit" value="32"/>
<!-- 包含的SQL模板相当于反向LIKE不同的JDBC驱动的SQL语句不一样Redkale内置了MySQL的语句 -->
<property name="javax.persistence.contain.sqltemplate" value="LOCATE(${keystr}, ${column}) > 0"/>
<property name="javax.persistence.notcontain.sqltemplate" value="LOCATE(${keystr}, ${column}) = 0"/>
<!-- 复制表结构的SQL模板Redkale内置了MySQL的语句 -->
<property name="javax.persistence.tablenotexist.sqlstates" value="42000;42S02"/>
<property name="javax.persistence.tablecopy.sqltemplate" value="CREATE TABLE ${newtable} LIKE ${oldtable}"/>
</properties>
</persistence-unit>
<!-- IM消息库 -->
<persistence-unit name="demoim">
<shared-cache-mode>NONE</shared-cache-mode>
<properties>
<!-- jdbc:mysql://127.0.0.1:3306/dbim?autoReconnect=true&amp;autoReconnectForPools=true&amp;characterEncoding=utf8 -->
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://127.0.0.1:3306/dbim?characterEncoding=utf8"/>
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
<property name="javax.persistence.jdbc.user" value="root"/>
<property name="javax.persistence.jdbc.password" value="123456"/>
</properties>
</persistence-unit>
</persistence>

View File

@@ -61,6 +61,13 @@ public @interface Column {
*/
String name() default "";
/**
* (Optional) The comment of the column.
*
* @return String
*/
String comment() default "";
/**
* (Optional) Whether the column is a unique key. This is a
* shortcut for the <code>UniqueConstraint</code> annotation at the table
@@ -96,17 +103,6 @@ public @interface Column {
*/
boolean updatable() default true;
/**
* (Optional) The SQL fragment that is used when
* generating the DDL for the column.
* <p>
* Defaults to the generated SQL to create a
* column of the inferred type.
*
* @return String
*/
String columnDefinition() default "";
/**
* (Optional) The name of the table that contains the column.
* If absent the column is assumed to be in the primary table.

View File

@@ -40,4 +40,11 @@ public @interface Entity {
* @return String
*/
String name() default "";
/**
* (Optional) The comment of the entity.
*
* @return String
*/
String comment() default "";
}

View File

@@ -1,4 +1,4 @@
/*******************************************************************************
/** *****************************************************************************
* Copyright (c) 2008 - 2013 Oracle Corporation. All rights reserved.
*
* This program and the accompanying materials are made available under the
@@ -12,7 +12,7 @@
* Linda DeMichiel - Java Persistence 2.1
* Linda DeMichiel - Java Persistence 2.0
*
******************************************************************************/
***************************************************************************** */
package javax.persistence;
import java.lang.annotation.Target;
@@ -23,13 +23,14 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME;
/**
* Provides for the specification of generation strategies for the
* values of primary keys.
* values of primary keys.
*
* <p> The <code>GeneratedValue</code> annotation
* <p>
* The <code>GeneratedValue</code> annotation
* may be applied to a primary key property or field of an entity or
* mapped superclass in conjunction with the {@link Id} annotation.
* The use of the <code>GeneratedValue</code> annotation is only
* required to be supported for simple primary keys. Use of the
* required to be supported for simple primary keys. Use of the
* <code>GeneratedValue</code> annotation is not supported for derived
* primary keys.
*
@@ -58,22 +59,5 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME;
@Retention(RUNTIME)
public @interface GeneratedValue {
/**
* (Optional) The primary key generation strategy
* that the persistence provider must use to
* generate the annotated entity primary key.
* @return GenerationType
*/
@Deprecated
GenerationType strategy() default GenerationType.AUTO;
/**
* (Optional) The name of the primary key generator
* to use as specified in the SequenceGenerator
* or TableGenerator annotation.
* <p> Defaults to the id generator supplied by persistence provider.
* @return String
*/
@Deprecated
String generator() default "";
}

View File

@@ -1,56 +0,0 @@
/*******************************************************************************
* Copyright (c) 2008 - 2013 Oracle Corporation. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
* which accompanies this distribution.
* The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Linda DeMichiel - Java Persistence 2.1
* Linda DeMichiel - Java Persistence 2.0
*
******************************************************************************/
package javax.persistence;
/**
* Defines the types of primary key generation strategies.
*
* @see GeneratedValue
*
* @since Java Persistence 1.0
*/
public enum GenerationType {
/**
* Indicates that the persistence provider must assign
* primary keys for the entity using an underlying
* database table to ensure uniqueness.
*/
TABLE,
/**
* Indicates that the persistence provider must assign
* primary keys for the entity using a database sequence.
*/
SEQUENCE,
/**
* Indicates that the persistence provider must assign
* primary keys for the entity using a database identity column.
*/
IDENTITY,
/**
* Indicates that the persistence provider should pick an
* appropriate strategy for the particular database. The
* <code>AUTO</code> generation strategy may expect a database
* resource to exist, or it may attempt to create one. A vendor
* may provide documentation on how to create such resources
* in the event that it does not support schema generation
* or cannot create the schema resource at runtime.
*/
AUTO
}

View File

@@ -1,4 +1,4 @@
/*******************************************************************************
/** *****************************************************************************
* Copyright (c) 2008 - 2013 Oracle Corporation. All rights reserved.
*
* This program and the accompanying materials are made available under the
@@ -12,7 +12,7 @@
* Linda DeMichiel - Java Persistence 2.1
* Linda DeMichiel - Java Persistence 2.0
*
******************************************************************************/
***************************************************************************** */
package javax.persistence;
import java.lang.annotation.Target;
@@ -22,9 +22,10 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME;
/**
* Specifies the primary table for the annotated entity. Additional
* tables may be specified using SecondaryTable or SecondaryTables annotation.
* tables may be specified using SecondaryTable or SecondaryTables annotation.
*
* <p> If no <code>Table</code> annotation is specified for an entity
* <p>
* If no <code>Table</code> annotation is specified for an entity
* class, the default values apply.
*
* <pre>
@@ -37,27 +38,25 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME;
*
* @since Java Persistence 1.0
*/
@Target(TYPE)
@Target(TYPE)
@Retention(RUNTIME)
public @interface Table {
/**
* (Optional) The name of the table.
* <p> Defaults to the entity name.
* <p>
* Defaults to the entity name.
*
* @return String
*/
String name() default "";
/** (Optional) The catalog of the table.
* <p> Defaults to the default catalog.
* <p>
* Defaults to the default catalog.
*
* @return String
*/
String catalog() default "";
/** (Optional) The schema of the table.
* <p> Defaults to the default schema for user.
* @return String
*/
String schema() default "";
}

View File

@@ -0,0 +1,154 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.redkale.boot;
import java.io.*;
import java.lang.reflect.*;
import java.util.*;
import javax.persistence.Column;
import org.redkale.convert.json.JsonConvert;
import org.redkale.net.http.*;
import org.redkale.util.*;
/**
* 继承 HttpBaseServlet 是为了获取 WebAction 信息
*
* 详情见: https://redkale.org
*
* @author zhangjx
*/
public class ApiDocs extends HttpBaseServlet {
private final Application app;
public ApiDocs(Application app) {
this.app = app;
}
public void run() throws Exception {
List<Map> serverList = new ArrayList<>();
Map<String, Map<String, Map<String, String>>> typesmap = new LinkedHashMap<>();
for (NodeServer node : app.servers) {
if (!(node instanceof NodeHttpServer)) continue;
final Map<String, Object> map = new LinkedHashMap<>();
serverList.add(map);
HttpServer server = node.getServer();
map.put("address", server.getSocketAddress());
List<Map<String, Object>> servletsList = new ArrayList<>();
map.put("servlets", servletsList);
for (HttpServlet servlet : server.getPrepareServlet().getServlets()) {
if (!(servlet instanceof HttpServlet)) continue;
WebServlet ws = servlet.getClass().getAnnotation(WebServlet.class);
if (ws == null) {
System.err.println(servlet + " not found @WebServlet");
continue;
}
final Map<String, Object> servletmap = new LinkedHashMap<>();
String prefix = _prefix(servlet);
String[] mappings = ws.value();
if (prefix != null && !prefix.isEmpty()) {
for (int i = 0; i < mappings.length; i++) {
mappings[i] = prefix + mappings[i];
}
}
servletmap.put("mappings", mappings);
servletmap.put("moduleid", ws.moduleid());
servletmap.put("name", ws.name());
servletmap.put("comment", ws.comment());
List<Map> actionsList = new ArrayList<>();
servletmap.put("actions", actionsList);
for (Method method : servlet.getClass().getMethods()) {
if (method.getParameterCount() != 2) continue;
WebAction action = method.getAnnotation(WebAction.class);
if (action == null) continue;
final Map<String, Object> actionmap = new LinkedHashMap<>();
actionmap.put("url", prefix + action.url());
actionmap.put("auth", method.getAnnotation(AuthIgnore.class) == null);
actionmap.put("actionid", action.actionid());
actionmap.put("comment", action.comment());
List<Map> paramsList = new ArrayList<>();
actionmap.put("params", paramsList);
for (WebParam param : method.getAnnotationsByType(WebParam.class)) {
final Map<String, Object> parammap = new LinkedHashMap<>();
final boolean isarray = param.type().isArray();
final Class ptype = isarray ? param.type().getComponentType() : param.type();
parammap.put("name", param.name());
parammap.put("radix", param.radix());
parammap.put("type", ptype.getName() + (isarray ? "[]" : ""));
parammap.put("src", param.src());
parammap.put("comment", param.comment());
paramsList.add(parammap);
if (ptype.isPrimitive() || ptype == String.class) continue;
if (typesmap.containsKey(ptype.getName())) continue;
final Map<String, Map<String, String>> typemap = new LinkedHashMap<>();
Class loop = ptype;
do {
if (loop == null || loop.isInterface()) break;
for (Field field : loop.getDeclaredFields()) {
if (Modifier.isFinal(field.getModifiers())) continue;
if (Modifier.isStatic(field.getModifiers())) continue;
Map<String, String> fieldmap = new LinkedHashMap<>();
fieldmap.put("type", field.getType().isArray() ? (field.getType().getComponentType().getName() + "[]") : field.getGenericType().getTypeName());
Comment comment = field.getAnnotation(Comment.class);
if (comment != null) {
fieldmap.put("comment", comment.value());
} else {
Column col = field.getAnnotation(Column.class);
if (col != null) fieldmap.put("comment", col.comment());
}
if (servlet.getClass().getAnnotation(Rest.RestDynamic.class) != null) {
if (field.getAnnotation(RestAddress.class) != null) continue;
}
typemap.put(field.getName(), fieldmap);
}
} while ((loop = loop.getSuperclass()) != Object.class);
typesmap.put(ptype.getName(), typemap);
}
actionmap.put("result", action.result());
actionsList.add(actionmap);
}
actionsList.sort((o1, o2) -> ((String) o1.get("url")).compareTo((String) o2.get("url")));
servletsList.add(servletmap);
}
servletsList.sort((o1, o2) -> {
String[] mappings1 = (String[]) o1.get("mappings");
String[] mappings2 = (String[]) o2.get("mappings");
return mappings1.length > 0 ? (mappings2.length > 0 ? mappings1[0].compareTo(mappings2[0]) : 1) : -1;
});
}
Map<String, Object> resultmap = new LinkedHashMap<>();
resultmap.put("servers", serverList);
resultmap.put("types", typesmap);
final String json = JsonConvert.root().convertTo(resultmap);
final FileOutputStream out = new FileOutputStream(new File(app.getHome(), "apidoc.json"));
out.write(json.getBytes("UTF-8"));
out.close();
File doctemplate = new File(app.getHome(), "conf/apidoc-template.html");
InputStream in = null;
if (doctemplate.isFile() && doctemplate.canRead()) {
in = new FileInputStream(doctemplate);
}
if (in == null) in = ApiDocs.class.getResourceAsStream("apidoc-template.html");
String content = Utility.read(in).replace("${content}", json);
in.close();
FileOutputStream outhtml = new FileOutputStream(new File(app.getHome(), "apidoc.html"));
outhtml.write(content.getBytes("UTF-8"));
outhtml.close();
}
@Override
public boolean authenticate(int moduleid, int actionid, HttpRequest request, HttpResponse response) throws IOException {
return true;
}
}

View File

@@ -6,6 +6,7 @@
package org.redkale.boot;
import java.io.*;
import java.lang.reflect.Modifier;
import java.net.*;
import java.nio.ByteBuffer;
import java.nio.channels.*;
@@ -33,9 +34,7 @@ import org.w3c.dom.*;
* <p>
* 进程启动类程序启动后读取application.xml,进行classpath扫描动态加载Service与Servlet 优先加载所有SNCP协议的服务 再加载其他协议服务, 最后进行Service、Servlet与其他资源之间的依赖注入。
* <p>
* <p>
* <p>
* 详情见: http://redkale.org
* 详情见: https://redkale.org
*
* @author zhangjx
*/
@@ -67,9 +66,7 @@ public final class Application {
final Map<InetSocketAddress, String> globalNodes = new HashMap<>();
final Map<String, Set<InetSocketAddress>> globalGroups = new HashMap<>();
final Map<String, String> globalGroupProtocols = new HashMap<>();
final Map<String, GroupInfo> globalGroups = new HashMap<>();
final InetAddress localAddress;
@@ -79,8 +76,6 @@ public final class Application {
final List<NodeServer> servers = new CopyOnWriteArrayList<>();
CountDownLatch servicecdl; //会出现两次赋值
final ObjectPool<ByteBuffer> transportBufferPool;
final ExecutorService transportExecutor;
@@ -89,6 +84,8 @@ public final class Application {
final ResourceFactory resourceFactory = ResourceFactory.root();
CountDownLatch servicecdl; //会出现两次赋值
//--------------------------------------------------------------------------------------------
private final boolean singletonrun;
@@ -333,15 +330,14 @@ public final class Application {
if (!"TCP".equalsIgnoreCase(protocol) && !"UDP".equalsIgnoreCase(protocol)) {
throw new RuntimeException("Not supported Transport Protocol " + conf.getValue("protocol"));
}
Set<InetSocketAddress> addrs = globalGroups.get(group);
if (addrs == null) {
addrs = new LinkedHashSet<>();
globalGroupProtocols.put(group, protocol);
globalGroups.put(group, addrs);
GroupInfo ginfo = globalGroups.get(group);
if (ginfo == null) {
ginfo = new GroupInfo(group, protocol, conf.getValue("kind", ""), new LinkedHashSet<>());
globalGroups.put(group, ginfo);
}
for (AnyValue node : conf.getAnyValues("node")) {
final InetSocketAddress addr = new InetSocketAddress(node.getValue("addr"), node.getIntValue("port"));
addrs.add(addr);
ginfo.addrs.add(addr);
String oldgroup = globalNodes.get(addr);
if (oldgroup != null) throw new RuntimeException(addr + " had one more group " + (globalNodes.get(addr)));
globalNodes.put(addr, group);
@@ -364,7 +360,7 @@ public final class Application {
final DatagramChannel channel = DatagramChannel.open();
channel.configureBlocking(true);
channel.socket().setSoTimeout(3000);
channel.bind(new InetSocketAddress(config.getValue("host", "127.0.0.1"), config.getIntValue("port")));
channel.bind(new InetSocketAddress("127.0.0.1", config.getIntValue("port")));
boolean loop = true;
ByteBuffer buffer = ByteBuffer.allocateDirect(1024);
while (loop) {
@@ -393,6 +389,19 @@ public final class Application {
buffer.flip();
channel.send(buffer, address);
}
} else if ("APIDOC".equalsIgnoreCase(new String(bytes))) {
try {
new ApiDocs(application).run();
buffer.clear();
buffer.put("APIDOC OK".getBytes());
buffer.flip();
channel.send(buffer, address);
} catch (Exception ex) {
buffer.clear();
buffer.put("APIDOC FAIL".getBytes());
buffer.flip();
channel.send(buffer, address);
}
}
}
} catch (Exception e) {
@@ -403,12 +412,12 @@ public final class Application {
}.start();
}
private void sendShutDown() throws Exception {
private void sendCommand(String command) throws Exception {
final DatagramChannel channel = DatagramChannel.open();
channel.configureBlocking(true);
channel.connect(new InetSocketAddress(config.getValue("host", "127.0.0.1"), config.getIntValue("port")));
channel.connect(new InetSocketAddress("127.0.0.1", config.getIntValue("port")));
ByteBuffer buffer = ByteBuffer.allocate(128);
buffer.put("SHUTDOWN".getBytes());
buffer.put(command.getBytes());
buffer.flip();
channel.write(buffer);
buffer.clear();
@@ -466,15 +475,15 @@ public final class Application {
final String protocol = serconf.getValue("protocol", "").replaceFirst("\\..+", "").toUpperCase();
NodeServer server = null;
if ("SNCP".equals(protocol)) {
server = new NodeSncpServer(Application.this, serconf);
} else if ("HTTP".equals(protocol)) {
server = NodeSncpServer.createNodeServer(Application.this, serconf);
} else if ("HTTP".equalsIgnoreCase(protocol)) {
server = new NodeHttpServer(Application.this, serconf);
} else {
if (!inited.get()) {
synchronized (nodeClasses) {
if (!inited.getAndSet(true)) { //加载自定义的协议SOCKS
ClassFilter profilter = new ClassFilter(NodeProtocol.class, NodeServer.class);
ClassFilter.Loader.load(home, profilter);
ClassFilter.Loader.load(home, serconf.getValue("excludelibs", "").split(";"), profilter);
final Set<FilterEntry<NodeServer>> entrys = profilter.getFilterEntrys();
for (FilterEntry<NodeServer> entry : entrys) {
final Class<? extends NodeServer> type = entry.getType();
@@ -518,6 +527,7 @@ public final class Application {
}
public static <T extends Service> T singleton(String name, Class<T> serviceClass) throws Exception {
if (serviceClass == null) throw new IllegalArgumentException("serviceClass is null");
final Application application = Application.create(true);
application.init();
application.start();
@@ -525,7 +535,9 @@ public final class Application {
T service = server.resourceFactory.find(name, serviceClass);
if (service != null) return service;
}
return null;
if (Modifier.isAbstract(serviceClass.getModifiers())) throw new IllegalArgumentException("abstract class not allowed");
if (serviceClass.isInterface()) throw new IllegalArgumentException("interface class not allowed");
throw new IllegalArgumentException(serviceClass.getName() + " maybe have zero not-final public method");
}
public static Application create(final boolean singleton) throws IOException {
@@ -539,8 +551,11 @@ public final class Application {
Utility.midnight(); //先初始化一下Utility
//运行主程序
final Application application = Application.create(false);
if (System.getProperty("SHUTDOWN") != null) {
application.sendShutDown();
if (System.getProperty("CMD") != null) {
application.sendCommand(System.getProperty("CMD"));
return;
} else if (System.getProperty("SHUTDOWN") != null) { //兼容旧接口
application.sendCommand("SHUTDOWN");
return;
}
application.init();
@@ -574,15 +589,9 @@ public final class Application {
return null;
}
String findGroupProtocol(String group) {
GroupInfo findGroupInfo(String group) {
if (group == null) return null;
return globalGroupProtocols.get(group);
}
Set<InetSocketAddress> findGlobalGroup(String group) {
if (group == null) return null;
Set<InetSocketAddress> set = globalGroups.get(group);
return set == null ? null : new LinkedHashSet<>(set);
return globalGroups.get(group);
}
private void shutdown() throws Exception {

View File

@@ -14,15 +14,13 @@ import java.util.concurrent.*;
import java.util.jar.*;
import java.util.logging.*;
import java.util.regex.*;
import org.redkale.util.AnyValue;
import org.redkale.util.*;
import org.redkale.util.AnyValue.DefaultAnyValue;
import org.redkale.util.AutoLoad;
/**
* class过滤器 符合条件的class会保留下来存入FilterEntry。
*
* <p>
* 详情见: http://redkale.org
* 详情见: https://redkale.org
*
* @author zhangjx
* @param <T> 泛型
@@ -30,23 +28,33 @@ import org.redkale.util.AutoLoad;
@SuppressWarnings("unchecked")
public final class ClassFilter<T> {
private final Set<FilterEntry<T>> entrys = new HashSet<>();
private static final Logger logger = Logger.getLogger(ClassFilter.class.getName());
private boolean refused;
private static final boolean finer = logger.isLoggable(Level.FINER);
private Class superClass;
private final Set<FilterEntry<T>> entrys = new HashSet<>(); //符合条件的结果
private Class<? extends Annotation> annotationClass;
private final Set<FilterEntry<T>> expectEntrys = new HashSet<>(); //准备符合条件的结果
private Pattern[] includePatterns;
private boolean refused; //是否拒绝所有数据,设置true则其他规则失效,都是拒绝.
private Pattern[] excludePatterns;
private Class superClass; //符合的父类型。不为空时扫描结果的class必须是superClass的子类
private List<ClassFilter> ors;
private Class<? extends Annotation> annotationClass;//符合的注解。不为空时扫描结果的class必须包含该注解
private List<ClassFilter> ands;
private Pattern[] includePatterns; //符合的classname正则表达式
private AnyValue conf;
private Pattern[] excludePatterns;//拒绝的classname正则表达式
private Set<String> privilegeIncludes; //特批符合条件的classname
private Set<String> privilegeExcludes;//特批拒绝条件的classname
private List<ClassFilter> ors; //或关系的其他ClassFilter
private List<ClassFilter> ands;//与关系的其他ClassFilter
private AnyValue conf; //基本配置信息, 当符合条件时将conf的属性赋值到FilterEntry中去。
public ClassFilter(Class<? extends Annotation> annotationClass, Class superClass) {
this(annotationClass, superClass, null);
@@ -58,6 +66,15 @@ public final class ClassFilter<T> {
this.conf = conf;
}
public static ClassFilter create(String includeregs, String excluderegs, Set<String> includeValues, Set<String> excludeValues) {
ClassFilter filter = new ClassFilter(null, null);
filter.setIncludePatterns(includeregs == null ? null : includeregs.split(";"));
filter.setExcludePatterns(excluderegs == null ? null : excluderegs.split(";"));
filter.setPrivilegeIncludes(includeValues);
filter.setPrivilegeExcludes(excludeValues);
return filter;
}
public ClassFilter<T> or(ClassFilter<T> filter) {
if (ors == null) ors = new ArrayList<>();
ors.add(filter);
@@ -79,10 +96,31 @@ public final class ClassFilter<T> {
return entrys;
}
/**
* 获取预留的class集合
*
* @return Set&lt;FilterEntry&lt;T&gt;&gt;
*/
public final Set<FilterEntry<T>> getFilterExpectEntrys() {
return expectEntrys;
}
/**
* 获取所有的class集合
*
* @return Set&lt;FilterEntry&lt;T&gt;&gt;
*/
public final Set<FilterEntry<T>> getAllFilterEntrys() {
HashSet<FilterEntry<T>> rs = new HashSet<>();
rs.addAll(entrys);
rs.addAll(expectEntrys);
return rs;
}
/**
* 自动扫描地过滤指定的class
*
* @param property AnyValue
* @param property AnyValue
* @param clazzname String
*/
@SuppressWarnings("unchecked")
@@ -93,9 +131,9 @@ public final class ClassFilter<T> {
/**
* 过滤指定的class
*
* @param property application.xml中对应class节点下的property属性项
* @param property application.xml中对应class节点下的property属性项
* @param clazzname class名称
* @param autoscan 为true表示自动扫描的 false表示显著调用filter AutoLoad的注解将被忽略
* @param autoscan 为true表示自动扫描的 false表示显著调用filter AutoLoad的注解将被忽略
*/
public final void filter(AnyValue property, String clazzname, boolean autoscan) {
boolean r = accept0(property, clazzname);
@@ -113,7 +151,7 @@ public final class ClassFilter<T> {
}
}
}
if (cf == null) return;
if (cf == null || clazzname.startsWith("sun.")) return;
try {
Class clazz = Class.forName(clazzname);
if (!cf.accept(property, clazz, autoscan)) return;
@@ -129,31 +167,38 @@ public final class ClassFilter<T> {
property = dav;
}
}
entrys.add(new FilterEntry(clazz, autoscan, property));
} catch (Throwable cfe) {
}
}
private static Pattern[] toPattern(String[] regs) {
if (regs == null) return null;
int i = 0;
Pattern[] rs = new Pattern[regs.length];
for (String reg : regs) {
if (reg == null || reg.trim().isEmpty()) continue;
rs[i++] = Pattern.compile(reg.trim());
AutoLoad auto = (AutoLoad) clazz.getAnnotation(AutoLoad.class);
if (autoscan && auto != null && !auto.value()) { //自动扫描且被标记为@AutoLoad(false)的
expectEntrys.add(new FilterEntry(clazz, autoscan, true, property));
} else {
entrys.add(new FilterEntry(clazz, autoscan, false, property));
}
} catch (Throwable cfe) {
if (finer && !clazzname.startsWith("sun.") && !clazzname.startsWith("javax.")
&& !clazzname.startsWith("com.sun.") && !clazzname.startsWith("jdk.")) {
//logger.log(Level.FINEST, ClassFilter.class.getSimpleName() + " filter error", cfe);
}
}
if (i == 0) return null;
if (i == rs.length) return rs;
Pattern[] ps = new Pattern[i];
System.arraycopy(rs, 0, ps, 0, i);
return ps;
}
/**
* 判断class是否有效
*
* @param property AnyValue
* @param classname String
*
* @return boolean
*/
public boolean accept(String classname) {
return accept(null, classname);
}
/**
* 判断class是否有效
*
* @param property AnyValue
* @param classname String
*
* @return boolean
*/
public boolean accept(AnyValue property, String classname) {
@@ -173,6 +218,8 @@ public final class ClassFilter<T> {
private boolean accept0(AnyValue property, String classname) {
if (this.refused) return false;
if (this.privilegeIncludes != null && this.privilegeIncludes.contains(classname)) return true;
if (this.privilegeExcludes != null && this.privilegeExcludes.contains(classname)) return false;
if (classname.startsWith("java.") || classname.startsWith("javax.")) return false;
if (excludePatterns != null) {
for (Pattern reg : excludePatterns) {
@@ -191,21 +238,33 @@ public final class ClassFilter<T> {
* 判断class是否有效
*
* @param property AnyValue
* @param clazz Class
* @param clazz Class
* @param autoscan boolean
*
* @return boolean
*/
@SuppressWarnings("unchecked")
public boolean accept(AnyValue property, Class clazz, boolean autoscan) {
if (this.refused || !Modifier.isPublic(clazz.getModifiers())) return false;
if (autoscan) {
AutoLoad auto = (AutoLoad) clazz.getAnnotation(AutoLoad.class);
if (auto != null && !auto.value()) return false;
}
if (annotationClass != null && clazz.getAnnotation(annotationClass) == null) return false;
return superClass == null || (clazz != superClass && superClass.isAssignableFrom(clazz));
}
public static Pattern[] toPattern(String[] regs) {
if (regs == null || regs.length == 0) return null;
int i = 0;
Pattern[] rs = new Pattern[regs.length];
for (String reg : regs) {
if (reg == null || reg.trim().isEmpty()) continue;
rs[i++] = Pattern.compile(reg.trim());
}
if (i == 0) return null;
if (i == rs.length) return rs;
Pattern[] ps = new Pattern[i];
System.arraycopy(rs, 0, ps, 0, i);
return ps;
}
public void setSuperClass(Class superClass) {
this.superClass = superClass;
}
@@ -246,6 +305,22 @@ public final class ClassFilter<T> {
this.refused = refused;
}
public Set<String> getPrivilegeIncludes() {
return privilegeIncludes;
}
public void setPrivilegeIncludes(Set<String> privilegeIncludes) {
this.privilegeIncludes = privilegeIncludes == null || privilegeIncludes.isEmpty() ? null : privilegeIncludes;
}
public Set<String> getPrivilegeExcludes() {
return privilegeExcludes;
}
public void setPrivilegeExcludes(Set<String> privilegeExcludes) {
this.privilegeExcludes = privilegeExcludes == null || privilegeExcludes.isEmpty() ? null : privilegeExcludes;
}
/**
* 存放符合条件的class与class指定的属性项
*
@@ -263,11 +338,13 @@ public final class ClassFilter<T> {
private final boolean autoload;
private final boolean expect;
public FilterEntry(Class<T> type, AnyValue property) {
this(type, false, property);
this(type, false, false, property);
}
public FilterEntry(Class<T> type, final boolean autoload, AnyValue property) {
public FilterEntry(Class<T> type, final boolean autoload, boolean expect, AnyValue property) {
this.type = type;
String str = property == null ? null : property.getValue("groups");
if (str != null) {
@@ -277,6 +354,7 @@ public final class ClassFilter<T> {
if (str != null) groups.addAll(Arrays.asList(str.split(";")));
this.property = property;
this.autoload = autoload;
this.expect = expect;
this.name = property == null ? "" : property.getValue("name", "");
}
@@ -322,6 +400,9 @@ public final class ClassFilter<T> {
return autoload;
}
public boolean isExpect() {
return expect;
}
}
/**
@@ -340,17 +421,30 @@ public final class ClassFilter<T> {
/**
* 加载当前线程的classpath扫描所有class进行过滤
*
* @param exclude 不需要扫描的文件夹, 可以为null
* @param filters 过滤器
* @param excludeFile 不需要扫描的文件夹, 可以为null
* @param excludeRegs 包含此关键字的文件将被跳过, 可以为null
* @param filters 过滤器
*
* @throws IOException 异常
*/
public static void load(final File exclude, final ClassFilter... filters) throws IOException {
public static void load(final File excludeFile, final String[] excludeRegs, final ClassFilter... filters) throws IOException {
URLClassLoader loader = (URLClassLoader) Thread.currentThread().getContextClassLoader();
List<URL> urlfiles = new ArrayList<>(2);
List<URL> urljares = new ArrayList<>(2);
final URL exurl = exclude != null ? exclude.toURI().toURL() : null;
final URL exurl = excludeFile != null ? excludeFile.toURI().toURL() : null;
final Pattern[] excludePatterns = toPattern(excludeRegs);
for (URL url : loader.getURLs()) {
if (exurl != null && exurl.sameFile(url)) continue;
if (excludePatterns != null) {
boolean skip = false;
for (Pattern p : excludePatterns) {
if (p.matcher(url.toString()).matches()) {
skip = false;
break;
}
}
if (skip) continue;
}
if (url.getPath().endsWith(".jar")) {
urljares.add(url);
} else {
@@ -395,7 +489,7 @@ public final class ClassFilter<T> {
files.clear();
File root = new File(url.getFile());
String rootpath = root.getPath();
loadClassFiles(exclude, root, files);
loadClassFiles(excludeFile, root, files);
for (File f : files) {
String classname = f.getPath().substring(rootpath.length() + 1, f.getPath().length() - 6).replace(File.separatorChar, '.');
if (classname.startsWith("javax.") || classname.startsWith("com.sun.")) continue;

View File

@@ -0,0 +1,74 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.redkale.boot;
import java.net.InetSocketAddress;
import java.util.*;
/**
*
* <p>
* 详情见: https://redkale.org
*
* @author zhangjx
*/
public class GroupInfo {
protected String name;
protected String protocol;
protected String kind;
protected Set<InetSocketAddress> addrs;
public GroupInfo() {
}
public GroupInfo(String name, String protocol, String kind, Set<InetSocketAddress> addrs) {
this.name = name;
this.protocol = protocol;
this.kind = kind;
this.addrs = addrs;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getProtocol() {
return protocol;
}
public void setProtocol(String protocol) {
this.protocol = protocol;
}
public String getKind() {
return kind;
}
public void setKind(String kind) {
this.kind = kind;
}
public Set<InetSocketAddress> getAddrs() {
return addrs;
}
public Set<InetSocketAddress> copyAddrs() {
return addrs == null ? null : new LinkedHashSet<>(addrs);
}
public void setAddrs(Set<InetSocketAddress> addrs) {
this.addrs = addrs;
}
}

View File

@@ -18,7 +18,7 @@ import java.util.logging.Formatter;
/**
* 自定义的日志输出类
* <p>
* 详情见: http://redkale.org
* 详情见: https://redkale.org
*
* @author zhangjx
*/

View File

@@ -22,18 +22,21 @@ import org.redkale.util.*;
* HTTP Server节点的配置Server
*
* <p>
* 详情见: http://redkale.org
* 详情见: https://redkale.org
*
* @author zhangjx
*/
@NodeProtocol({"HTTP"})
public final class NodeHttpServer extends NodeServer {
public class NodeHttpServer extends NodeServer {
private final HttpServer httpServer;
protected final boolean rest;
protected final HttpServer httpServer;
public NodeHttpServer(Application application, AnyValue serconf) {
super(application, createServer(application, serconf));
this.httpServer = (HttpServer) server;
this.rest = serconf == null ? false : serconf.getAnyValue("rest") != null;
}
private static Server createServer(Application application, AnyValue serconf) {
@@ -84,9 +87,9 @@ public final class NodeHttpServer extends NodeServer {
}, WebSocketNode.class);
}
protected void loadHttpServlet(final AnyValue conf, final ClassFilter<? extends Servlet> filter) throws Exception {
final StringBuilder sb = logger.isLoggable(Level.FINE) ? new StringBuilder() : null;
final String prefix = conf == null ? "" : conf.getValue("path", "");
protected void loadHttpServlet(final AnyValue servletsConf, final ClassFilter<? extends Servlet> filter) throws Exception {
final StringBuilder sb = logger.isLoggable(Level.INFO) ? new StringBuilder() : null;
final String prefix = servletsConf == null ? "" : servletsConf.getValue("path", "");
final String threadName = "[" + Thread.currentThread().getName() + "] ";
List<FilterEntry<? extends Servlet>> list = new ArrayList(filter.getFilterEntrys());
list.sort((FilterEntry<? extends Servlet> o1, FilterEntry<? extends Servlet> o2) -> { //必须保证WebSocketServlet优先加载 因为要确保其他的HttpServlet可以注入本地模式的WebSocketNode
@@ -121,7 +124,7 @@ public final class NodeHttpServer extends NodeServer {
ss.add(new AbstractMap.SimpleEntry<>(clazz.getName(), mappings));
}
}
if (ss != null) {
if (ss != null && sb != null) {
Collections.sort(ss, (AbstractMap.SimpleEntry<String, String[]> o1, AbstractMap.SimpleEntry<String, String[]> o2) -> o1.getKey().compareTo(o2.getKey()));
int max = 0;
for (AbstractMap.SimpleEntry<String, String[]> as : ss) {
@@ -135,7 +138,77 @@ public final class NodeHttpServer extends NodeServer {
sb.append(" mapping to ").append(Arrays.toString(as.getValue())).append(LINE_SEPARATOR);
}
}
if (sb != null && sb.length() > 0) logger.log(Level.FINE, sb.toString());
if (sb != null && sb.length() > 0) logger.log(Level.INFO, sb.toString());
if (rest && serverConf != null) {
for (AnyValue restConf : serverConf.getAnyValues("rest")) {
loadRestServlet(prefix, restConf);
}
}
}
protected void loadRestServlet(final String prefix, final AnyValue restConf) throws Exception {
if (!rest) return;
if (restConf == null) return; //不存在REST服务
final StringBuilder sb = logger.isLoggable(Level.INFO) ? new StringBuilder() : null;
final String threadName = "[" + Thread.currentThread().getName() + "] ";
final List<AbstractMap.SimpleEntry<String, String[]>> ss = sb == null ? null : new ArrayList<>();
final Class baseServletClass = Class.forName(restConf.getValue("base", DefaultRestServlet.class.getName()));
final boolean autoload = restConf.getBoolValue("autoload", true);
final boolean mustsign = restConf.getBoolValue("mustsign", true); //是否只加载标记@RestService的Service类
final Set<String> includeValues = new HashSet<>();
final Set<String> excludeValues = new HashSet<>();
for (AnyValue item : restConf.getAnyValues("service")) {
if (item.getBoolValue("ignore", false)) {
excludeValues.add(item.getValue("value", ""));
} else {
includeValues.add(item.getValue("value", ""));
}
}
final ClassFilter restFilter = ClassFilter.create(restConf.getValue("includes", ""), restConf.getValue("excludes", ""), includeValues, excludeValues);
super.interceptorServiceWrappers.forEach((wrapper) -> {
final Class stype = wrapper.getType();
RestService rs = (RestService) stype.getAnnotation(RestService.class);
if (rs != null && rs.ignore()) return;
if (mustsign && rs == null) return;
if (stype.getAnnotation(LocalService.class) != null && rs == null) return;
final String stypename = stype.getName();
if (!autoload && !includeValues.contains(stypename)) return;
if (!restFilter.accept(stypename)) return;
RestHttpServlet servlet = httpServer.addRestServlet(wrapper.getName(), stype, wrapper.getService(), baseServletClass, prefix, (AnyValue) null);
resourceFactory.inject(servlet, NodeHttpServer.this);
if (finest) logger.finest("Create RestServlet[resource=" + wrapper.getName() + "] = " + servlet);
if (ss != null) {
String[] mappings = servlet.getClass().getAnnotation(WebServlet.class).value();
for (int i = 0; i < mappings.length; i++) {
mappings[i] = prefix + mappings[i];
}
if (servlet.getClass().getSimpleName().charAt(0) != '_') {
ss.add(new AbstractMap.SimpleEntry<>(servlet.getClass().getName(), mappings));
}
}
});
//输出信息
if (ss != null && sb != null) {
Collections.sort(ss, (AbstractMap.SimpleEntry<String, String[]> o1, AbstractMap.SimpleEntry<String, String[]> o2) -> o1.getKey().compareTo(o2.getKey()));
int max = 0;
for (AbstractMap.SimpleEntry<String, String[]> as : ss) {
if (as.getKey().length() > max) max = as.getKey().length();
}
for (AbstractMap.SimpleEntry<String, String[]> as : ss) {
sb.append(threadName).append(" Loaded ").append(as.getKey());
for (int i = 0; i < max - as.getKey().length(); i++) {
sb.append(' ');
}
sb.append(" mapping to ").append(Arrays.toString(as.getValue())).append(LINE_SEPARATOR);
}
}
if (sb != null && sb.length() > 0) logger.log(Level.INFO, sb.toString());
}
}

View File

@@ -5,10 +5,13 @@
*/
package org.redkale.boot;
import java.util.Objects;
import org.redkale.service.Service;
/**
*
* <p>
* 详情见: http://redkale.org
* 详情见: https://redkale.org
*
* @author zhangjx
*/
@@ -21,4 +24,64 @@ public class NodeInterceptor {
public void preShutdown(NodeServer server) {
}
public static class InterceptorServiceWrapper<T extends Service> {
private String name;
private Class<T> type;
private T service;
public InterceptorServiceWrapper() {
}
public InterceptorServiceWrapper(String name, Class<T> type, T service) {
this.name = name;
this.type = type;
this.service = service;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Class<T> getType() {
return type;
}
public void setType(Class<T> type) {
this.type = type;
}
public T getService() {
return service;
}
public void setService(T service) {
this.service = service;
}
@Override
public int hashCode() {
int hash = 7;
hash = 97 * hash + Objects.hashCode(this.name);
hash = 97 * hash + Objects.hashCode(this.type);
return hash;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null) return false;
if (getClass() != obj.getClass()) return false;
final InterceptorServiceWrapper<?> other = (InterceptorServiceWrapper<?>) obj;
return Objects.equals(this.name, other.name) && Objects.equals(this.type, other.type);
}
}
}

View File

@@ -11,7 +11,7 @@ import java.lang.annotation.*;
* 根据application.xml中的server节点中的protocol值来适配Server的加载逻辑
*
* <p>
* 详情见: http://redkale.org
* 详情见: https://redkale.org
*
* @author zhangjx
*/

View File

@@ -6,14 +6,13 @@
package org.redkale.boot;
import java.io.*;
import static java.lang.Class.forName;
import java.lang.annotation.Annotation;
import java.lang.reflect.*;
import java.net.InetSocketAddress;
import java.nio.file.Path;
import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.function.Consumer;
import java.util.concurrent.*;
import java.util.function.*;
import java.util.logging.*;
import java.util.stream.Collectors;
import javax.annotation.Resource;
@@ -21,6 +20,7 @@ import javax.persistence.Transient;
import static org.redkale.boot.Application.*;
import org.redkale.boot.ClassFilter.FilterEntry;
import org.redkale.net.*;
import org.redkale.net.http.WebSocketNode;
import org.redkale.net.sncp.*;
import org.redkale.service.*;
import org.redkale.source.*;
@@ -29,9 +29,9 @@ import org.redkale.util.*;
/**
* Server节点的初始化配置类
* <p>
* <p>
* 详情见: http://redkale.org
*
*
* 详情见: https://redkale.org
*
* @author zhangjx
*/
@@ -47,9 +47,12 @@ public abstract class NodeServer {
//日志是否为FINE级别
protected final boolean fine;
//日志是否为FINE级别
//日志是否为FINER级别
protected final boolean finer;
//日志是否为FINEST级别
protected final boolean finest;
//进程主类
protected final Application application;
@@ -74,6 +77,9 @@ public abstract class NodeServer {
//加载server节点后的拦截器
protected NodeInterceptor interceptor;
//供interceptor使用的Service对象集合
protected final Set<NodeInterceptor.InterceptorServiceWrapper> interceptorServiceWrappers = new LinkedHashSet<>();
//本地模式的Service对象集合
protected final Set<ServiceWrapper> localServiceWrappers = new LinkedHashSet<>();
@@ -87,6 +93,7 @@ public abstract class NodeServer {
this.logger = Logger.getLogger(this.getClass().getSimpleName());
this.fine = logger.isLoggable(Level.FINE);
this.finer = logger.isLoggable(Level.FINER);
this.finest = logger.isLoggable(Level.FINEST);
}
protected Consumer<Runnable> getExecutor() throws Exception {
@@ -106,7 +113,11 @@ public abstract class NodeServer {
logger.log(Level.SEVERE, "Server (" + server.getSocketAddress() + ") cannot find Context", e);
}
}
context.submit(t);
if (context == null) {
t.run();
} else {
context.submit(t);
}
}
};
@@ -134,7 +145,7 @@ public abstract class NodeServer {
if (this.sncpGroup != null) this.resourceFactory.register(RESNAME_SERVER_GROUP, this.sncpGroup);
{
//设置root文件夹
String webroot = config.getValue("root", "root");
String webroot = this.serverConf.getValue("root", "root");
File myroot = new File(webroot);
if (!webroot.contains(":") && !webroot.startsWith("/")) {
myroot = new File(System.getProperty(Application.RESNAME_APP_HOME), webroot);
@@ -146,15 +157,15 @@ public abstract class NodeServer {
final String homepath = myroot.getCanonicalPath();
//加入指定的classpath
Server.loadLib(logger, config.getValue("lib", "").replace("${APP_HOME}", homepath) + ";" + homepath + "/lib/*;" + homepath + "/classes");
Server.loadLib(logger, this.serverConf.getValue("lib", "").replace("${APP_HOME}", homepath) + ";" + homepath + "/lib/*;" + homepath + "/classes");
}
//必须要进行初始化, 构建Service时需要使用Context中的ExecutorService
server.init(config);
server.init(this.serverConf);
initResource(); //给 DataSource、CacheSource 注册依赖注入时的监听回调事件。
String interceptorClass = config.getValue("nodeInterceptor", "");
String interceptorClass = this.serverConf.getValue("interceptor", "");
if (!interceptorClass.isEmpty()) {
Class clazz = forName(interceptorClass);
Class clazz = Class.forName(interceptorClass);
this.interceptor = (NodeInterceptor) clazz.newInstance();
}
@@ -162,9 +173,9 @@ public abstract class NodeServer {
ClassFilter<Service> serviceFilter = createServiceClassFilter();
long s = System.currentTimeMillis();
if (servletFilter == null) {
ClassFilter.Loader.load(application.getHome(), serviceFilter);
ClassFilter.Loader.load(application.getHome(), serverConf.getValue("excludelibs", "").split(";"), serviceFilter);
} else {
ClassFilter.Loader.load(application.getHome(), serviceFilter, servletFilter);
ClassFilter.Loader.load(application.getHome(), serverConf.getValue("excludelibs", "").split(";"), serviceFilter, servletFilter);
}
long e = System.currentTimeMillis() - s;
logger.info(this.getClass().getSimpleName() + " load filter class in " + e + " ms");
@@ -201,7 +212,7 @@ public abstract class NodeServer {
localServiceWrappers.add(wrapper);
sncpServer.consumerAccept(wrapper);
rf.inject(cacheListenerService, self);
if (fine) logger.fine("[" + Thread.currentThread().getName() + "] Load Service " + wrapper.getService());
logger.info("[" + Thread.currentThread().getName() + "] Load Service " + wrapper.getService());
}
field.set(src, source);
rf.inject(source, self); // 给 "datasource.nodeid" 赋值;
@@ -226,6 +237,7 @@ public abstract class NodeServer {
source.setStoreType(pt == null ? Serializable.class : (Class) pt.getActualTypeArguments()[0], valType instanceof Class ? (Class) valType : Object.class);
if (field.getAnnotation(Transient.class) != null) source.setNeedStore(false); //必须在setStoreType之后
application.cacheSources.add(source);
appResFactory.register(resourceName, genericType, source);
appResFactory.register(resourceName, CacheSource.class, source);
field.set(src, source);
rf.inject(source, self); //
@@ -235,10 +247,10 @@ public abstract class NodeServer {
NodeSncpServer sncpServer = application.findNodeSncpServer(sncpAddr);
Set<String> gs = application.findSncpGroups(sameGroupTransport, diffGroupTransports);
ServiceWrapper wrapper = new ServiceWrapper(CacheSourceService.class, (Service) source, resourceName, sncpServer.getSncpGroup(), gs, null);
sncpServer.getSncpServer().addService(wrapper);
if (finer) logger.finer("[" + Thread.currentThread().getName() + "] Load Service " + wrapper.getService());
sncpServer.getSncpServer().addSncpServlet(wrapper);
logger.info("[" + Thread.currentThread().getName() + "] Load Service " + wrapper.getService());
}
logger.finer("[" + Thread.currentThread().getName() + "] Load Source " + source);
logger.info("[" + Thread.currentThread().getName() + "] Load Source " + source);
} catch (Exception e) {
logger.log(Level.SEVERE, "DataSource inject error", e);
}
@@ -249,15 +261,26 @@ public abstract class NodeServer {
protected void loadService(ClassFilter serviceFilter) throws Exception {
if (serviceFilter == null) return;
final String threadName = "[" + Thread.currentThread().getName() + "] ";
final Set<FilterEntry<Service>> entrys = serviceFilter.getFilterEntrys();
final Set<FilterEntry<Service>> entrys = serviceFilter.getAllFilterEntrys();
ResourceFactory regFactory = isSNCP() ? application.getResourceFactory() : resourceFactory;
for (FilterEntry<Service> entry : entrys) { //service实现类
final Class<? extends Service> type = entry.getType();
if (Modifier.isFinal(type.getModifiers())) continue; //修饰final的类跳过
if (!Modifier.isPublic(type.getModifiers())) continue;
if (entry.isExpect()) {
if (Modifier.isAbstract(type.getModifiers())) continue; //修饰abstract的类跳过
if (DataSource.class.isAssignableFrom(type)) continue;
if (CacheSource.class.isAssignableFrom(type)) continue;
if (DataCacheListener.class.isAssignableFrom(type)) continue;
if (WebSocketNode.class.isAssignableFrom(type)) continue;
}
if (entry.getName().contains("$")) throw new RuntimeException("<name> value cannot contains '$' in " + entry.getProperty());
if (resourceFactory.find(entry.getName(), type) != null) continue; //Server加载Service时需要判断是否已经加载过了。
if (resourceFactory.find(entry.getName(), type) != null) { //Server加载Service时需要判断是否已经加载过了。
Service oldother = resourceFactory.find(entry.getName(), type);
interceptorServiceWrappers.add(new NodeInterceptor.InterceptorServiceWrapper(entry.getName(), type, oldother));
continue;
}
final HashSet<String> groups = entry.getGroups(); //groups.isEmpty()表示<services>没有配置groups属性。
if (groups.isEmpty() && isSNCP() && this.sncpGroup != null) groups.add(this.sncpGroup);
@@ -266,29 +289,51 @@ public abstract class NodeServer {
|| (this.sncpGroup == null && entry.isEmptyGroups()) //空的SNCP配置
|| type.getAnnotation(LocalService.class) != null;//本地模式
if (localed && (type.isInterface() || Modifier.isAbstract(type.getModifiers()))) continue; //本地模式不能实例化接口和抽象类的Service类
Service service;
if (localed) { //本地模式
service = Sncp.createLocalService(entry.getName(), getExecutor(), application.getResourceFactory(), type, this.sncpAddress, loadTransport(this.sncpGroup), loadTransports(groups));
} else {
service = Sncp.createRemoteService(entry.getName(), getExecutor(), type, this.sncpAddress, loadTransport(groups));
}
if (SncpClient.parseMethod(type).isEmpty()) continue; //class没有可用的方法 通常为BaseService
final ServiceWrapper wrapper = new ServiceWrapper(type, service, entry.getName(), localed ? this.sncpGroup : null, groups, entry.getProperty());
for (final Class restype : wrapper.getTypes()) {
if (resourceFactory.find(wrapper.getName(), restype) == null) {
regFactory.register(wrapper.getName(), restype, wrapper.getService());
} else if (isSNCP() && !entry.isAutoload()) {
throw new RuntimeException(ServiceWrapper.class.getSimpleName() + "(class:" + type.getName() + ", name:" + entry.getName() + ", group:" + groups + ") is repeat.");
final BiConsumer<ResourceFactory, Boolean> runner = (ResourceFactory rf, Boolean needinject) -> {
try {
Service service;
if (localed) { //本地模式
service = Sncp.createLocalService(entry.getName(), getExecutor(), application.getResourceFactory(), type,
NodeServer.this.sncpAddress, loadTransport(NodeServer.this.sncpGroup), loadTransports(groups));
} else {
service = Sncp.createRemoteService(entry.getName(), getExecutor(), type, NodeServer.this.sncpAddress, loadTransport(groups));
}
if (SncpClient.parseMethod(type).isEmpty()) return; //class没有可用的方法 通常为BaseService
final ServiceWrapper wrapper = new ServiceWrapper(type, service, entry.getName(), localed ? NodeServer.this.sncpGroup : null, groups, entry.getProperty());
for (final Class restype : wrapper.getTypes()) {
if (resourceFactory.find(wrapper.getName(), restype) == null) {
regFactory.register(wrapper.getName(), restype, wrapper.getService());
if (needinject) rf.inject(wrapper.getService()); //动态加载的Service也存在按需加载的注入资源
} else if (isSNCP() && !entry.isAutoload()) {
throw new RuntimeException(ServiceWrapper.class.getSimpleName() + "(class:" + type.getName() + ", name:" + entry.getName() + ", group:" + groups + ") is repeat.");
}
}
if (wrapper.isRemote()) {
remoteServiceWrappers.add(wrapper);
} else {
localServiceWrappers.add(wrapper);
interceptorServiceWrappers.add(new NodeInterceptor.InterceptorServiceWrapper(entry.getName(), type, service));
if (consumer != null) consumer.accept(wrapper);
}
} catch (RuntimeException ex) {
throw ex;
} catch (Exception e) {
throw new RuntimeException(e);
}
};
if (entry.isExpect()) {
ResourceFactory.ResourceLoader resourceLoader = (ResourceFactory rf, final Object src, final String resourceName, Field field, final Object attachment) -> {
runner.accept(rf, true);
};
for (final Class restype : ServiceWrapper.parseTypes(entry.getType())) {
resourceFactory.register(resourceLoader, restype);
}
}
if (wrapper.isRemote()) {
remoteServiceWrappers.add(wrapper);
} else {
localServiceWrappers.add(wrapper);
if (consumer != null) consumer.accept(wrapper);
runner.accept(resourceFactory, false);
}
}
application.servicecdl.countDown();
application.servicecdl.await();
@@ -297,27 +342,36 @@ public abstract class NodeServer {
new ArrayList<>(localServiceWrappers).forEach(y -> {
resourceFactory.inject(y.getService(), NodeServer.this);
});
remoteServiceWrappers.forEach(y -> {
new ArrayList<>(remoteServiceWrappers).forEach(y -> {
resourceFactory.inject(y.getService(), NodeServer.this);
if (sb != null) {
sb.append(threadName).append(y.toSimpleString()).append(" loaded and injected").append(LINE_SEPARATOR);
}
});
if (sb != null) {
remoteServiceWrappers.forEach(y -> {
sb.append(threadName).append(y.toSimpleString()).append(" loaded and injected").append(LINE_SEPARATOR);
});
}
//----------------- init -----------------
List<ServiceWrapper> swlist = new ArrayList<>(localServiceWrappers);
Collections.sort(swlist);
localServiceWrappers.clear();
localServiceWrappers.addAll(swlist);
final List<String> slist = sb == null ? null : new CopyOnWriteArrayList<>();
CountDownLatch clds = new CountDownLatch(localServiceWrappers.size());
localServiceWrappers.parallelStream().forEach(y -> {
long s = System.currentTimeMillis();
y.getService().init(y.getConf());
long e = System.currentTimeMillis() - s;
if (slist != null) slist.add(new StringBuilder().append(threadName).append(y.toSimpleString()).append(" loaded and init ").append(e).append(" ms").append(LINE_SEPARATOR).toString());
try {
long s = System.currentTimeMillis();
y.getService().init(y.getConf());
long e = System.currentTimeMillis() - s;
if (slist != null) slist.add(new StringBuilder().append(threadName).append(y.toSimpleString()).append(" loaded and inited ").append(e).append(" ms").append(LINE_SEPARATOR).toString());
} finally {
clds.countDown();
}
});
Collections.sort(slist);
clds.await();
if (slist != null && sb != null) {
for (String s : slist) {
List<String> wlist = new ArrayList<>(slist); //直接使用CopyOnWriteArrayList偶尔会出现莫名的异常(CopyOnWriteArrayList源码1185行)
Collections.sort(wlist);
for (String s : wlist) {
sb.append(s);
}
}
@@ -347,8 +401,9 @@ public abstract class NodeServer {
Set<InetSocketAddress> addrs = new HashSet();
transports.forEach(t -> addrs.addAll(Arrays.asList(t.getRemoteAddresses())));
Transport first = transports.get(0);
Transport newTransport = new Transport(groupid, application.findGroupProtocol(first.getName()), application.getWatchFactory(),
application.transportBufferPool, application.transportChannelGroup, this.sncpAddress, addrs);
GroupInfo ginfo = application.findGroupInfo(first.getName());
Transport newTransport = new Transport(groupid, ginfo.getProtocol(), application.getWatchFactory(),
ginfo.getKind(), application.transportBufferPool, application.transportChannelGroup, this.sncpAddress, addrs);
synchronized (application.resourceFactory) {
transport = application.resourceFactory.find(groupid, Transport.class);
if (transport == null) {
@@ -370,10 +425,11 @@ public abstract class NodeServer {
}
return transport;
}
Set<InetSocketAddress> addrs = application.findGlobalGroup(group);
GroupInfo ginfo = application.findGroupInfo(group);
Set<InetSocketAddress> addrs = ginfo.copyAddrs();
if (addrs == null) throw new RuntimeException("Not found <group> = " + group + " on <resources> ");
transport = new Transport(group, application.findGroupProtocol(group), application.getWatchFactory(),
application.transportBufferPool, application.transportChannelGroup, this.sncpAddress, addrs);
transport = new Transport(group, ginfo.getProtocol(), application.getWatchFactory(),
ginfo.getKind(), application.transportBufferPool, application.transportChannelGroup, this.sncpAddress, addrs);
application.resourceFactory.register(group, transport);
}
return transport;
@@ -406,19 +462,19 @@ public abstract class NodeServer {
prop.addValue("groups", sc);
}
ClassFilter filter = new ClassFilter(ref, inter, prop);
for (AnyValue av : list.getAnyValues(property)) {
for (AnyValue av : list.getAnyValues(property)) { // <service> 或 <servlet> 节点
final AnyValue[] items = av.getAnyValues("property");
if (av instanceof DefaultAnyValue && items.length > 0) {
if (av instanceof DefaultAnyValue && items.length > 0) { //存在 <property>节点
DefaultAnyValue dav = DefaultAnyValue.create();
final AnyValue.Entry<String>[] strings = av.getStringEntrys();
if (strings != null) {
if (strings != null) { //将<service>或<servlet>节点的属性值传给dav
for (AnyValue.Entry<String> en : strings) {
dav.addValue(en.name, en.getValue());
}
}
final AnyValue.Entry<AnyValue>[] anys = av.getAnyEntrys();
if (anys != null) {
for (AnyValue.Entry<AnyValue> en : anys) {
for (AnyValue.Entry<AnyValue> en : anys) { //将<service>或<servlet>节点的非property属性节点传给dav
if (!"property".equals(en.name)) dav.addValue(en.name, en.getValue());
}
}
@@ -426,7 +482,7 @@ public abstract class NodeServer {
for (AnyValue item : items) {
ps.addValue(item.getValue("name"), item.getValue("value"));
}
dav.addValue("property", ps);
dav.addValue("properties", ps);
av = dav;
}
filter.filter(av, av.getValue("value"), false);
@@ -460,6 +516,10 @@ public abstract class NodeServer {
return serverConf;
}
public Logger getLogger() {
return logger;
}
public String getSncpGroup() {
return sncpGroup;
}
@@ -488,6 +548,10 @@ public abstract class NodeServer {
return (T) server;
}
public Set<NodeInterceptor.InterceptorServiceWrapper> getInterceptorServiceWrappers() {
return new LinkedHashSet<>(interceptorServiceWrappers);
}
public Set<ServiceWrapper> getLocalServiceWrappers() {
return new LinkedHashSet<>(localServiceWrappers);
}

View File

@@ -15,19 +15,27 @@ import org.redkale.util.*;
/**
*
* <p>
* 详情见: http://redkale.org
* 详情见: https://redkale.org
*
* @author zhangjx
*/
@NodeProtocol({"SNCP"})
public final class NodeSncpServer extends NodeServer {
public class NodeSncpServer extends NodeServer {
private final SncpServer sncpServer;
protected final SncpServer sncpServer;
public NodeSncpServer(Application application, AnyValue serconf) {
private NodeSncpServer(Application application, AnyValue serconf) {
super(application, createServer(application, serconf));
this.sncpServer = (SncpServer) this.server;
this.consumer = sncpServer == null ? null : x -> sncpServer.addService(x);
this.consumer = sncpServer == null ? null : x -> sncpServer.addSncpServlet(x);
}
public static NodeServer createNodeServer(Application application, AnyValue serconf) {
if (serconf != null && serconf.getAnyValue("rest") != null) {
((AnyValue.DefaultAnyValue) serconf).addValue("_$sncp", "true");
return new NodeHttpServer(application, serconf);
}
return new NodeSncpServer(application, serconf);
}
private static Server createServer(Application application, AnyValue serconf) {

View File

@@ -0,0 +1,85 @@
<!doctype html>
<html>
<head>
<meta charset="UTF-8"><title>Document</title>
<style type="text/css">
body {text-align: center;margin:auto;}
a{text-decoration: none;}
.table {margin: auto;border-collapse: collapse;border-spacing: 0;display: block;width: 100%;overflow: auto;word-break: normal;word-break: keep-all;}
.table td,.table th{padding: 0.4rem 1.2rem 0.4rem 1.2rem;border: 1px solid #aaa;}
.table td {text-align: left;}
.s {font-size: 0.8rem; vertical-align: middle;}
.subtable {border-spacing: 0;border: 0;margin:0;}
.subtable td{border: 0;padding: 0 0 0 10px;}
.typetable {border-spacing: 0;border: 0;margin:0;}
.typetable td{border: 0;padding: 2px 20px 2px 10px;}
.typetable .l{border-bottom: 1px solid red;}
</style>
</head>
<body>
<script>
var createhtml = function (jsoncontent) {
var classmap = jsoncontent.types;
var html = [];
html.push('<div style="width:' + Math.floor(window.screen.width * 0.9) + 'px;margin:0 auto;text-align: center;">');
html.push('<br/><br/><table class="table" align="center">');
for (var i = 0; i < jsoncontent.servers.length; i++) {
for (var j = 0; j < jsoncontent.servers[i].servlets.length; j++) {
var servlet = jsoncontent.servers[i].servlets[j];
if (html.length > 2) html.push(' <tr><th colspan="5" style="border-bottom:0;">&nbsp;</th></tr>');
html.push(' <tr><th colspan="5" style="border-top:' + ((html.length > 2) ? 0 : 1) + ';">' + (servlet.comment || '未知模块') + '</th></tr>');
html.push(' <tr><th>请求URL</th><th>描 述</th><th>鉴 权</th><th>参 数 <span style="font-size:12px;">(红色: Header; 蓝色: Cookie)</span></th><th>输 出</th></tr>');
for (var k = 0; k < servlet.actions.length; k++) {
var action = servlet.actions[k];
html.push(' <tr>');
html.push('<td style="color:#ff00ff;">' + action.url + '</td>');
html.push('<td>' + action.comment + '</td>');
html.push('<td class="s">模块ID: ' + servlet.moduleid + '<br/>操作ID: ' + action.actionid + '<br/>需鉴权: ' + (action.auth ? '<font style="font-weight:bold;color:green;">true</font>' : '<font color=red>false</font>') + '</td>');
var paramshtml = [];
paramshtml.push('<table class="subtable">');
for (var p = 0; p < action.params.length; p++) {
var param = action.params[p];
var t = param.type.substring(param.type.lastIndexOf('.') + 1);
if (classmap[param.type.replace('[]', '')]) {
t = '<a href="#' + param.type.replace('[]', '') + '">' + t + '</a>';
}
if (param.name == '&') {
paramshtml.push('<tr><td style="font-size:12px;">内置 </td><td> ' + t + '</td><td> 当前用户</td></tr>');
} else {
var c = ' style="font-weight:bold;"';
if (param.src == "HEADER") c = ' style="color:red;font-weight:bold;"';
if (param.src == "COOKIE") c = ' style="color:blue;font-weight:bold;"';
paramshtml.push('<tr><td ' + c + '> ' + param.name + ' </td><td> ' + t + '</td><td> ' + param.comment + '</td></tr>');
}
}
paramshtml.push('</table>');
html.push('<td class="s" style="padding:0 5px;">' + paramshtml.join('') + '</td>');
html.push('<td>' + action.result.replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/([a-zA-Z0-9_\$]+\.)+/g, "") + '</td>');
html.push('</tr>');
}
}
}
for (var type in classmap) {
html.push(' <tr><th colspan="5" style="border-bottom:0;">&nbsp;</th></tr>');
html.push(' <tr id="' + type + '"><th colspan="5" style="border-top:0;">' + type + '</th></tr>');
html.push(' <tr><td colspan="5"><table class="typetable">');
for (var fieldname in classmap[type]) {
var field = classmap[type][fieldname];
var t = field.type.replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/([a-zA-Z0-9_\$]+\.)+/g, "");
html.push(' <tr class="l"><td>' + fieldname + '</td><td>' + t + '</td><td colspan="2">' + (field.comment || '') + '</td></tr>');
}
html.push(' </table></td></tr>');
}
html.push('</table><br/><br/><br/>');
html.push('</div>');
return html.join('');
};
</script>
<script>
var jsoncontent = ${content};
document.write(createhtml(jsoncontent));
</script>
</body>
</html>

View File

@@ -1,4 +1,4 @@
/**
* 提供RedKale服务器的启动、初始化和加载功能
* 提供Redkale服务器的启动、初始化和加载功能
*/
package org.redkale.boot;

View File

@@ -10,8 +10,7 @@ import java.lang.reflect.Type;
/**
* 对不明类型的对象进行序列化; BSON序列化时将对象的类名写入WriterJSON则不写入。
* <p>
* <p>
* 详情见: http://redkale.org
* 详情见: https://redkale.org
*
* @author zhangjx
* @param <T> 序列化的泛型类型

View File

@@ -14,7 +14,7 @@ import java.util.*;
* 支持一定程度的泛型。
*
* <p>
* 详情见: http://redkale.org
* 详情见: https://redkale.org
*
* @author zhangjx
* @param <T> 反解析的数组元素类型

View File

@@ -13,7 +13,7 @@ import java.lang.reflect.*;
* 支持一定程度的泛型。
*
* <p>
* 详情见: http://redkale.org
* 详情见: https://redkale.org
*
* @author zhangjx
* @param <T> 序列化的数组元素类型

View File

@@ -16,7 +16,7 @@ import java.util.Collection;
* 支持一定程度的泛型。
*
* <p>
* 详情见: http://redkale.org
* 详情见: https://redkale.org
*
* @author zhangjx
* @param <T> 反解析的集合元素类型

View File

@@ -13,7 +13,7 @@ import java.util.Collection;
* 集合大小不能超过 32767。 在BSON中集合大小设定的是short对于大于32767长度的集合传输会影响性能所以没有采用int存储。
* 支持一定程度的泛型。
*
* <p> 详情见: http://redkale.org
* <p> 详情见: https://redkale.org
* @author zhangjx
* @param <T> 序列化的集合元素类型
*/

View File

@@ -9,7 +9,7 @@ package org.redkale.convert;
* 序列化操作类
*
* <p>
* 详情见: http://redkale.org
* 详情见: https://redkale.org
*
* @author zhangjx
* @param <R> Reader输入的子类

View File

@@ -13,7 +13,7 @@ import static java.lang.annotation.RetentionPolicy.*;
* 依附在setter、getter方法、字段进行简单的配置
*
* <p>
* 详情见: http://redkale.org
* 详情见: https://redkale.org
*
* @author zhangjx
*/

View File

@@ -8,7 +8,7 @@ package org.redkale.convert;
/**
* ConvertColumn 对应的实体类
*
* <p> 详情见: http://redkale.org
* <p> 详情见: https://redkale.org
* @author zhangjx
*/
public final class ConvertColumnEntry {

View File

@@ -12,7 +12,7 @@ import static java.lang.annotation.RetentionPolicy.*;
/**
* ConvertColumn 的多用类
*
* <p> 详情见: http://redkale.org
* <p> 详情见: https://redkale.org
* @author zhangjx
*/
@Inherited

View File

@@ -14,7 +14,7 @@ import java.lang.annotation.*;
* 该值必须是全局唯一
* 使用场景: 当BSON序列化为了不指定class可以使用@ConvertEntity来取个别名。关联方法: Reader.readClassName() 和 Writer.writeClassName(String value) 。
*
* <p> 详情见: http://redkale.org
* <p> 详情见: https://redkale.org
* @author zhangjx
*/
@Inherited

View File

@@ -6,7 +6,7 @@ package org.redkale.convert;
/**
*
* <p> 详情见: http://redkale.org
* <p> 详情见: https://redkale.org
* @author zhangjx
*/
public class ConvertException extends RuntimeException {

View File

@@ -19,7 +19,7 @@ import org.redkale.util.*;
/**
*
* <p>
* 详情见: http://redkale.org
* 详情见: https://redkale.org
*
* @author zhangjx
* @param <R> Reader输入的子类
@@ -104,6 +104,14 @@ public abstract class ConvertFactory<R extends Reader, W extends Writer> {
this.register(double[].class, DoubleArraySimpledCoder.instance);
this.register(String[].class, StringArraySimpledCoder.instance);
//---------------------------------------------------------
this.register(HttpCookie.class, new Creator<HttpCookie>() {
@Override
@Creator.ConstructorParameters({"name", "value"})
public HttpCookie create(Object... params) {
return new HttpCookie((String) params[0], (String) params[1]);
}
});
}
}
@@ -201,6 +209,18 @@ public abstract class ConvertFactory<R extends Reader, W extends Writer> {
this.skipAllIgnore = skipIgnore;
}
/**
* 使所有类的所有被声明为ConvertColumn.ignore = true 的字段或方法变为ConvertColumn.ignore = false
*
* @param skipIgnore 忽略ignore
*
* @return 自身
*/
public ConvertFactory<R, W> skipAllIgnore(final boolean skipIgnore) {
this.skipAllIgnore = skipIgnore;
return this;
}
/**
* 使该类所有被声明为ConvertColumn.ignore = true 的字段或方法变为ConvertColumn.ignore = false
*
@@ -215,11 +235,11 @@ public abstract class ConvertFactory<R extends Reader, W extends Writer> {
register(type, column, new ConvertColumnEntry(column, ignore));
}
}
public final boolean register(final Class type, String column, String alias) {
return register(type, column, new ConvertColumnEntry(alias));
}
public final boolean register(final Class type, String column, ConvertColumnEntry entry) {
if (type == null || column == null || entry == null) return false;
try {
@@ -375,7 +395,9 @@ public abstract class ConvertFactory<R extends Reader, W extends Writer> {
} else if (clazz == Object.class) {
od = new ObjectDecoder(type);
decoder = od;
} else if (!clazz.getName().startsWith("java.")) {
} else if (!clazz.getName().startsWith("java.")
|| java.net.HttpCookie.class == clazz
|| clazz.getName().startsWith("java.awt.geom.Point2D")) {
Decodeable simpleCoder = null;
for (final Method method : clazz.getDeclaredMethods()) {
if (!Modifier.isStatic(method.getModifiers())) continue;
@@ -455,7 +477,7 @@ public abstract class ConvertFactory<R extends Reader, W extends Writer> {
encoder = new MapEncoder(this, type);
} else if (clazz == Object.class) {
return (Encodeable<W, E>) this.anyEncoder;
} else if (!clazz.getName().startsWith("java.")) {
} else if (!clazz.getName().startsWith("java.") || java.net.HttpCookie.class == clazz) {
Encodeable simpleCoder = null;
for (final Method method : clazz.getDeclaredMethods()) {
if (!Modifier.isStatic(method.getModifiers())) continue;

View File

@@ -7,7 +7,7 @@ package org.redkale.convert;
/**
*
* <p> 详情见: http://redkale.org
* <p> 详情见: https://redkale.org
* @author zhangjx
*/
public enum ConvertType {

View File

@@ -11,7 +11,7 @@ import org.redkale.util.Attribute;
/**
*
* <p>
* 详情见: http://redkale.org
* 详情见: https://redkale.org
*
* @author zhangjx
* @param <R> Reader输入的子类

View File

@@ -10,7 +10,7 @@ import java.lang.reflect.Type;
/**
*
* <p>
* 详情见: http://redkale.org
* 详情见: https://redkale.org
*
* @author zhangjx
* @param <R> Reader输入的子类

View File

@@ -11,7 +11,7 @@ import org.redkale.util.Attribute;
/**
*
* <p>
* 详情见: http://redkale.org
* 详情见: https://redkale.org
*
* @author zhangjx
* @param <W> Writer输出的子类

View File

@@ -10,7 +10,7 @@ import java.lang.reflect.Type;
/**
*
* <p>
* 详情见: http://redkale.org
* 详情见: https://redkale.org
*
* @author zhangjx
* @param <W> Writer输出的子类

View File

@@ -12,7 +12,7 @@ import java.util.Map;
/**
*
* <p> 详情见: http://redkale.org
* <p> 详情见: https://redkale.org
* @author zhangjx
* @param <K> Map key的数据类型
* @param <V> Map value的数据类型

View File

@@ -12,7 +12,7 @@ import java.util.Map;
/**
*
* <p>
* 详情见: http://redkale.org
* 详情见: https://redkale.org
*
* @author zhangjx
* @param <K> Map key的数据类型

View File

@@ -15,7 +15,7 @@ import org.redkale.util.*;
/**
*
* <p>
* 详情见: http://redkale.org
* 详情见: https://redkale.org
*
* @author zhangjx
* @param <R> Reader输入的子类
@@ -161,6 +161,7 @@ public final class ObjectDecoder<R extends Reader, T> implements Decodeable<R, T
* 对象格式: [0x1][short字段个数][字段名][字段值]...[0x2]
*
* @param in 输入流
*
* @return 反解析后的对象结果
*/
@Override

View File

@@ -12,7 +12,7 @@ import org.redkale.util.*;
/**
*
* <p>
* 详情见: http://redkale.org
* 详情见: https://redkale.org
*
* @author zhangjx
* @param <W> Writer输出的子类
@@ -121,7 +121,7 @@ public final class ObjectEncoder<W extends Writer, T> implements Encodeable<W, T
}
}
}
if (value != null && value.getClass() != this.typeClass) {
if (value.getClass() != this.typeClass) {
final Class clz = value.getClass();
if (out.needWriteClassName()) out.writeClassName(factory.getEntityAlias(clz));
factory.loadEncoder(clz).convertTo(out, value);

View File

@@ -8,7 +8,7 @@ package org.redkale.convert;
/**
*
* <p>
* 详情见: http://redkale.org
* 详情见: https://redkale.org
*
* @author zhangjx
*/

View File

@@ -11,7 +11,7 @@ import java.lang.reflect.Type;
/**
*
* <p>
* 详情见: http://redkale.org
* 详情见: https://redkale.org
*
* @author zhangjx
* @param <R> Reader输入的子类

View File

@@ -10,7 +10,7 @@ import org.redkale.util.Attribute;
/**
*
* <p>
* 详情见: http://redkale.org
* 详情见: https://redkale.org
*
* @author zhangjx
*/

View File

@@ -11,6 +11,8 @@ import static org.redkale.convert.Reader.SIGN_NULL;
import org.redkale.util.*;
/**
*
* 详情见: https://redkale.org
*
* @author zhangjx
*/

View File

@@ -11,7 +11,7 @@ import java.util.function.*;
/**
*
* <p>
* 详情见: http://redkale.org
* 详情见: https://redkale.org
*
* @author zhangjx
*/

View File

@@ -33,7 +33,7 @@ import org.redkale.util.*;
*
* </pre></blockquote>
* <p>
* 详情见: http://redkale.org
* 详情见: https://redkale.org
*
* @author zhangjx
*/

View File

@@ -11,7 +11,7 @@ import org.redkale.convert.*;
/**
*
* <p>
* 详情见: http://redkale.org
* 详情见: https://redkale.org
*
* @author zhangjx
*/
@@ -39,6 +39,12 @@ public final class BsonFactory extends ConvertFactory<BsonReader, BsonWriter> {
return this;
}
@Override
public BsonFactory skipAllIgnore(final boolean skipIgnore) {
this.registerSkipAllIgnore(skipIgnore);
return this;
}
public static BsonFactory root() {
return instance;
}

View File

@@ -14,7 +14,7 @@ import org.redkale.util.*;
/**
*
* <p>
* 详情见: http://redkale.org
* 详情见: https://redkale.org
*
* @author zhangjx
*/

View File

@@ -10,7 +10,7 @@ import org.redkale.convert.SimpledCoder;
/**
*
* <p>
* 详情见: http://redkale.org
* 详情见: https://redkale.org
*
* @author zhangjx
* @param <T> 序列化/反解析的数据类型

View File

@@ -9,6 +9,8 @@ import java.io.*;
import org.redkale.convert.*;
/**
*
* 详情见: https://redkale.org
*
* @author zhangjx
*/

View File

@@ -9,6 +9,8 @@ import java.io.*;
import org.redkale.convert.*;
/**
*
* 详情见: https://redkale.org
*
* @author zhangjx
*/

View File

@@ -13,7 +13,7 @@ import org.redkale.util.*;
/**
*
* <p>
* 详情见: http://redkale.org
* 详情见: https://redkale.org
*
* @author zhangjx
*/

View File

@@ -14,7 +14,7 @@ import java.math.BigInteger;
* BigInteger 的SimpledCoder实现
*
* <p>
* 详情见: http://redkale.org
* 详情见: https://redkale.org
*
* @author zhangjx
* @param <R> Reader输入的子类型

View File

@@ -13,7 +13,7 @@ import org.redkale.convert.Writer;
* boolean[] 的SimpledCoder实现
*
* <p>
* 详情见: http://redkale.org
* 详情见: https://redkale.org
*
* @author zhangjx
* @param <R> Reader输入的子类型

View File

@@ -13,7 +13,7 @@ import org.redkale.convert.Writer;
* boolean 的SimpledCoder实现
*
* <p>
* 详情见: http://redkale.org
* 详情见: https://redkale.org
*
* @author zhangjx
* @param <R> Reader输入的子类型

View File

@@ -13,7 +13,7 @@ import org.redkale.convert.Writer;
* byte[] 的SimpledCoder实现
*
* <p>
* 详情见: http://redkale.org
* 详情见: https://redkale.org
*
* @author zhangjx
* @param <R> Reader输入的子类型

View File

@@ -13,7 +13,7 @@ import org.redkale.convert.Writer;
* byte 的SimpledCoder实现
*
* <p>
* 详情见: http://redkale.org
* 详情见: https://redkale.org
*
* @author zhangjx
* @param <R> Reader输入的子类型

View File

@@ -12,7 +12,7 @@ import org.redkale.convert.Writer;
/**
* char[] 的SimpledCoder实现
*
* <p> 详情见: http://redkale.org
* <p> 详情见: https://redkale.org
* @author zhangjx
* @param <R> Reader输入的子类型
* @param <W> Writer输出的子类型

View File

@@ -10,7 +10,7 @@ import org.redkale.convert.*;
/**
* CharSequence 的SimpledCoder实现
*
* <p> 详情见: http://redkale.org
* <p> 详情见: https://redkale.org
* @author zhangjx
* @param <R> Reader输入的子类型
* @param <W> Writer输出的子类型

View File

@@ -13,7 +13,7 @@ import org.redkale.convert.Writer;
/**
* char 的SimpledCoder实现
*
* <p> 详情见: http://redkale.org
* <p> 详情见: https://redkale.org
* @author zhangjx
* @param <R> Reader输入的子类型
* @param <W> Writer输出的子类型

View File

@@ -12,7 +12,7 @@ import org.redkale.convert.*;
* java.nio.channels.CompletionHandler 的SimpledCoder实现, 只输出null
*
* <p>
* 详情见: http://redkale.org
* 详情见: https://redkale.org
*
* @author zhangjx
* @param <R> Reader输入的子类型

View File

@@ -14,7 +14,7 @@ import org.redkale.util.*;
* Dlong 的SimpledCoder实现
*
* <p>
* 详情见: http://redkale.org
* 详情见: https://redkale.org
*
* @author zhangjx
* @param <R> Reader输入的子类型

View File

@@ -13,7 +13,9 @@ import java.util.Date;
/**
* Date 的SimpledCoder实现
*
* <p> 详情见: http://redkale.org
* <p>
* 详情见: https://redkale.org
*
* @author zhangjx
* @param <R> Reader输入的子类型
* @param <W> Writer输出的子类型
@@ -24,12 +26,13 @@ public final class DateSimpledCoder<R extends Reader, W extends Writer> extends
@Override
public void convertTo(W out, Date value) {
out.writeLong(value.getTime());
out.writeLong(value == null ? 0L : value.getTime());
}
@Override
public Date convertFrom(R in) {
return new Date(in.readLong());
long t = in.readLong();
return t == 0 ? null : new Date();
}
}

View File

@@ -12,7 +12,7 @@ import org.redkale.convert.Writer;
/**
* double[] 的SimpledCoder实现
*
* <p> 详情见: http://redkale.org
* <p> 详情见: https://redkale.org
* @author zhangjx
* @param <R> Reader输入的子类型
* @param <W> Writer输出的子类型

View File

@@ -12,7 +12,7 @@ import org.redkale.convert.Writer;
/**
* double 的SimpledCoder实现
*
* <p> 详情见: http://redkale.org
* <p> 详情见: https://redkale.org
* @author zhangjx
* @param <R> Reader输入的子类型
* @param <W> Writer输出的子类型

View File

@@ -13,7 +13,7 @@ import org.redkale.convert.Writer;
* 枚举 的SimpledCoder实现
*
* <p>
* 详情见: http://redkale.org
* 详情见: https://redkale.org
*
* @author zhangjx
* @param <R> Reader输入的子类型

View File

@@ -12,7 +12,7 @@ import org.redkale.convert.Writer;
/**
* float[] 的SimpledCoder实现
*
* <p> 详情见: http://redkale.org
* <p> 详情见: https://redkale.org
* @author zhangjx
* @param <R> Reader输入的子类型
* @param <W> Writer输出的子类型

View File

@@ -12,7 +12,7 @@ import org.redkale.convert.Writer;
/**
* float 的SimpledCoder实现
*
* <p> 详情见: http://redkale.org
* <p> 详情见: https://redkale.org
* @author zhangjx
* @param <R> Reader输入的子类型
* @param <W> Writer输出的子类型

View File

@@ -14,7 +14,7 @@ import java.net.*;
* InetAddress 的SimpledCoder实现
*
* <p>
* 详情见: http://redkale.org
* 详情见: https://redkale.org
*
* @author zhangjx
* @param <R> Reader输入的子类型

View File

@@ -12,7 +12,7 @@ import org.redkale.convert.Writer;
/**
* int[] 的SimpledCoder实现
*
* <p> 详情见: http://redkale.org
* <p> 详情见: https://redkale.org
* @author zhangjx
* @param <R> Reader输入的子类型
* @param <W> Writer输出的子类型

View File

@@ -12,7 +12,7 @@ import org.redkale.convert.Writer;
/**
* int 的SimpledCoder实现
*
* <p> 详情见: http://redkale.org
* <p> 详情见: https://redkale.org
* @author zhangjx
* @param <R> Reader输入的子类型
* @param <W> Writer输出的子类型

View File

@@ -13,7 +13,7 @@ import org.redkale.convert.Writer;
* long[] 的SimpledCoder实现
*
* <p>
* 详情见: http://redkale.org
* 详情见: https://redkale.org
*
* @author zhangjx
* @param <R> Reader输入的子类型

View File

@@ -13,7 +13,7 @@ import org.redkale.convert.Writer;
/**
* long 的SimpledCoder实现
*
* <p> 详情见: http://redkale.org
* <p> 详情见: https://redkale.org
* @author zhangjx
* @param <R> Reader输入的子类型
* @param <W> Writer输出的子类型

View File

@@ -13,7 +13,7 @@ import org.redkale.convert.Writer;
* Number 的SimpledCoder实现
*
* <p>
* 详情见: http://redkale.org
* 详情见: https://redkale.org
*
* @author zhangjx
* @param <R> Reader输入的子类型

View File

@@ -11,7 +11,7 @@ import org.redkale.convert.*;
/**
* Pattern 的SimpledCoder实现
*
* <p> 详情见: http://redkale.org
* <p> 详情见: https://redkale.org
* @author zhangjx
* @param <R> Reader输入的子类型
* @param <W> Writer输出的子类型

View File

@@ -12,7 +12,7 @@ import org.redkale.convert.Writer;
/**
* short[] 的SimpledCoder实现
*
* <p> 详情见: http://redkale.org
* <p> 详情见: https://redkale.org
* @author zhangjx
* @param <R> Reader输入的子类型
* @param <W> Writer输出的子类型

View File

@@ -12,7 +12,7 @@ import org.redkale.convert.Writer;
/**
* short 的SimpledCoder实现
*
* <p> 详情见: http://redkale.org
* <p> 详情见: https://redkale.org
* @author zhangjx
* @param <R> Reader输入的子类型
* @param <W> Writer输出的子类型

View File

@@ -12,7 +12,7 @@ import org.redkale.convert.Writer;
/**
* String[] 的SimpledCoder实现
*
* <p> 详情见: http://redkale.org
* <p> 详情见: https://redkale.org
* @author zhangjx
* @param <R> Reader输入的子类型
* @param <W> Writer输出的子类型

View File

@@ -12,7 +12,7 @@ import org.redkale.convert.Writer;
/**
* String 的SimpledCoder实现
*
* <p> 详情见: http://redkale.org
* <p> 详情见: https://redkale.org
* @author zhangjx
* @param <R> Reader输入的子类型
* @param <W> Writer输出的子类型

View File

@@ -13,7 +13,7 @@ import org.redkale.convert.SimpledCoder;
* Type 的SimpledCoder实现 只支持Type的子类Class
*
* <p>
* 详情见: http://redkale.org
* 详情见: https://redkale.org
*
* @author zhangjx
* @param <R> Reader输入的子类型

View File

@@ -9,8 +9,13 @@ import java.net.*;
import org.redkale.convert.*;
/**
*
* <p>
* 详情见: https://redkale.org
*
* @author zhangjx
* @param <R> Reader输入的子类型
* @param <W> Writer输出的子类型
*/
public class URISimpledCoder<R extends Reader, W extends Writer> extends SimpledCoder<R, W, URI> {

View File

@@ -9,8 +9,13 @@ import java.net.*;
import org.redkale.convert.*;
/**
*
* <p>
* 详情见: https://redkale.org
*
* @author zhangjx
* @param <R> Reader输入的子类型
* @param <W> Writer输出的子类型
*/
public class URLSimpledCoder<R extends Reader, W extends Writer> extends SimpledCoder<R, W, URL> {

View File

@@ -11,7 +11,10 @@ import org.redkale.convert.*;
import static org.redkale.convert.Reader.*;
/**
*
* 只支持UTF-8格式
*
* 详情见: https://redkale.org
*
* @author zhangjx
*/

View File

@@ -15,7 +15,7 @@ import org.redkale.util.*;
/**
*
* <p>
* 详情见: http://redkale.org
* 详情见: https://redkale.org
*
* @author zhangjx
*/

View File

@@ -16,7 +16,7 @@ import org.redkale.util.*;
/**
*
* <p>
* 详情见: http://redkale.org
* 详情见: https://redkale.org
*
* @author zhangjx
*/

View File

@@ -15,7 +15,7 @@ import org.redkale.util.DLong;
/**
*
* <p>
* 详情见: http://redkale.org
* 详情见: https://redkale.org
*
* @author zhangjx
*/
@@ -41,6 +41,12 @@ public final class JsonFactory extends ConvertFactory<JsonReader, JsonWriter> {
return this;
}
@Override
public JsonFactory skipAllIgnore(final boolean skipIgnore) {
this.registerSkipAllIgnore(skipIgnore);
return this;
}
public static JsonFactory root() {
return instance;
}

View File

@@ -12,7 +12,7 @@ import org.redkale.util.*;
/**
*
* <p>
* 详情见: http://redkale.org
* 详情见: https://redkale.org
*
* @author zhangjx
*/

View File

@@ -10,7 +10,7 @@ import org.redkale.convert.SimpledCoder;
/**
*
* <p>
* 详情见: http://redkale.org
* 详情见: https://redkale.org
*
* @author zhangjx
* @param <T> 序列化/反解析的数据类型

View File

@@ -10,6 +10,8 @@ import org.redkale.convert.*;
/**
*
* 详情见: https://redkale.org
*
* @author zhangjx
*/
class JsonStreamReader extends JsonByteBufferReader {

View File

@@ -13,6 +13,8 @@ import org.redkale.util.*;
/**
*
* 详情见: https://redkale.org
*
* @author zhangjx
*/
class JsonStreamWriter extends JsonByteBufferWriter {

View File

@@ -13,8 +13,7 @@ import org.redkale.util.*;
*
* writeTo系列的方法输出的字符不能含特殊字符
* <p>
* <p>
* 详情见: http://redkale.org
* 详情见: https://redkale.org
*
* @author zhangjx
*/

View File

@@ -15,7 +15,7 @@ import java.util.concurrent.*;
/**
*
* <p>
* 详情见: http://redkale.org
* 详情见: https://redkale.org
*
* @author zhangjx
*/

Some files were not shown because too many files have changed in this diff Show More