根据文件管理系统,逐文件地、初步修改了OA系统,并成功登录
@@ -1,5 +1,12 @@
|
||||
#\u4FEE\u6539\u914D\u7F6E\u6587\u4EF6
|
||||
#Mon Mar 16 11:20:10 CST 2020
|
||||
ServerIPAddress=121.15.171.88
|
||||
#Tue Apr 07 15:45:02 CST 2020
|
||||
KeyName=/testKey_v3
|
||||
loginUserName=466D1203678EFB16BE85C8A02E1486B6
|
||||
ndnBlockChainIPAddress=116.77.74.139
|
||||
ServerIPAddress=116.77.74.139
|
||||
ThreadNumberForFileTransfer=5
|
||||
ndnBlockChainPortAddress=9001
|
||||
DataPackagePrefix=/ndn/edu/pkusz/OA
|
||||
LoginStatus=true
|
||||
loginPassWord=A1B9652D9ED940B8FC63453C50CB3337
|
||||
ServerPortAddress=6363
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
MIIEogIBAAKCAQEA1SfrgYkPWsFCq68QPY/LlaofFZHPsGf3v9xbcSzdOwRlFh1o
|
||||
c4VOZ6NUqmX4cJtDzsuxcivXyj529VgywrhijreFWlFV8o+94pSGRf3ncQqXXRGM
|
||||
JdN+Jyk65atPXYZaCb9Qcy0EPcvGy478ysN0vZN9ZLuYMcy4itVpjWCjrKQIhRpI
|
||||
bPVQ2JO9VYB8ow1emIFMbPlBR2SXeA/Q9hPpl3loqItHzIlcT0QhFzH01QINEy1m
|
||||
f2cjDaWvHYRobFPTAcv07a956EGXfvodne3BVc6Bcw7tOPJRgQGZPw/iI0vzcITc
|
||||
XBCJTTnOKbR+5BLmNxdlwVfI1BXTE95nmE/60QIDAQABAoIBABwMlMEG+C5JICzX
|
||||
bJutQG0BZfXAqkPcao2kwaOy86nAekzesdAByr94jrudj4PB6rpbs44ClvLWJXFD
|
||||
mepluRJus+2epmC06ZfXU5QCRWJqsmBc3sRbgE5G7qkqUddMxqxhsIR3eAdpuU8w
|
||||
EbPc5I/NyMJorS5gcihSzQD9powhDA392rFrh5yoZeoRAondJnv/a4TqcWpL86Zr
|
||||
bArIR1s/Fmx5uNdi2zkXvXKbDEoWGngwGKs3TKVztsIq8z3LaIoTvZshVtRtAi7X
|
||||
4tyPaVMuVF2nXU2i1Fi3pa2DowblxeA5VgYT8OgcZom3fXQpnoTDChBYL3x0ftE8
|
||||
caHkF8ECgYEA/aKcY+XNlbu6sCuya1Qz6O9ot5078Z23UCWhGKAeNYVXjW2Ez7d4
|
||||
8rDzvF/XxM5jSM920FbdQWsZl/b9yzh31dBYqgoPbCKxyF/NE6Cm66OfaqIiTLBm
|
||||
vbr1Q9me1TjFrWvk1yk89nPj7Y9ewFWLO0hKlMb4BGUo9dhF40+7TnsCgYEA1ySw
|
||||
7gxutLH7pYzdXe1+QhgPVYOR5whFUyAdbg8QPMC5USaZEmjInfvKvMAfzRVF0Kn9
|
||||
VEdpWeUHsNxh4c+vJ8ayO7liugI96738iwt1NJwb3fDfemN+sdPw1XsDUfJWZiML
|
||||
pjmnq6nrhyFHwgKvAl9RXP0oM+jewYPt7FkIwCMCgYBobFiC8Ivxx7aW7YaplaNB
|
||||
lb/BSOTzFwHv524p21JUqq9fNOXnNxx+nsfamIMXLfnGclPydrDlTBjfbfsTfg4o
|
||||
Y3z9lOLAnJAhdP/TwuK2RUlO962zcTT7jEuKQcCY/KS2P6OZygqlVRVUKyDRguat
|
||||
45eBJWHbPWLdxMsRSTROnQKBgEzphAsGDMmyWzk626SJk7qDKXAzwgQq88Wc1IiV
|
||||
AAQIDfgR6WUoapf3/Olvca76bOQE8Vig0uvdMdurXZ7BhWed4/fv9Xhz9rkBSXhX
|
||||
10XAjUHRq8LwMMnX7+ARwwUXsoV+/9okAGohK986KZIVLYWWl9q7chTkqkXaKUN2
|
||||
LOerAoGAMaeH8w6iQsdBJjmP1Wfk2ZT/Wk47a1RgTqCCahIz5EDGL2/YlTRlIACy
|
||||
KaWOp9cjHb+sWz4/Mor5unOvTIq3Csa82qGu8sle2PCf8lDfSw+OpaB6jFO6oA56
|
||||
OGJ2dzdky9OAAO0ldbO8aX23nqoqqcgCIWedboB/lVYAZlfkSTU=
|
||||
@@ -0,0 +1,25 @@
|
||||
MIIEowIBAAKCAQEAhZm4MZ8r2h/uBzVLT1DLZCj5J9eF/htay0jhhDU9s4swPsvd
|
||||
zB1eBBG7IQCyD6BupM0M1jGuRJ64p5Dk17jy/VAuCH5MkCIxXo3C1wAWNKv708gO
|
||||
CU3LduFg3vjpMP9ceisDfDcCr8ZJ1Mma5JV+7QMsHdTiU41CGUl7bNSn1e0Zq3rY
|
||||
QGe/HxsSTXGcigl638xGQ9sKdNFrWpQHeHQEoPHylwh4bHKTuN8vGYKQbCpyI3IX
|
||||
s69Qm3INzgNpCwda1pZLdRKaBDTO91kOZJ9Ln43k2Ic68icaoL8ZDHUD3C6M5b2l
|
||||
MxSPg2989VV768YNPpiKJskRfY7LlKPy4f5iNQIDAQABAoIBAHDsZ1X59fTefDC3
|
||||
iTo3TlMQlthoQSdxM6MTrRo0bjyt70+EvapjQC4sVoEkt1yh/CNr9eeuAmCZz/ZC
|
||||
cEsuVqRp+x7OsiQ54oTLSd60ghBvNeHh/Is8qDeJdHnC5ke18BKK/N0nGiw8a/dh
|
||||
mHyRJ8FppwZoBA0fHrmE9MAeVuZnxNfns5VWVha4Z1WopSyGT5Ux+G6vMxFlLgen
|
||||
b9ANMw9v2kHv5+BNvZ81ro2A8vJhL69ig3mJFefkxHoIWhdwl+CtUC3dR2FRb/9w
|
||||
fSjXi/D6jkHMeOrZjfBcpDikcZ5oVfmOL4HO6PMWnxx6XgG9fQS2HFcF9C5SqnAj
|
||||
43KGmEECgYEA+phd35ylwRuzBFH0BJNxk7LnYVWSm2FdpGVc06khnOIvG6i+RXuW
|
||||
PmqFqGxmm3sKpXzMU0gc9Z8o0hg8nIkFCwr2+ZZIdfP70JsEledvxc/J8/CNL5zJ
|
||||
Fj0NbkuzSjofZ2FBvmyNorLU+OfNyu5MzdUi9iTrJ1yur90+BBNOdF0CgYEAiHth
|
||||
KuXMa71oajLDWuGDQ2AXrSWhiVBTH+9p39J6cLUzIfmHRtu5Vwxuxsw91HJw0nsH
|
||||
izAliqWAZvtFGirfjWlrpe3GWtMdOyy8c0UWXCbI6HKBcJxebe8qlsEyg8e0o3Yj
|
||||
Z73MwsAifwKprzcKZPSiIhogx/5BxjTxU5u4x7kCgYAq5ANFL5mLKMOGHMTIN7g7
|
||||
0GYb2bqjD5IofhTaQVt4b5oigMo4OEPp4O+JeSxCtleHJYoPQwt52sjw1KcjH6yW
|
||||
TEUjSN6UGbNi6/Vn9tnBoKPvNZ/ko1Ajl0WCOECylqojVpkbD5daXoNnKr2lWw4Y
|
||||
OL+oI3+AGDPp89MWfXtzHQKBgE/LuyLmml8/rYWxylAfW6yPySf9wXVUFlWsl706
|
||||
BUZSWuP5TWNbYgCID1iB34CPrHETZ3S0oK5wVyNes6c5+9xlD4BDBd7iYcvQOxo2
|
||||
AX29W2e0UwOxGPCzjbX4nP05TN7pWof0C3yt8z1JJEaCKryd3xGLLzFe8bveBl64
|
||||
xA9ZAoGBAImSFu8nFLtQNCTJza4js2t3P4q9Tg5VIbzeEjdtos/dLqGhGOq1wPMt
|
||||
WPBFh6r29gMuqDeUgZnZo/XioENspBHV99fakO2nkrwcKinAvmIgriXU82pDNp8j
|
||||
UemLtcHGaAFfinfmGw4Z5H5aApVzDxEAL1TLKyHcJFXhPu5I7RV4
|
||||
@@ -0,0 +1,25 @@
|
||||
MIIEogIBAAKCAQEAnfq8CLJMv7IYQNOUehxTbi3Wtgv5jxbYo7jtw+HLH85jujkX
|
||||
BL89G4zpGv0+q7ZKkrxYauSUkvuxyQ7Aeg0xao7TIxQgZPMyY4VPJpLSE+xJaach
|
||||
xqcTJt2snPy6pw/gz8gVj74G70+j1xK2ZkdsZw/iUzPa+jJlK3rI7+l6LsUUVBHa
|
||||
jEB136njugNC0s8+nBi06h4u6BhBFYYAx4AuZeBar3EcRnHu8u3L5LCzbS9v87Go
|
||||
05JmlhtGKzDLgFRTGVc49Kvu4YvVTZ/YnNtQeOjP3Uc3WRAHd0ApDfZMZLvRsbxz
|
||||
4h/h5/58tSW4Z4m3fOn00nD0pitSBuMjsq8wFwIDAQABAoIBAD21s72x6Ej5SIAK
|
||||
JfWNGwnu3fA+vT0nr3hExJu/l5jVBh+4LUWtbjFU2bmxMsnga0DmUaNvppnDt67S
|
||||
FF2YybTWFaOeOQk19njpmgF3WJhvtD2RC6CNou2LqeGo10Bq82Y2wjVkBVF1yoo4
|
||||
xQcu3yljCwV1PBR/mwVg8RzGFvQtaO/CHB6x0RxsOk9mFyOn2US8t4vj6oGVAKj3
|
||||
7agk3UxGWAiRWPl/x44U7xnXE+6KavbOSguMWzI8LGAwYivNlOg8VhW1NYpuqAZU
|
||||
LxnwMTC0xHrxQqYtCVRQNl91i+Krkh+0MCH1TkAo+IxJJEmtsGJCB4GrHa+0pcWP
|
||||
xgr4IAECgYEA6RbOvg6q86H6sVUjWL00ypm9GwBOlDFZNLMWQ8p5NMrpkiHbp43r
|
||||
IlvSP8IpptImhOhJJs4i84bFt5pkQdqO1FLyLhM3FEaK5LKqlIKNDKfVdW3n0K2d
|
||||
qoRz38J9UYgtp7ctXttV2oqVUr+F4sylnqGhbRKM+v7zRIWSKJkQ0nsCgYEArYHz
|
||||
oewqJpQcaNZ4fS/ae+IjUYHbOGs7L5rUocmkXFBeGa8XCl9RqyvxVeg5yqEhn4Mn
|
||||
3AC7ONWAIXtkMa+IsCgka1cagF57ULcn7oWDRgw3TShvbNXZkWo4+rz0EQT19L75
|
||||
zcPa06FWrURT1CMH/xjb899iYbR5wgsFWEXMBBUCgYAdbzfkYE3OPmI+CpZQGnSU
|
||||
MR3kTwGdTS4KraLeJK9xrz4Xqhbm7dEHobjHPGmuG1Op7Ptv3xAi2J4XNXP7rPHk
|
||||
diUHFH4cHVxkzPsljebp9jfKgHqJq6MBaYCIfTL+HMhHKaadF+2bj2yT6oOpxFYV
|
||||
1itgbrtG5vMpcASpA8tQCQKBgE5RUDWQsl4DkOdJl816Ija1Fpgd82P+ExMj4kK9
|
||||
D/GTXUZeoBnQeL648RCD6EIshU7JFt7ZfajjxhhW6Bz9TMem9vl0scOr4iHG6sFh
|
||||
hqXBsdykGdeYl8Jpnhqf29Mq2BKHeZ6Ff2rzcnp3Uxd4UI23HOFxvai4nBUYgGsd
|
||||
5j8ZAoGAHRYhOF+zDbK3nGQsuZjsDb3LrngdNjiEPA+hYeh3k2BKwirSKoVUQa62
|
||||
k0Tb/PRBiPiyQk7uYGwyR9WA8Yr2BA3y+/9m5rNenwJAL/o39DjogV9K/pxSmPH+
|
||||
FOz29FNtO0WO5IpNaVroKCn+SHSEahFdhdyR6I9J+chFHnsDQDo=
|
||||
@@ -0,0 +1,25 @@
|
||||
MIIEpQIBAAKCAQEAs9dajy8yS3WCi15hnHumAP6SELbbusHDqx957OwA4V5YSiXJ
|
||||
ocgT4k+SPg9y+FgM90XNtiYZbqqi0tXtrIXsNN3VZx4UDQAAoR8Xe2RCuINA9o38
|
||||
b3roK+3eJnlv0Z6msY7jBawib8ngdyNJMobVPNM2qNT9Z3CE7aNjDvKf/Y4/DeK2
|
||||
X9ljvK2+XPjMwZ+otlIcS+q027cGlJO4RkHLukGuJbpltkhcGLL+wVvs7lx/Per0
|
||||
Z/6pTum6LPVar2H+qse4XWpVgIVeMEg1uGmdplqqRV0YR1yzhfuQ0tqOYjHvaPwX
|
||||
e68zOIyDcqkapvsogztm06E0682uzId9vup66QIDAQABAoIBAFgmN4o1TQa1m34q
|
||||
jdfAt7aHERtGNd+NeBYZgI7Dgw70SnxVl0ZIJo7oB7uJoQXfSsOtIE6m0BJxawvC
|
||||
thO5NPUYwrAfix5wIN7YuY7OrvF3zFDNea0+5iwaFKhxH4D0raocamRuYha/MdnT
|
||||
nt44Pq7orEMG2wpnmZBNZJGAFTGXQiuYCr9UVGnlChn3nNORJrYA6yogjSwJVhVo
|
||||
4S9g0JNI4pq9bgZk7xQ3J51LbJRT7KEnGHNY9E8+3Ya0uQpD9qGHTeueBnEjjh04
|
||||
MU7bPfRmfr6E5stQUgt9fK4MmFLGm/DJhI5RGMDIck+8kcWDnP+zzghicscUavmn
|
||||
XwY9Aq0CgYEA9oAtyUqTCFZGbcHIUu/I4j+vcAoOtIkW5UxNuQJn5jmYuQYJu47o
|
||||
D9n+AZQVfKrSRgSQw5EqYLx/dkzv1gxmJaM1urfVQG7b/XFtk0CFPhZAFrAT6m5M
|
||||
RQuqhZ49+F0CYYA4kCeOjDQ3/QUO7ofHOKhKUBBkZn/PQFyJ3EdhLpMCgYEAusWN
|
||||
69pVMKiT3Rkfo2Lv+uqj+HXCFyiE8ASIulX/VkKnlnFWA9Wiesr3S6PBZBSk58Ky
|
||||
1lPZdVWTV1DXh2bxSggCVNccxriIQVUCqyWGN3rWhFZvLK7DCcU5cfNGzwnCvisn
|
||||
JqVENg9fxvBPDI33T1NkcI1QHWTiNiAWTGm5ohMCgYEAocCYyvbJpvXeP1Wi23GH
|
||||
k5eQyud+oM84m/zHH7lJbpSq9/bTWiU7eHNmr6h5tRXu541FZV+TvGjVB08TLpVy
|
||||
Tg5cSospP5+/cf8FlVQIWyaEpZ6jYvk/ySsPmaCuL5Tw5AQcmdOrQatedgTkuHeW
|
||||
rkIYiZNIHs6NtEFFIawhREsCgYEAqk4fhhN1IMRm5/HTvpkluEeispk2HQXOikmo
|
||||
HzjxdkebJvw7cY2o9Y0DiA5O9qI4aDhJ+FNG883PZ4wIq6e7l0TMU24/CBkV7XTF
|
||||
1SeHRimVV+C0ySqmH8+d/QDW7Uy6LcuNjJigJSdJr05K1mjRPJ0O9e51QghOmQoT
|
||||
KyQwp88CgYEAtA/he1Lf81965giwWg6k1Ul2+o4d96eq+aGDesW9awmKQIMVnXPw
|
||||
9++6uYLNTOazRELEt0+jeuf8T/nqtmjahURhG+rbxj0fvafd0faV07ygIHbpK575
|
||||
pEMIV3UUZjKUVPqnhSOc7B71k1163prIjIYvjSe2pCq9KxEAORd9Je4=
|
||||
@@ -0,0 +1,25 @@
|
||||
MIIEogIBAAKCAQEA1XSNRuSN3o/wayYGHV4FnBL8iofwlRjUJsJEQuGTi5eIVT7j
|
||||
qL3IalgGJJ5lAFpaLod83NTXG+4lqFnUfQPB7qd0MQyi9xWt3IdzL83t6V7egLx2
|
||||
DpSd8Y5ZgKasD05LA6/kcmAMv04Vvj/ndwvLmHUTr3j8xNMJMFIWdpB19Zuma7Zr
|
||||
6UwXh+ylS3bvJPDOcDsQgu2f/Boa7cMhALs76AdM7szrnbnHZbv+dtuxOD609Wjy
|
||||
albxSLqjpqV3w2Af0/Z5PIa8turNREGqxqI7R7vm/VIUrjU6bpzn2E2/lc3l0sPr
|
||||
XVydRPc1HJi0k+1ivRsWpevpGE5h5Y7rdtckuQIDAQABAoIBAAaHw0647VIyyyMs
|
||||
DaHWX4uP1SQT1ptpIAxzgw0cw5vQrf4Vp3dhHwGJ4d467lIdcYbc5EgJRu920LYe
|
||||
0W5lsAgyHU7m2RGAG0qU5kQ/I5kxKtN7cI0vpMlgFoLmFnt9ZLQfLHkHUTyFEgs4
|
||||
/0bYGIl4g3qp0+ndnvlYeZF1B/bUlus1VKVjW7tBlXDmst6kcfgi767AAHJjaaaz
|
||||
Ho9stJR+UT0MIHCz5f+OUrQOfynO1F6K6zVlQBaIgSfmSIhSkzQ10qjhTXka7miF
|
||||
UEJs580sPg13+EMjSDIWVRe81s9hc9uoeozY+sdnk6AAjhyktU3BijxPdAGZuJyo
|
||||
1hFEXJECgYEA7ypNV7kMEU8bVNjsFNdpxVoWc6/RgXAYXmJ5kMKC1fXanUxPYGxN
|
||||
0UWeEhLw3SuL//iAMe9magGeykGsZFr1qcz4eveL0jl5mu8jhv/nZcENemrAHd2P
|
||||
zBWBe10pvBfT2Wn1dv7Wit3mVz5QpEvdDZNOFTgAYLN5kwf6XGDKdi0CgYEA5Hr2
|
||||
cKpP+Bk9f6CeCLwvwFyih2oRn9Z2boRLUVrJcWlxB49rWc1nh+EAZWIarjeZh/8r
|
||||
sDmCJoX60c9GZSyFFEBRQfprW5Ao3RyXNY6oKenBjCWHJUbv041C2qkdTeblls0e
|
||||
3etqaa/tHL2zLFiOvlAf/8nj1N4psE0duRR2bD0CgYAMf7h1Ci2wReMWxxNnb26O
|
||||
qsublierzRDo9dqGjzPJPMUFDXTkhCR4+FtvdF/0Hw98/B6u/WTry1PiHBaHVB2c
|
||||
lyKxQnijLu/FAhRoPL16GuG6cRPDO84FC2at7Mt+kfw3U4tJgb3ymfAsxQvv2ise
|
||||
R4GAKGIUq6yB25vg8goCrQKBgCdbSwIjRD0vU9mdODu29t7C1jhPPBP1ZFcrMLIl
|
||||
2ldP22l6+fnxGOleB6xvFrt11luHx+XGMjYilA76Dl01KwNPBPBBi6atEWztFNrj
|
||||
5PG7U1ypxjrUmlEtnxt9UA/wOxIb6To+6AimhkiSIL/9zTDZKnnsM/OiBTpaPkl4
|
||||
TeHdAoGAO1Tfl5KcEP/zMSg2hDtmrb90z2fVA4ewoFOo5Y64F99GIepS83MYiwRK
|
||||
tmmqHqG+DUYOs8sLexfKtZyRyguWxFwW69/aTNomZoeCzP9F/nHg+ns8jZsGwSZY
|
||||
TpER91D1iiTLhl1Wnz7EPGKQVn1a/OdWkxsiFlFpMMxFAQye6A4=
|
||||
@@ -0,0 +1,25 @@
|
||||
MIIEpAIBAAKCAQEAg3GRtC0iPdgugSnyNkp29LDaYNzVjXY46pE+OFSAbFm3X++K
|
||||
LIinlxqB1cc5nlk82ckzodUzUvGpTbSNib7PKq1625A+k0Ue3WD7aKB+yDoIr66b
|
||||
ZMqCOx8bpMEOFoHIb/Ua/zDFezZUheX6nVZnTDl3vFf4erx8jZYeC47miJKkjH1l
|
||||
eiX+U5M9IV4vkU/iIoTyLFOBuqDy95OD7dkFIdOqoSY0MvjuPMT9+bTfBgvVXaYW
|
||||
kEoLpcdxV6Yq2FhMiCINaYm+dVmg14PYVXLMAsUFzotSZ9jB3JQOcmKZYhyLEke8
|
||||
6P90KOrDaT7qwzY+h2vovpIf77EXfNve2ezP9QIDAQABAoIBAE9CyYireq1uUcSj
|
||||
ZaIlTwwIJPcp00CFXJbd1HYlRnePtgsMp/ZoxR5R5p7hjrYUu6PcNt1McbF/dgcc
|
||||
bAj23XevupjxpzopAQ6fb5rMxQa6MAi4Mo4Zq2Q5QvMbUwJxaktQsuHVKBA/V8KS
|
||||
Rohf1NRbBv+00Go6hKTgM+fmWM9bM7t2lpuv2dD8Tt5TwqfWINAjfrHUIVBf2HUG
|
||||
FOpcaOufmdYiVpTkdrx+lfc8uZBBSM7GYDS6WdtotamWsaL9XhBlVzUFgvd6LKOu
|
||||
A8iju6YRnDBrBy/MrdShAZGv+AruNXW/psxdUNfSPY9jAzTtS3f2/v6liXCY7xNO
|
||||
anSnlbUCgYEA4zYDutw2WSAtJDcUtpxIxahwX52vRbnSHToYtvJfkxcFeuJ4jj3M
|
||||
5WBivV7CSvrKGVlL88O9X7QrmouUhNPoQ4cqHOPWnQecKxAiksfdMNl+bn8PV2bP
|
||||
W5J35rHFtYfzrO/mHz6Et6De9ASGNAUlvFTZORkqu+EKs4HGzgLC9gcCgYEAlBks
|
||||
P6iaLDUqnkPaUYC87BKCfztFq0vwBAuFmzJiqti/URaaB1ABOX9ICIii9bLKBBpH
|
||||
UVk4SxMqxFOkfO4aERBWg08eaT4iEvJOBDF9w/x5ElapEA7uw81rAmpwvQszwSiw
|
||||
p9e1FocoepSsd34eL/V/EkFFhhqrpxjCxan+KyMCgYEA0Xz22W26alhhZpemcGwO
|
||||
KLgRzAbuGIKouKvdJ6i2+D5sng17C+LtLLu+rk1VJJ6wgci0X6+kxj2vSlHRgNqE
|
||||
tuZDrNlhAe2HTqkUx3KhfS27BZP/CB3Rp+OWy0wzNxl/UX7rFPmmkkwv5JrbRdFN
|
||||
JqSwl5WdshZesH1CWKVxLjcCgYEAkDRqt5mudXlXhD/BpzbZvmzPkJ/gWMlabjXh
|
||||
5JqNJJpkv8poNNKcPqZHN7gEJYXv20rTQszDWabSL9TaB6O40gC8nKM/k26isxwp
|
||||
B0BBm8KNCWREvpQrvZCZsAKAwDLWNDEwwl3xwHve2G1H+hpdvoknMFlKHyh9F/mu
|
||||
PdYm3U0CgYBHKh+FWZ2K/MPY/+69+7BgpdvTYoyV/nO4lTDVoLpMsrk6/PwAwwHT
|
||||
YyXx36E1xGjFvBN46H3UTXd06mI4a8aX3obRDVvzrHAEd1uWAr4ufYvpib2BFMuu
|
||||
iIfBlsG7qPSdL5af0w8jKiLW6QxegqYVPrtbCCY4JpbcgEXjtL6z0g==
|
||||
@@ -0,0 +1,25 @@
|
||||
MIIEowIBAAKCAQEAiA3stSNU6Xkr26SYt/AANIdq1zXCsaErIDM5LIIQ+CG+NK37
|
||||
bikKdrxouYhJ00lPTP7GyIwRpbORf4Xy9kNad+Xfs0KhWrebyn8ZWsPFVrDX7aVa
|
||||
Pb68GY2EuQBwGp2dkZjFGUVQKvK6dhwMl3pvtfucjIjg2qAktNw1SFcAy5kjA6JN
|
||||
pMqh9MbrV9hF7otMvnfXge2VpIglpS8zmT3fbPjXc+V9PhaY9MIBVnMLA+Q1BvXl
|
||||
X/127NjgSrMLqW+eBYltZzNt8PD142oL4CMR71nR5sJxXrYHmABQtnRYr+ek0is+
|
||||
6EpAdj92hQ7CXAeeoXacEScODV6NQG7dRMtn4wIDAQABAoIBAEOaR6epqqNn5fb5
|
||||
Tjj3M+Ll9pyAxgDlCDyztxD6f9wLSCt815XhJqXg8Fhf8+7cWl7zqWo0zv/6va0T
|
||||
ranXxbgVrJWx4eLloK95f+utovx0WpZmtvQ/Nc+sleom4Y0YDBcwRZ9M5Yyxlxzg
|
||||
yxDpcWCHaT4bNT7sm9CSKpeLQ4XmEntrOASb3v1G/6bzl5d1M2UXiy85uP2RqSez
|
||||
uvcugYEGIJTAF2FXH4iISiA0uEvnCu0k4H5CVoe4eu44Ykc86KwHASqwb1Yl/5LF
|
||||
DOUA4fiy5Grq99gnoOWrPqOfQAZVy16i04+q9qp5BAD9yBsgaLgsgzzhsFm1UAzx
|
||||
pETc9SECgYEA1Q+ftMsFzLdFa9tzlFzOG4OQu/hFYf2SVweXkpwZk3TMyu9zBTbX
|
||||
zl9es2ygWYJXwCRl4a6iFOj7j3ucq16Od94MsHl1AtO1XdP2Wx3ppZd5F8a7lyPk
|
||||
krQaGgealz6y/IqWev5FuzqQuiTOClf+L2OAQkoWgUdpBTxH8aJiIK0CgYEAo3lT
|
||||
qy9VbHxBh62Mi//C9LXdMzHSZnlf2i1K4VXew8gQHMidxMay6ef/UT4jYRgly5xo
|
||||
mZoAf5bhmlbgKONVwCsTGi77L+m20QCq4WOfGG770xQtMdAohYvZmfdZhcbxqhmf
|
||||
IAfXAAR/bAQqYjl9mK7Xyj+GrpUMQLX++YuSbM8CgYBYcYzlWuXEbku2EznuW3v/
|
||||
deTt8oiyvbUyxWcJKB2B1ZlxoGaJwpNhCrvgFXaW0YGltDZKsdh8f551mGWXyb+w
|
||||
SI/R7glBrCp8kZGRj2A/KhrNYOTcP70RnQu8xG1K3W8lYE5JLiY6K3yKmN6i8pYE
|
||||
i/RhECo5bjBNSRHAX50GXQKBgQCiZr7zOoPf0ZV8R7JvxreUSjQlTuKaAQxzgDl6
|
||||
oMc8sr0nCzqJKWjGrT7dJCEbrVSm8YyMxAyotGkN3i61EBu5XFGO2ouabtG60rHw
|
||||
VfrQ2Dj+2nWHnicTfPrBVZSvLRQaC3gk5wT1tIIt+fltOXYHv/MKro+LUvEoPGXA
|
||||
3aKqywKBgGjnOX39Un3MB/15i9qV1Mvh6QJgv5ldlRnYtPKpPU7HCGCieLcS9SgG
|
||||
6O0bZ1bbbIn5boYg21wq1O0HrSFgDi5DW0JdsBysKDqUAyp7346GCez7z98wYHR0
|
||||
dInzfUjMgdeQ7JlC5cZi/+ETotKjvZWu1QDaIj2S3UAd9R4MHPP5
|
||||
@@ -0,0 +1,25 @@
|
||||
MIIEpAIBAAKCAQEAlP1sWRkjTq25xwcrISI1YHR/CjdTacF1MfBZdDNPQ1krFybr
|
||||
qtzbUeqjUzwHVMhH6TP6x3H6+k9RCAkcuGbafhsKvKdteN9Yi4doadzQE5HUYsQE
|
||||
fbGSuC2afN4txIqt40QJKhDnqyi9abr3pRn+sGin14AWBUiMi9n/xd9RcOly6AkG
|
||||
D/Rr3eEmaBKc/GbvKEpurcCuQURsNu0x0LiBm/sGeBKaPXOU3zqfWiDXS9fjenyi
|
||||
iMLDZZBD45FQxIa2aFWtNbpPFLCjWJCwlIwtC4kKutZR8k0ZN7rXNavpajEXg33H
|
||||
0hhgQwWNgMPK04lIyAU6MCiUN6cdL59liuQNbQIDAQABAoIBAAUnWwcd+n2vPrzm
|
||||
v5Qu1b/XZ8mXrlf7LC2lDcMaP0SqIfZ0DzTi3OdRgYLQkcRaBTrI5ITfqXndIoVv
|
||||
o0GxtR8lmlJ6TCwhNbPl5DO9QqlaowkjlLAwY03hrfVhzh19WpSA9vwwh4MBLsQo
|
||||
hoZ8hrXdeOjYcmqOXuY7jUBwACYyr5ZSzp8Q+QXuP1QLiyw6TpotrbB6wkx5JS0U
|
||||
X2CJWxfllMAYr/mDXSXW4uysLqvYCR/VAu/B2s0kue9WjcsGyRuzP42A4gKGKa/E
|
||||
/RC6RVqR/WSEPMRlt30+A9zNt/1lkTWF5Nr/8CILtAbdhq2uGxS1qs+Smt1uTdBb
|
||||
BYYsTzUCgYEAxwunZuQduW6mAajuLC03qT6SrJntBnHnr4hJV203n4kaiBvOO54W
|
||||
pXt2zFXZ7h9C1ziwIGrtQdVUTfDw+pkZCM7EAt82IYwUp4MB/7Dnbe3nW3nRCEd9
|
||||
5Q89r0cSLwp8I49jyRjYIb21eZ4NCQRJSryc0L6McqaCbUmm1LJ9Qz8CgYEAv58h
|
||||
tnKwLfwhXhRNS3UERJ2wGBuuTXGymWyhUTISmPumt0+R8NZRrlJ7zhkLBaDQkA4Q
|
||||
Zu2GnyZdQ77aBrfXXD1E9gaEO5pukHNZhavSIg48K2nw7eaa0c40iJ2uTbo1nli0
|
||||
qK/mywAxd4imjCWpYMLwUHXapFRe7bTeCsgowFMCgYEAlDQkL+M4EqLFbkT3GeON
|
||||
JzIVCfkOWBcluDgUy8jheqMeIyv48cDzAcIdIWXm/3s9THzD/08+Wx9ZRzNYam7m
|
||||
Cf3SSoUii/X+Rv+v1E9G8j4KXr0kHDMHFS+08TZM3sPCzMNuPASIoQ7c+bHp6MXN
|
||||
QJ2RcYf/kTpTsMX/Ny2zQQcCgYEAhvLAwUafwKLRtPnDPaLZMKGExFWqOSwbRWV1
|
||||
bkM/SbHgRTSqaNvmhkfcnNaSJpKMjwb4kiQxLJ/OCsm7rgOGjZUwnbsVIQyvVNeH
|
||||
clYBFK7FvSVM4Z4H5j28TYIOoPrEjBGYmTvX45rtO2tnL0fOszBWIbP+GMC6YdmA
|
||||
jkNMP7UCgYA2fubLdBrpoS1ITDzqCzpffQNoGeRq0DqnpDMIYuSqYGvWING0UkY0
|
||||
w9PHGiVL3p3PisVGOyfv0Zne2bpF6VOOkbGRdd9P82wr85CgsOwt4WQIFRvIEmlu
|
||||
lx4p38As1CpEDW1wIQ8KOJu6BQoHTI/EuTQDApOEmnaP4I9eQX4Z8A==
|
||||
|
After Width: | Height: | Size: 3.9 KiB |
|
After Width: | Height: | Size: 3.9 KiB |
|
After Width: | Height: | Size: 3.9 KiB |
|
After Width: | Height: | Size: 3.9 KiB |
|
After Width: | Height: | Size: 3.9 KiB |
|
After Width: | Height: | Size: 3.9 KiB |
|
After Width: | Height: | Size: 3.9 KiB |
@@ -2,14 +2,16 @@ package cn.minoa;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
import cn.minoa.dataRequestInterface.MinoaDataAPI;
|
||||
import cn.minoa.dataRequestInterface.OrderInfo;
|
||||
import cn.minoa.dataRequestInterface.ResponseData;
|
||||
import cn.minoa.dataRequestInterface.*;
|
||||
import cn.minoa.model.*;
|
||||
import cn.minoa.util.FileUtil;
|
||||
import cn.minoa.util.LoggerUtil;
|
||||
import cn.minoa.util.StringByteLengthUtil;
|
||||
import cn.minoa.view.NavigationBarController;
|
||||
import cn.minoa.view.home.*;
|
||||
import cn.minoa.view.login.KeepLoginStatus;
|
||||
import cn.minoa.view.login.LoginOverviewController;
|
||||
import cn.minoa.view.login.RegisterOverviewController;
|
||||
import cn.minoa.view.login.SettingOverviewController;
|
||||
@@ -29,6 +31,7 @@ import javafx.fxml.FXMLLoader;
|
||||
import javafx.geometry.Pos;
|
||||
import javafx.scene.Group;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.scene.control.Alert;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.ProgressBar;
|
||||
@@ -36,7 +39,9 @@ import javafx.scene.image.Image;
|
||||
import javafx.scene.layout.AnchorPane;
|
||||
import javafx.scene.layout.BorderPane;
|
||||
import javafx.scene.layout.HBox;
|
||||
import javafx.scene.layout.VBox;
|
||||
import javafx.scene.paint.Color;
|
||||
import javafx.scene.text.Text;
|
||||
import javafx.stage.Modality;
|
||||
import javafx.stage.Stage;
|
||||
import javafx.stage.StageStyle;
|
||||
@@ -86,19 +91,25 @@ public class MainApp extends Application {
|
||||
// 判断聊天窗口是否已经被完整加载的锁(保证得到新消息时 在控制器已经被加载出来后才更新气泡)
|
||||
private boolean chatBoxIniFinished; // 标志ChatBox是否初始化完成
|
||||
|
||||
// 服务器数据接口
|
||||
public MinoaDataAPI minoaDataAPI;
|
||||
// 唯一标识数据请求
|
||||
private Long dataReqId;
|
||||
// 服务器数据接口
|
||||
public volatile static MinoaDataAPI minoaDataAPI;
|
||||
// 唯一标识数据请求
|
||||
private static AtomicLong dataReqId = new AtomicLong(0);
|
||||
|
||||
// 服务器数据接口参数信息
|
||||
public String minoaServerIpString;
|
||||
public Integer minoaServerPortInteger;
|
||||
public String globalPrefixString;
|
||||
// 服务器数据接口参数信息
|
||||
public String minoaServerIpString;
|
||||
public Integer minoaServerPortInteger;
|
||||
public static String NDNBlockChainIPAddress;
|
||||
public static Integer NDNBlockChainPortAddress;
|
||||
public String globalPrefixString;
|
||||
public Integer threadNumberForFileTransfer; //文件传输使用的线程数目
|
||||
// public String pidDbPathString;
|
||||
|
||||
// 密钥导出文件的默认文件名称: username_KeyFileNameString
|
||||
public static String KeyFileNameString="SecretKeyMIN";
|
||||
|
||||
// 保存登录者信息
|
||||
public Loginer loginer;
|
||||
public static Loginer loginer;
|
||||
// 保存联系人列表数据
|
||||
public ObservableList<Person> contactListData = FXCollections.observableArrayList();
|
||||
// 保存与所有联系人的消息记录
|
||||
@@ -110,14 +121,14 @@ public class MainApp extends Application {
|
||||
// 保存通知列表
|
||||
public ObservableList<SingleNotice> noticeList = FXCollections.observableArrayList();
|
||||
|
||||
// 文件下载默认保存到windows本地的路径
|
||||
public final String fileLocalPath;
|
||||
// 文件分片包含的最大字节数
|
||||
public final Integer sliceSize;
|
||||
// 文件上传默认上传到服务器的路径[用户根目录]
|
||||
public final String fileServerBinPath;
|
||||
// 邮件中的附件文件上传到服务器的路径[/share]
|
||||
public final String sharedFileServerPath;
|
||||
// 文件下载默认保存到windows本地的路径
|
||||
public final String fileLocalPath;
|
||||
// 文件分片包含的最大字节数
|
||||
public static final Integer sliceSize = 7000;
|
||||
// 文件上传默认上传到服务器的路径[用户根目录]
|
||||
public static final String fileServerBinPath = "/";
|
||||
// 邮件中的附件文件上传到服务器的路径[/share/]
|
||||
public final String sharedFileServerPath;
|
||||
|
||||
// 用户头像的默认保存位置
|
||||
public final String userHeadPhotoBinPath;
|
||||
@@ -125,17 +136,19 @@ public class MainApp extends Application {
|
||||
// 进度条更新任务[传入子线程]
|
||||
Task copyWorker;
|
||||
// 标记是否是手动取消了上传或下载操作【false表示未取消,true表示取消】
|
||||
public boolean isCancelFileTransferFlag;
|
||||
public static boolean isCancelFileTransferFlag;
|
||||
// 上传文件进度条stage
|
||||
private Stage uploadFileDialogStage;
|
||||
// 下载文件进度条stage
|
||||
private Stage downloadFileDialogStage;
|
||||
|
||||
// 决定心跳包是否需要判断登录状态是否失效
|
||||
public boolean isNeedKnowLoginStatus=false;
|
||||
|
||||
public MainApp() {
|
||||
// 加载配置文件
|
||||
loadSettingProperties();
|
||||
// 初始化一些数据
|
||||
dataReqId = (long) 0;
|
||||
minoaDataAPI = new MinoaDataAPI(this);
|
||||
messageLogMap = new TreeMap<String, ObservableList<SingleMessage>>();
|
||||
iniNotReadMessageListWhenLogin = new NotReadMessageList();
|
||||
@@ -144,12 +157,11 @@ public class MainApp extends Application {
|
||||
contactListFinished = false;
|
||||
chatBoxIniFinished = false;
|
||||
fileLocalPath = "E:\\";
|
||||
fileServerBinPath = "/";
|
||||
sharedFileServerPath = "/share/";
|
||||
System.out.println("客户端根目录:"+getClientPath());
|
||||
userHeadPhotoBinPath = getClientPath() + "\\resources\\images\\headPhotos\\";
|
||||
// System.out.println(userHeadPhotoBinPath);
|
||||
sliceSize = 7000;
|
||||
// sliceSize = 7000;
|
||||
isCancelFileTransferFlag=false;
|
||||
|
||||
// 初始化记录当前显示的面板的字符串
|
||||
@@ -178,49 +190,57 @@ public class MainApp extends Application {
|
||||
System.out.println("en bytelength: "+StringByteLengthUtil.getByteLength("en"));
|
||||
}
|
||||
|
||||
// 加载可修改属性的配置文件
|
||||
public void loadSettingProperties(){
|
||||
InputStream inputStream = null;
|
||||
try {
|
||||
//如果 classPath 不存在,则获取的输入流会为 null
|
||||
inputStream=new BufferedInputStream(new FileInputStream(this.getClientPath()+ File.separator+"ndn"+File.separator+"settings.properties"));
|
||||
// 加载可修改属性的配置文件
|
||||
public void loadSettingProperties() {
|
||||
InputStream inputStream = null;
|
||||
try {
|
||||
//如果 classPath 不存在,则获取的输入流会为 null
|
||||
inputStream = new BufferedInputStream(new FileInputStream(this.getClientPath() + File.separator + "ndn" + File.separator + "settings.properties"));
|
||||
// inputStream = MainApp.class.getClassLoader().getResourceAsStream("/ndn/settings.properties");
|
||||
if (inputStream == null) {
|
||||
System.out.println("没有找到配置文件...");
|
||||
}
|
||||
Properties settingProperties = new Properties();
|
||||
settingProperties.load(inputStream);
|
||||
String serverIPAddress = settingProperties.getProperty("ServerIPAddress");
|
||||
String serverPortAddress=settingProperties.getProperty("ServerPortAddress");
|
||||
String dataPackagePrefix=settingProperties.getProperty("DataPackagePrefix");
|
||||
System.out.println("ServerIPAddress: "+serverIPAddress);
|
||||
System.out.println("ServerPortAddress: "+serverPortAddress);
|
||||
System.out.println("DataPackagePrefix: "+dataPackagePrefix);
|
||||
this.minoaServerIpString=serverIPAddress;
|
||||
this.minoaServerPortInteger=Integer.parseInt(serverPortAddress);
|
||||
this.globalPrefixString=dataPackagePrefix;
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}finally{
|
||||
//关闭输入流
|
||||
if (inputStream != null) {
|
||||
try {
|
||||
inputStream.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (inputStream == null) {
|
||||
System.out.println("没有找到配置文件...");
|
||||
}
|
||||
Properties settingProperties = new Properties();
|
||||
settingProperties.load(inputStream);
|
||||
String serverIPAddress = settingProperties.getProperty("ServerIPAddress");
|
||||
String serverPortAddress = settingProperties.getProperty("ServerPortAddress");
|
||||
String NDNBlockChainIPAddressString=settingProperties.getProperty("ndnBlockChainIPAddress");
|
||||
String NDNBlockChainPortAddressString=settingProperties.getProperty("ndnBlockChainPortAddress");
|
||||
String dataPackagePrefix = settingProperties.getProperty("DataPackagePrefix");
|
||||
String threadNumberString = settingProperties.getProperty("ThreadNumberForFileTransfer");
|
||||
System.out.println("ServerIPAddress: " + serverIPAddress);
|
||||
System.out.println("ServerPortAddress: " + serverPortAddress);
|
||||
System.out.println("NDNBlockChainIPAddress: "+NDNBlockChainIPAddressString);
|
||||
System.out.println("NDNBlockChainPortAddress: "+NDNBlockChainPortAddressString);
|
||||
System.out.println("DataPackagePrefix: " + dataPackagePrefix);
|
||||
System.out.println("ThreadNumberString: " + threadNumberString);
|
||||
this.minoaServerIpString = serverIPAddress;
|
||||
this.minoaServerPortInteger = Integer.parseInt(serverPortAddress);
|
||||
this.NDNBlockChainIPAddress=NDNBlockChainIPAddressString;
|
||||
this.NDNBlockChainPortAddress=Integer.parseInt(NDNBlockChainPortAddressString);
|
||||
this.globalPrefixString = dataPackagePrefix;
|
||||
this.threadNumberForFileTransfer = Integer.parseInt(threadNumberString);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
//关闭输入流
|
||||
if (inputStream != null) {
|
||||
try {
|
||||
inputStream.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 获取一个新的数据请求标识
|
||||
public Long getNewDataReqId() {
|
||||
dataReqId++;
|
||||
return dataReqId;
|
||||
}
|
||||
// 获取一个新的数据请求标识
|
||||
public static Long getNewDataReqId() {
|
||||
return dataReqId.incrementAndGet();
|
||||
}
|
||||
|
||||
// 获取项目根目录路径
|
||||
public String getClientPath() {
|
||||
public static String getClientPath() {
|
||||
File directory = new File("");// 参数为空
|
||||
String path = "";
|
||||
try {
|
||||
@@ -266,60 +286,132 @@ public class MainApp extends Application {
|
||||
minoaDataAPI.bindNews();
|
||||
}
|
||||
|
||||
// 判断minoaAPI中的face是否启动,如果未开启,说明IP有问题,返回false
|
||||
public static boolean isFaceLinked(){
|
||||
return minoaDataAPI.runFace();
|
||||
}
|
||||
|
||||
// 下载文件到本地缺省目录下[E盘根目录]
|
||||
public Integer downloadFileByPathfilename(String pathfileName) {
|
||||
return loginerController.downloadFile(pathfileName);
|
||||
}
|
||||
// public Integer downloadFileByPathfilename(String pathfileName) {
|
||||
// return loginerController.downloadFile(pathfileName);
|
||||
// }
|
||||
|
||||
// 登录失效:弹窗提醒,点击确定之后跳转到登录界面
|
||||
public void reLogin(){
|
||||
// 非FX线程调用FX的UI组件
|
||||
Platform.runLater(() -> {
|
||||
// 首先,修改本地登录状态
|
||||
KeepLoginStatus.setLoginStatus(false);
|
||||
// 然后,弹窗提醒
|
||||
// 弹窗参考:https://code.makery.ch/blog/javafx-dialogs-official/
|
||||
Alert alert = new Alert(Alert.AlertType.ERROR);
|
||||
alert.setTitle("登录状态失效");
|
||||
alert.setHeaderText("登录状态失效");
|
||||
alert.setContentText("您的登录状态失效,请重新登录。");
|
||||
alert.showAndWait();
|
||||
// 最后,展示登录界面
|
||||
showLoginOverview();
|
||||
});
|
||||
}
|
||||
|
||||
// 下载文件到指定目录下
|
||||
public Integer downloadFileByPathfilename(String pathfileName, String localDir) {
|
||||
return loginerController.downloadFileToSpecifiedDir(pathfileName, localDir);
|
||||
}
|
||||
// public Integer downloadFileByPathfilename(String pathfileName, String localDir) {
|
||||
// return loginerController.downloadFileToSpecifiedDir(pathfileName, localDir);
|
||||
// }
|
||||
|
||||
// 显示进度条并下载文件到指定目录下
|
||||
public void downloadFileByPathfilenameWithProgressBar(String pathfileName, String localDir){
|
||||
isCancelFileTransferFlag=false;
|
||||
// 显示进度条并下载文件到指定目录下
|
||||
public void downloadFileByPathfilenameWithProgressBar(String pathfileName, String localDir) {
|
||||
// currentDownloadedDataSlices.set(0);
|
||||
isCancelFileTransferFlag = false;
|
||||
// 创建进度条子Stage
|
||||
downloadFileDialogStage = new Stage();
|
||||
downloadFileDialogStage.setTitle("minoaClientWindows-文件传输");
|
||||
downloadFileDialogStage.setTitle("FileSystem-文件传输");
|
||||
downloadFileDialogStage.getIcons().add(new Image("file:resources/images/logo_mini.png"));
|
||||
downloadFileDialogStage.initStyle(StageStyle.TRANSPARENT);
|
||||
downloadFileDialogStage.initModality(Modality.WINDOW_MODAL);
|
||||
downloadFileDialogStage.initOwner(primaryStage);
|
||||
|
||||
Group root = new Group();
|
||||
Scene scene = new Scene(root, 330, 120, Color.WHITE);
|
||||
Scene scene = new Scene(root, 530, 220, Color.WHITE);
|
||||
downloadFileDialogStage.setScene(scene);
|
||||
|
||||
BorderPane mainPane = new BorderPane();
|
||||
mainPane.setPrefHeight(100);
|
||||
mainPane.setPrefWidth(325);
|
||||
mainPane.setPrefHeight(200);
|
||||
mainPane.setPrefWidth(525);
|
||||
root.getChildren().add(mainPane);
|
||||
|
||||
final Label label = new Label("文件传输进度:");
|
||||
final ProgressBar progressBar = new ProgressBar(0);
|
||||
progressBar.setPrefWidth(300);
|
||||
Long filelen=loginerController.getServerFileLength(pathfileName);
|
||||
Integer cycle = (int)(filelen / sliceSize);
|
||||
if (filelen % sliceSize != 0) {
|
||||
cycle++;
|
||||
}
|
||||
final Integer sliceNum=cycle;
|
||||
// final Text text = new Text("0/" + cycle.toString());
|
||||
final Text text = new Text("0%");
|
||||
text.setWrappingWidth(50);
|
||||
|
||||
Text nullTextTop=new Text("");//空text,控制位置
|
||||
Text nullTextLeft=new Text("");//空text,控制位置
|
||||
// 文件名称
|
||||
final Label filenamelabel = new Label("文件名称:");
|
||||
final Text filenameText = new Text();
|
||||
String filename=pathfileName;
|
||||
if(filename.length()>50){
|
||||
filename=filename.substring(0,50)+"...";
|
||||
}
|
||||
filenameText.setText(filename);
|
||||
final HBox fnhb = new HBox();
|
||||
fnhb.setSpacing(10);
|
||||
fnhb.setAlignment(Pos.CENTER_LEFT);
|
||||
fnhb.getChildren().addAll(filenamelabel, filenameText);
|
||||
// 文件大小
|
||||
final Label filesizeLabel = new Label("文件大小:");
|
||||
final Text filesizeText = new Text();
|
||||
String filesize= FileUtil.sizeToShowSize((long)filelen);
|
||||
filesizeText.setText(filesize);
|
||||
final HBox fshb = new HBox();
|
||||
fshb.setSpacing(10);
|
||||
fshb.setAlignment(Pos.CENTER_LEFT);
|
||||
fshb.getChildren().addAll(filesizeLabel, filesizeText);
|
||||
// fshb.setLayoutX(50);
|
||||
// 两个合并
|
||||
final VBox vb=new VBox();
|
||||
vb.setSpacing(25);
|
||||
vb.setAlignment(Pos.CENTER_LEFT);
|
||||
vb.getChildren().addAll(nullTextTop,fnhb,fshb);
|
||||
HBox bigHb=new HBox();
|
||||
bigHb.setSpacing(38);
|
||||
bigHb.setAlignment(Pos.CENTER_LEFT);
|
||||
bigHb.getChildren().setAll(nullTextLeft,vb);
|
||||
// vb.setLayoutX(50);
|
||||
mainPane.setTop(bigHb);
|
||||
|
||||
final HBox hb = new HBox();
|
||||
hb.setSpacing(20);
|
||||
hb.setSpacing(10);
|
||||
hb.setAlignment(Pos.CENTER);
|
||||
hb.getChildren().addAll(label, progressBar);
|
||||
hb.getChildren().addAll(label, progressBar,text);
|
||||
mainPane.setCenter(hb);
|
||||
|
||||
final Button startButton = new Button("开始传输");
|
||||
final Button cancelButton = new Button("取消传输");
|
||||
final Button sureButton = new Button("确认完成");
|
||||
sureButton.setDisable(true);
|
||||
final HBox hb2 = new HBox();
|
||||
hb2.setSpacing(20);
|
||||
hb2.setSpacing(50);
|
||||
hb2.setAlignment(Pos.CENTER);
|
||||
// hb2.getChildren().addAll(startButton);
|
||||
hb2.getChildren().addAll(startButton, cancelButton);
|
||||
hb2.getChildren().addAll(startButton, cancelButton,sureButton);
|
||||
mainPane.setBottom(hb2);
|
||||
startButton.setOnAction(new EventHandler<ActionEvent>() {
|
||||
public void handle(ActionEvent event) {
|
||||
startButton.setDisable(true);
|
||||
progressBar.setProgress(0);
|
||||
cancelButton.setDisable(true);
|
||||
cancelButton.setText("确认完成");
|
||||
copyWorker = createDownWorker(pathfileName, localDir,cancelButton);
|
||||
cancelButton.setDisable(false);
|
||||
sureButton.setDisable(true);
|
||||
copyWorker = createDownWorkerBasedWindow(pathfileName, localDir,sliceNum, cancelButton,sureButton,text);
|
||||
progressBar.progressProperty().unbind();
|
||||
progressBar.progressProperty().bind(copyWorker.progressProperty());
|
||||
copyWorker.messageProperty().addListener(new ChangeListener<String>() {
|
||||
@@ -333,237 +425,315 @@ public class MainApp extends Application {
|
||||
});
|
||||
cancelButton.setOnAction(new EventHandler<ActionEvent>() {
|
||||
public void handle(ActionEvent event) {
|
||||
if(cancelButton.getText().equals("确认完成")){
|
||||
}else{
|
||||
isCancelFileTransferFlag=true;
|
||||
}
|
||||
isCancelFileTransferFlag = true;
|
||||
downloadFileDialogStage.close();
|
||||
}
|
||||
});
|
||||
sureButton.setOnAction(new EventHandler<ActionEvent>() {
|
||||
public void handle(ActionEvent event) {
|
||||
downloadFileDialogStage.close();
|
||||
// startButton.setDisable(false);
|
||||
// cancelButton.setDisable(true);
|
||||
// copyWorker.cancel(true);
|
||||
// progressBar.progressProperty().unbind();
|
||||
// progressBar.setProgress(0);
|
||||
// System.out.println("传输已终止。");
|
||||
}
|
||||
});
|
||||
// 打开文件传输Stage
|
||||
downloadFileDialogStage.showAndWait();
|
||||
}
|
||||
|
||||
// 文件数据下载TASK
|
||||
public Task createDownWorker(String filename, String localDir,Button button) {
|
||||
// 文件数据下载TASK:滑动窗口
|
||||
public Task createDownWorkerBasedWindow(String filename, String localDir,Integer sliceNum, Button button,Button sureButton,Text text) {
|
||||
return new Task() {
|
||||
@Override
|
||||
protected Object call() throws Exception {
|
||||
// 下载到本地的文件名称
|
||||
String localName = loginerController.getPureFileName(filename);
|
||||
// 发送数据请求
|
||||
Long seqLong = getNewDataReqId();
|
||||
OrderInfo orderInfo=new OrderInfo();
|
||||
orderInfo.setSeq(seqLong);
|
||||
orderInfo.setJsonString(loginerController.getFileInfoJson(filename));
|
||||
minoaDataAPI.executeOrder("/fileInfo", orderInfo);
|
||||
// 获取文件信息
|
||||
ResponseData responseData = minoaDataAPI.dataCacheQueue.getResponseDataBySeq(seqLong);
|
||||
JSONObject jsonObject = responseData.praseRequestData();
|
||||
System.out.println("fileInfo-JSON: " + jsonObject.toString());
|
||||
Integer codeInteger = null;
|
||||
try {
|
||||
codeInteger = jsonObject.getInt("code");
|
||||
} catch (JSONException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (codeInteger == 200) {
|
||||
String dataString;
|
||||
try {
|
||||
dataString = jsonObject.getString("data");
|
||||
JSONObject dataJsonObject = new JSONObject(dataString);
|
||||
Integer sliceNumInteger;
|
||||
sliceNumInteger = dataJsonObject.getInt("sliceNum");
|
||||
// 根据分片信息获取每个分片,并合并成一个完整比特流
|
||||
Integer flagSuccessInteger=0;
|
||||
Integer flagInteger = 0;
|
||||
for (int i = 0; i < sliceNumInteger; i++) {
|
||||
flagInteger = loginerController.downLoadFileBySlice(filename, i, localDir, localName);
|
||||
if(flagInteger==0){
|
||||
flagSuccessInteger++;
|
||||
System.out.println("数据分片"+i+"传输成功. ");
|
||||
// updateMessage("");
|
||||
updateProgress(flagSuccessInteger, sliceNumInteger);
|
||||
}else{
|
||||
flagSuccessInteger++;
|
||||
System.out.println("数据分片"+i+"传输失败. ");
|
||||
// updateMessage("");
|
||||
updateProgress(flagSuccessInteger, sliceNumInteger);
|
||||
Long startTime = System.currentTimeMillis();
|
||||
// 滑动窗口协议下载文件
|
||||
// DownLoadClient downLoadClient = new DownLoadClient(filename,localDir,sliceNum);
|
||||
DownLoadClientBasedFacePool downLoadClient=new DownLoadClientBasedFacePool(filename,
|
||||
localDir,sliceNum,threadNumberForFileTransfer);
|
||||
//启动一个线程监听更新的传输进度值
|
||||
Thread listenThread = new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Long sliceNumLong=sliceNum.longValue();
|
||||
// TODO Auto-generated method stub
|
||||
while (true) {
|
||||
Long progressInteger = downLoadClient.recvCount.get();
|
||||
System.out.println("当前已经下载的数据片个数:" + progressInteger);
|
||||
Double progressPercentDouble=Math.floor((progressInteger*100)/sliceNumLong);
|
||||
Integer progressPercentInteger=progressPercentDouble.intValue();
|
||||
String textString=progressPercentInteger.toString()+"%";
|
||||
// 更新进度条
|
||||
// String textString=progressInteger.toString()+ "/" + sliceNumLong.toString();
|
||||
if (!text.getText().equals(textString)) {
|
||||
updateProgress(progressInteger, sliceNumLong);
|
||||
text.setText(textString);
|
||||
}
|
||||
//如果当前进度条
|
||||
if (progressInteger.equals(sliceNumLong)) {
|
||||
updateProgress(1,1);
|
||||
text.setText("100%");
|
||||
System.out.println("***************监听进度条的线程结束监听*************");
|
||||
break;
|
||||
}
|
||||
try {
|
||||
Thread.sleep(30);
|
||||
} catch (InterruptedException e) {
|
||||
System.out.println(e.getMessage());
|
||||
text.setText("100%");
|
||||
updateProgress(1,1);
|
||||
System.out.println("***************监听进度条的线程结束监听*************");
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(flagSuccessInteger==sliceNumInteger){
|
||||
System.out.println("文件数据已成功全部写入本地");
|
||||
}else{
|
||||
System.out.println("由于未知原因,文件数据全部或部分未成功写入本地");
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
listenThread.start();
|
||||
// 下载文件
|
||||
boolean res = downLoadClient.downloadData();
|
||||
listenThread.interrupt();
|
||||
Long endTime = System.currentTimeMillis();
|
||||
System.out.println("耗时:" + (endTime - startTime) + "ms");
|
||||
LoggerUtil.insertFileAction(filename,"下载",(endTime - startTime) + "ms");
|
||||
// 每个分片都上传成功
|
||||
if (res) {
|
||||
System.out.println("已成功将文件 " + filename + " 下载到本地" + localDir + "目录下。");
|
||||
} else {
|
||||
System.out.println("由于未知原因,服务器端文件" + filename + "下载失败。");
|
||||
}
|
||||
//设置确认按钮
|
||||
button.setDisable(false);
|
||||
button.setDisable(true);
|
||||
sureButton.setDisable(false);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// 上传本地文件到指定的服务器目录下
|
||||
public Integer uploadFileToServerPath(File file, String serverpath) {
|
||||
Integer r=loginerController.sendFileToServer(file, serverpath);
|
||||
return r;
|
||||
}
|
||||
// public Integer uploadFileToServerPath(File file, String serverpath) {
|
||||
// Integer r=loginerController.sendFileToServer(file, serverpath);
|
||||
// return r;
|
||||
// }
|
||||
|
||||
// 显示进度条并上传文件到指定目录
|
||||
public void uploadFileToServerPathWithProgressBar(File file, String serverpath){
|
||||
isCancelFileTransferFlag=false;
|
||||
// 创建进度条子Stage
|
||||
uploadFileDialogStage = new Stage();
|
||||
uploadFileDialogStage.setTitle("minoaClientWindows-文件传输");
|
||||
uploadFileDialogStage.getIcons().add(new Image("file:resources/images/logo_mini.png"));
|
||||
uploadFileDialogStage.initStyle(StageStyle.TRANSPARENT);
|
||||
uploadFileDialogStage.initModality(Modality.WINDOW_MODAL);
|
||||
uploadFileDialogStage.initOwner(primaryStage);
|
||||
public void uploadFileToServerPathWithProgressBar(File file, String serverpath) {
|
||||
// currentUploadedDataSlices.set(0);
|
||||
isCancelFileTransferFlag = false;
|
||||
// 创建进度条子Stage
|
||||
uploadFileDialogStage = new Stage();
|
||||
uploadFileDialogStage.setTitle("FileSystemWindows-文件传输");
|
||||
uploadFileDialogStage.getIcons().add(new Image("file:resources/images/logo_mini.png"));
|
||||
uploadFileDialogStage.initStyle(StageStyle.TRANSPARENT);
|
||||
uploadFileDialogStage.initModality(Modality.WINDOW_MODAL);
|
||||
uploadFileDialogStage.initOwner(primaryStage);
|
||||
|
||||
Group root = new Group();
|
||||
Scene scene = new Scene(root, 330, 120, Color.WHITE);
|
||||
uploadFileDialogStage.setScene(scene);
|
||||
Group root = new Group();
|
||||
Scene scene = new Scene(root, 530, 220, Color.WHITE);
|
||||
uploadFileDialogStage.setScene(scene);
|
||||
|
||||
BorderPane mainPane = new BorderPane();
|
||||
mainPane.setPrefHeight(100);
|
||||
mainPane.setPrefWidth(325);
|
||||
root.getChildren().add(mainPane);
|
||||
BorderPane mainPane = new BorderPane();
|
||||
mainPane.setPrefHeight(200);
|
||||
mainPane.setPrefWidth(525);
|
||||
root.getChildren().add(mainPane);
|
||||
|
||||
final Label label = new Label("文件传输进度:");
|
||||
final ProgressBar progressBar = new ProgressBar(0);
|
||||
Text nullTextTop=new Text("");//空text,控制位置
|
||||
Text nullTextLeft=new Text("");//空text,控制位置
|
||||
// 文件名称
|
||||
final Label filenamelabel = new Label("文件名称:");
|
||||
final Text filenameText = new Text();
|
||||
String filename=file.getAbsolutePath();
|
||||
if(filename.length()>50){
|
||||
filename=filename.substring(0,50)+"...";
|
||||
}
|
||||
filenameText.setText(filename);
|
||||
final HBox fnhb = new HBox();
|
||||
fnhb.setSpacing(10);
|
||||
fnhb.setAlignment(Pos.CENTER_LEFT);
|
||||
fnhb.getChildren().addAll(filenamelabel, filenameText);
|
||||
// 文件大小
|
||||
final Label filesizeLabel = new Label("文件大小:");
|
||||
final Text filesizeText = new Text();
|
||||
String filesize= FileUtil.sizeToShowSize(file.length());
|
||||
filesizeText.setText(filesize);
|
||||
final HBox fshb = new HBox();
|
||||
fshb.setSpacing(10);
|
||||
fshb.setAlignment(Pos.CENTER_LEFT);
|
||||
fshb.getChildren().addAll(filesizeLabel, filesizeText);
|
||||
// fshb.setLayoutX(50);
|
||||
// 两个合并
|
||||
final VBox vb=new VBox();
|
||||
vb.setSpacing(25);
|
||||
vb.setAlignment(Pos.CENTER_LEFT);
|
||||
vb.getChildren().addAll(nullTextTop,fnhb,fshb);
|
||||
HBox bigHb=new HBox();
|
||||
bigHb.setSpacing(38);
|
||||
bigHb.setAlignment(Pos.CENTER_LEFT);
|
||||
bigHb.getChildren().setAll(nullTextLeft,vb);
|
||||
// vb.setLayoutX(50);
|
||||
mainPane.setTop(bigHb);
|
||||
|
||||
final HBox hb = new HBox();
|
||||
hb.setSpacing(20);
|
||||
hb.setAlignment(Pos.CENTER);
|
||||
hb.getChildren().addAll(label, progressBar);
|
||||
mainPane.setCenter(hb);
|
||||
final Label label = new Label("文件传输进度:");
|
||||
final ProgressBar progressBar = new ProgressBar(0);
|
||||
progressBar.setPrefWidth(300);
|
||||
// long filelen = file.length();
|
||||
// int cycle = (int) (filelen / sliceSize);
|
||||
// if (filelen % sliceSize != 0) {
|
||||
// cycle++;
|
||||
// }
|
||||
// final Text text = new Text("0/" + cycle);
|
||||
final Text text = new Text("0%" );
|
||||
text.setWrappingWidth(50);
|
||||
final HBox hb = new HBox();
|
||||
hb.setSpacing(10);
|
||||
hb.setAlignment(Pos.CENTER);
|
||||
hb.getChildren().addAll(label, progressBar, text);
|
||||
mainPane.setCenter(hb);
|
||||
|
||||
final Button startButton = new Button("开始传输");
|
||||
final Button cancelButton = new Button("取消传输");
|
||||
final HBox hb2 = new HBox();
|
||||
hb2.setSpacing(20);
|
||||
hb2.setAlignment(Pos.CENTER);
|
||||
final Button startButton = new Button("开始传输");
|
||||
final Button cancelButton = new Button("取消传输");
|
||||
final Button sureButton = new Button("确认完成");
|
||||
sureButton.setDisable(true);
|
||||
final HBox hb2 = new HBox();
|
||||
hb2.setSpacing(50);
|
||||
hb2.setAlignment(Pos.CENTER);
|
||||
// hb2.getChildren().addAll(startButton);
|
||||
hb2.getChildren().addAll(startButton, cancelButton);
|
||||
mainPane.setBottom(hb2);
|
||||
startButton.setOnAction(new EventHandler<ActionEvent>() {
|
||||
public void handle(ActionEvent event) {
|
||||
startButton.setDisable(true);
|
||||
progressBar.setProgress(0);
|
||||
cancelButton.setDisable(true);
|
||||
cancelButton.setText("确认完成");
|
||||
copyWorker = createWorker(file, serverpath,cancelButton);
|
||||
progressBar.progressProperty().unbind();
|
||||
progressBar.progressProperty().bind(copyWorker.progressProperty());
|
||||
copyWorker.messageProperty().addListener(new ChangeListener<String>() {
|
||||
public void changed(ObservableValue<? extends String> observable,
|
||||
String oldValue, String newValue) {
|
||||
System.out.println(newValue);
|
||||
}
|
||||
});
|
||||
new Thread(copyWorker).start();
|
||||
}
|
||||
});
|
||||
cancelButton.setOnAction(new EventHandler<ActionEvent>() {
|
||||
public void handle(ActionEvent event) {
|
||||
if(cancelButton.getText().equals("确认完成")){
|
||||
}else{
|
||||
isCancelFileTransferFlag=true;
|
||||
hb2.getChildren().addAll(startButton, cancelButton,sureButton);
|
||||
mainPane.setBottom(hb2);
|
||||
startButton.setOnAction(new EventHandler<ActionEvent>() {
|
||||
public void handle(ActionEvent event) {
|
||||
startButton.setDisable(true);
|
||||
progressBar.setProgress(0);
|
||||
cancelButton.setDisable(false);
|
||||
// copyWorker = createWorker(file, serverpath, cancelButton, text);
|
||||
copyWorker = createUploadWorkerBasedWindow(file, serverpath, cancelButton, sureButton,text);
|
||||
progressBar.progressProperty().unbind();
|
||||
progressBar.progressProperty().bind(copyWorker.progressProperty());
|
||||
copyWorker.messageProperty().addListener(new ChangeListener<String>() {
|
||||
public void changed(ObservableValue<? extends String> observable,
|
||||
String oldValue, String newValue) {
|
||||
System.out.println(newValue);
|
||||
}
|
||||
uploadFileDialogStage.close();
|
||||
// startButton.setDisable(false);
|
||||
// cancelButton.setDisable(true);
|
||||
// copyWorker.cancel(true);
|
||||
// progressBar.progressProperty().unbind();
|
||||
// progressBar.setProgress(0);
|
||||
// System.out.println("传输已终止。");
|
||||
}
|
||||
});
|
||||
// 打开文件传输Stage
|
||||
uploadFileDialogStage.showAndWait();
|
||||
});
|
||||
new Thread(copyWorker).start();
|
||||
}
|
||||
});
|
||||
cancelButton.setOnAction(new EventHandler<ActionEvent>() {
|
||||
public void handle(ActionEvent event) {
|
||||
// 手动取消了传输
|
||||
isCancelFileTransferFlag = true;
|
||||
uploadFileDialogStage.close();
|
||||
}
|
||||
});
|
||||
sureButton.setOnAction(new EventHandler<ActionEvent>() {
|
||||
public void handle(ActionEvent event) {
|
||||
// 确认完成了传输
|
||||
uploadFileDialogStage.close();
|
||||
}
|
||||
});
|
||||
// 打开文件传输Stage
|
||||
uploadFileDialogStage.showAndWait();
|
||||
// });
|
||||
}
|
||||
|
||||
// 文件数据上传TASK
|
||||
public Task createWorker(File file, String serverpath,Button button) {
|
||||
// 文件数据上传TASK:滑动窗口
|
||||
public Task createUploadWorkerBasedWindow(File file, String serverpath, Button button,Button sureButton, Text text) {
|
||||
return new Task() {
|
||||
@Override
|
||||
protected Object call() throws Exception {
|
||||
//获取要上传文件的文件长度,计算上传次数
|
||||
long filelen = file.length();
|
||||
int cycle = (int) filelen / sliceSize;
|
||||
int remainder=(int)filelen%sliceSize;
|
||||
if((cycle>0)&&(remainder==0)) {
|
||||
cycle--;
|
||||
int cycle = (int) (filelen / sliceSize);
|
||||
if (filelen % sliceSize != 0) {
|
||||
cycle++;
|
||||
}
|
||||
System.out.println("file-len: " + filelen);
|
||||
System.out.println("cycle: " + cycle);
|
||||
//发送上传命令给上传接口,接口自行取本地数据
|
||||
int flagSuccess = 0; //记录收到200回复的次数
|
||||
for (int i = 0; i <= cycle; i++) {
|
||||
OrderInfo orderInfo = new OrderInfo();
|
||||
ResponseData responseData = new ResponseData();
|
||||
Long seqLong = getNewDataReqId();
|
||||
orderInfo.setSeq(seqLong);
|
||||
//此时传入的文件路径是windows下的绝对路径
|
||||
orderInfo.setJsonString(loginerController.getUploadFile(file.getAbsolutePath(), i * sliceSize));
|
||||
minoaDataAPI.executeOrder("/uploadFile", orderInfo, serverpath);
|
||||
responseData = minoaDataAPI.dataCacheQueue.getResponseDataBySeq(seqLong);
|
||||
// System.out.println("上传文件的数据回执(200表示成功):"+responseData.getResponseJsonDataString());
|
||||
JSONObject jsonObject = responseData.praseRequestData();
|
||||
responseData.printSelf();
|
||||
// 解析数据
|
||||
Integer codeInteger = null;
|
||||
try {
|
||||
codeInteger = jsonObject.getInt("code");
|
||||
} catch (JSONException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
Long startTime = System.currentTimeMillis();
|
||||
// 滑动窗口协议上传文件
|
||||
// UpLoadClient upLoadClient = new UpLoadClient(file, serverpath);
|
||||
UpLoadClientBasedFacePool upLoadClient=new UpLoadClientBasedFacePool(file,
|
||||
serverpath,threadNumberForFileTransfer);
|
||||
//启动一个线程监听更新的传输进度值
|
||||
Thread listenThread = new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
long filelen = file.length();
|
||||
Long sliceNumLong = filelen / sliceSize;
|
||||
if (filelen % sliceSize != 0) {
|
||||
sliceNumLong++;
|
||||
}
|
||||
// TODO Auto-generated method stub
|
||||
while (true) {
|
||||
Long progressInteger = upLoadClient.recvCount.get();
|
||||
System.out.println("当前已经上传的数据片个数:" + progressInteger);
|
||||
Double progressPercentDouble=Math.floor((progressInteger*100)/sliceNumLong);
|
||||
Integer progressPercentInteger=progressPercentDouble.intValue();
|
||||
String textString=progressPercentInteger.toString()+"%";
|
||||
// 更新进度条
|
||||
// String textString=progressInteger.toString()+ "/" + cycleInteger;
|
||||
if (!text.getText().equals(textString)) {
|
||||
updateProgress(progressInteger, sliceNumLong);
|
||||
text.setText(textString);
|
||||
}
|
||||
//如果当前进度条
|
||||
if (progressInteger.equals(sliceNumLong)) {
|
||||
text.setText("100%");
|
||||
updateProgress(1,1);
|
||||
System.out.println("***************监听进度条的线程结束监听*************");
|
||||
break;
|
||||
}
|
||||
try {
|
||||
Thread.sleep(30);
|
||||
} catch (InterruptedException e) {
|
||||
System.out.println(e.getMessage());
|
||||
text.setText("100%");
|
||||
updateProgress(1,1);
|
||||
System.out.println("***************监听进度条的线程结束监听*************");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (codeInteger == 200) {
|
||||
flagSuccess++;
|
||||
System.out.println("数据分片"+i+"传输结果[200表示成功]: "+codeInteger);
|
||||
// updateMessage("");
|
||||
updateProgress(i + 1, cycle+1);
|
||||
}else{
|
||||
System.out.println("数据分片"+i+"传输结果[200表示成功]: "+codeInteger);
|
||||
// updateMessage("");
|
||||
updateProgress(i + 1, cycle+1);
|
||||
}
|
||||
}
|
||||
//每个分片都上传成功
|
||||
if (flagSuccess == (cycle + 1)) {
|
||||
});
|
||||
// 先发送一个开始上传信号
|
||||
String serverFilePath = serverpath + MinoaDataAPI.getPureFileNameFromWindows(file.getAbsolutePath());
|
||||
// ECOSUtil.sendUploadFileBeginSignal(serverFilePath);
|
||||
listenThread.start();
|
||||
// 上传文件
|
||||
boolean res = upLoadClient.uploadData();
|
||||
// 上传完成或取消上传后,取消上传进度监听
|
||||
listenThread.interrupt();
|
||||
Long endTime = System.currentTimeMillis();
|
||||
System.out.println("耗时:" + (endTime - startTime) + "ms");
|
||||
LoggerUtil.insertFileAction(file.getAbsolutePath(),"上传",(endTime - startTime) + "ms");
|
||||
// 每个分片都上传成功
|
||||
if (res) {
|
||||
System.out.println("已成功将文件" + file.getAbsolutePath() + "上传至服务器" + serverpath + "目录下。");
|
||||
// String serverFilePath = serverpath + MinoaDataAPI.getPureFileNameFromWindows(file.getAbsolutePath());
|
||||
// ECOSUtil.sendUploadFileEndSignal(serverFilePath);
|
||||
} else {
|
||||
System.out.println("由于未知原因,本地文件" + file.getAbsolutePath() + "上传服务器失败。");
|
||||
}
|
||||
//设置确认按钮
|
||||
button.setDisable(false);
|
||||
// System.out.println("文件上传线程:我干完活儿啦");
|
||||
// 设置取消按钮状态
|
||||
button.setDisable(true);
|
||||
// 设置确认按钮状态
|
||||
sureButton.setDisable(false);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// 上传本地文件到服务器的共享文件夹下
|
||||
public Integer uploadFileToServerSharedFolder(File file) {
|
||||
Integer res=loginerController.sendFileToServer(file, this.sharedFileServerPath);
|
||||
public boolean uploadFileToServerSharedFolder(File file) {
|
||||
// Integer res=loginerController.sendFileToServer(file, this.sharedFileServerPath);
|
||||
Long startTime = System.currentTimeMillis();
|
||||
UpLoadClientBasedFacePool upLoadClient = new UpLoadClientBasedFacePool(
|
||||
file,this.sharedFileServerPath,threadNumberForFileTransfer);
|
||||
// 下载文件
|
||||
boolean res = ((UpLoadClientBasedFacePool) upLoadClient).uploadData();
|
||||
Long endTime = System.currentTimeMillis();
|
||||
System.out.println("耗时:" + (endTime - startTime) + "ms");
|
||||
return res;
|
||||
}
|
||||
|
||||
//请求服务器某文件的字节长度
|
||||
public Integer getServerFileByteLength(String filename){
|
||||
public Long getServerFileByteLength(String filename){
|
||||
return loginerController.getServerFileLength(filename);
|
||||
}
|
||||
|
||||
@@ -709,27 +879,49 @@ public class MainApp extends Application {
|
||||
showLoginOverview();
|
||||
}
|
||||
|
||||
// 展示登录界面
|
||||
public void showLoginOverview() {
|
||||
try {
|
||||
// 加载overview
|
||||
FXMLLoader loader = new FXMLLoader();
|
||||
loader.setLocation(MainApp.class.getClassLoader().getResource("fxml/login/LoginOverview.fxml"));
|
||||
AnchorPane loginOverview = (AnchorPane) loader.load();
|
||||
// 展示登录界面
|
||||
public void showLoginOverview() {
|
||||
try {
|
||||
// 加载overview
|
||||
FXMLLoader loader = new FXMLLoader();
|
||||
loader.setLocation(MainApp.class.getClassLoader().getResource("fxml/login/LoginOverview.fxml"));
|
||||
AnchorPane loginOverview = (AnchorPane) loader.load();
|
||||
|
||||
// 设置scene
|
||||
Scene scene = new Scene(loginOverview);
|
||||
primaryStage.setScene(scene);
|
||||
// 设置scene
|
||||
Scene scene = new Scene(loginOverview);
|
||||
|
||||
// 传参给控制器
|
||||
loginerController = loader.getController();
|
||||
loginerController.setMainApp(this);
|
||||
// 传参给控制器
|
||||
loginerController = loader.getController();
|
||||
loginerController.setMainApp(this);
|
||||
|
||||
primaryStage.show();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
// 判断是否是登录状态,且账号密码是正确的
|
||||
boolean m_flag=false;
|
||||
boolean isLoginning= KeepLoginStatus.getLogineStatus();
|
||||
Loginer m_loginer=KeepLoginStatus.getLoginerInfo();
|
||||
if((isLoginning==true)&&(m_loginer.getUserName()!=null)&&(m_loginer.getPassWord()!=null)){
|
||||
System.out.println("login status: "+isLoginning);
|
||||
System.out.println("loginer name: "+m_loginer.getUserName());
|
||||
System.out.println("loginer password: "+m_loginer.getPassWord());
|
||||
String loginString=loginerController.getLoginJsonString(
|
||||
m_loginer.getUserName(),m_loginer.getPassWord());
|
||||
if(loginerController.checkPass(loginString)){
|
||||
m_flag=true;
|
||||
}
|
||||
}
|
||||
|
||||
if(m_flag){
|
||||
// 是登录状态且账号密码正确
|
||||
isNeedKnowLoginStatus=true;
|
||||
iniShow();
|
||||
}else{
|
||||
// 否则
|
||||
primaryStage.setScene(scene);
|
||||
}
|
||||
primaryStage.show();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
// 使用弹窗展示设置界面
|
||||
public void showSettingOverview() {
|
||||
|
||||
@@ -0,0 +1,205 @@
|
||||
package cn.minoa.dataRequestInterface;
|
||||
|
||||
/**
|
||||
* @author mac
|
||||
* @description
|
||||
* 拥塞窗口
|
||||
* @date 2020-03-24 10:25
|
||||
*/
|
||||
public class CongestionWindow {
|
||||
|
||||
//拥塞窗口大小
|
||||
private Double cwnd;
|
||||
|
||||
//表示当前正在发送的数据,发送一条数据需要加一,收到成功恢复需要减一
|
||||
private Double inFlight;
|
||||
|
||||
//拥塞窗口阈值
|
||||
private Double thresh;
|
||||
|
||||
//下一次窗口减小的界限
|
||||
private Integer nSupress = 0;
|
||||
|
||||
//收到数据包的数量,收到一个数据包进行加一操作
|
||||
private Long nIndata = 0l;
|
||||
|
||||
//发送兴趣包的数量,发出一个兴趣包进行加一操作
|
||||
private Long nOutInterest = 0l;
|
||||
|
||||
//更新nsupress时的一个比率
|
||||
private static Double rate = 0.5d;
|
||||
|
||||
public CongestionWindow(){
|
||||
this.cwnd = 4d;
|
||||
this.thresh = 300d;
|
||||
this.inFlight = 0d;
|
||||
}
|
||||
public CongestionWindow(Double cwnd, Double thresh, Double inFlight){
|
||||
this.inFlight = inFlight;
|
||||
this.cwnd = cwnd;
|
||||
this.thresh = thresh;
|
||||
}
|
||||
|
||||
/**
|
||||
* 当前窗口是否为空
|
||||
* @return
|
||||
*/
|
||||
public boolean empty(){
|
||||
boolean res = false;
|
||||
synchronized (this){
|
||||
if (inFlight == 0){
|
||||
res = true;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* 当前窗口是否已满
|
||||
* @return
|
||||
*/
|
||||
public boolean full(){
|
||||
boolean res = false;
|
||||
synchronized (this){
|
||||
if(cwnd == inFlight){
|
||||
res = true;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前还能发送多少数据
|
||||
* 如果不能发送数据,返回值为0
|
||||
* @return
|
||||
*/
|
||||
public int getAvailableCwnd(){
|
||||
int res = 0;
|
||||
synchronized (this){
|
||||
if(inFlight >= cwnd){
|
||||
res = 0;
|
||||
}else{
|
||||
res = (int)(cwnd - inFlight);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 在onData函数中
|
||||
* 收到一个数据包,执行加一操作,需要加锁
|
||||
*/
|
||||
public void nIndataIncrease(){
|
||||
synchronized (this){
|
||||
nIndata++;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 发出一个兴趣包,执行加一操作,不需要加锁
|
||||
*/
|
||||
public void nOutInterestIncrease(){
|
||||
nOutInterest++;
|
||||
}
|
||||
|
||||
/**
|
||||
* inFlight加一
|
||||
*/
|
||||
public void inFlightIncrease(){
|
||||
synchronized (this){
|
||||
this.inFlight++;
|
||||
}
|
||||
}
|
||||
|
||||
public void inFlightIncrease(int inFlight){
|
||||
synchronized (this){
|
||||
this.inFlight += inFlight;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* inFliehgt减一
|
||||
*/
|
||||
public void inFlightDecrease(){
|
||||
synchronized (this){
|
||||
this.inFlight--;
|
||||
}
|
||||
}
|
||||
public void inFlightDecrease(int inFlight){
|
||||
synchronized (this){
|
||||
this.inFlight -= inFlight;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 增加拥塞窗口的值
|
||||
*
|
||||
*/
|
||||
public void cwndIncrease(){
|
||||
|
||||
synchronized (this){
|
||||
if(this.cwnd < this.thresh){
|
||||
//慢开始算法
|
||||
this.cwnd += 1;
|
||||
/*if(this.cwnd > this.thresh){
|
||||
this.thresh = this.cwnd;
|
||||
}*/
|
||||
}else{
|
||||
//拥塞避免算法
|
||||
this.cwnd += (1.0/this.cwnd);
|
||||
}
|
||||
}
|
||||
System.out.println("-----------------------------------------cwnd:" + cwnd + ", thresh:" + thresh);
|
||||
}
|
||||
|
||||
/**
|
||||
* 减少拥塞窗口的值
|
||||
* 每当检测到拥塞时,就需要执行此函数
|
||||
*/
|
||||
public void cwndDecrease(){
|
||||
synchronized (this){
|
||||
if(nIndata >= nSupress){
|
||||
this.thresh = Math.floor(this.cwnd/2);
|
||||
this.cwnd = this.thresh;
|
||||
nSupress = (int)(nOutInterest + rate*(nOutInterest - nIndata));
|
||||
}
|
||||
}
|
||||
System.out.println("-----------------------------------------cwnd:" + cwnd + ", thresh:" + thresh);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 设置拥塞窗口大小
|
||||
* @param cwnd
|
||||
*/
|
||||
public void setCwnd(Double cwnd){
|
||||
synchronized (this){
|
||||
this.cwnd = cwnd;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得当前拥塞窗口大小
|
||||
* @return
|
||||
*/
|
||||
public Integer getCwnd(){
|
||||
|
||||
int res = 0;
|
||||
synchronized (this){
|
||||
res = this.cwnd.intValue();
|
||||
}
|
||||
return res;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "CongestionWindow {" +
|
||||
"cwnd=" + cwnd +
|
||||
", inFlight=" + inFlight +
|
||||
", thresh=" + thresh +
|
||||
'}';
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2,28 +2,30 @@ package cn.minoa.dataRequestInterface;
|
||||
//缓存服务器的回执数据
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class DataCacheQueue {
|
||||
//存储数据回执
|
||||
public Map<Long, ResponseData> responseDataMap;
|
||||
|
||||
// public static volatile Map<Long, ResponseData> responseDataMap;
|
||||
public static volatile ConcurrentHashMap<Long, ResponseData> responseDataMap = new ConcurrentHashMap<Long, ResponseData>();
|
||||
|
||||
public DataCacheQueue() {
|
||||
// TODO Auto-generated constructor stub
|
||||
responseDataMap=new TreeMap<Long, ResponseData>();
|
||||
// responseDataMap=new TreeMap<Long, ResponseData>();
|
||||
responseDataMap=new ConcurrentHashMap<Long, ResponseData>();
|
||||
}
|
||||
|
||||
|
||||
//放入一个数据
|
||||
public void setResponseData(Long seq,ResponseData rd) {
|
||||
public static void setResponseData(Long seq,ResponseData rd) {
|
||||
responseDataMap.put(seq, rd);
|
||||
}
|
||||
|
||||
|
||||
//根据seq获取ResponseData
|
||||
public ResponseData getResponseDataBySeq(Long seq) {
|
||||
public static ResponseData getResponseDataBySeq(Long seq) {
|
||||
//等待数据回执
|
||||
while(!responseDataMap.containsKey(seq)) {
|
||||
try {
|
||||
Thread.sleep(10);
|
||||
Thread.sleep(1);
|
||||
} catch (InterruptedException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
@@ -33,11 +35,20 @@ public class DataCacheQueue {
|
||||
responseDataMap.remove(seq);
|
||||
return rd;
|
||||
}
|
||||
|
||||
|
||||
//判断是否为空
|
||||
public boolean isEmpty() {
|
||||
public static boolean isEmpty() {
|
||||
return responseDataMap.isEmpty();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public static void showMapData(){
|
||||
System.out.println("this is responseDataMap info:");
|
||||
for(Map.Entry<Long, ResponseData> entry : responseDataMap.entrySet()){
|
||||
System.out.println("entry-key:" + entry.getKey() + ", entry-value:");
|
||||
entry.getValue().printSelf();
|
||||
|
||||
}
|
||||
System.out.println("--------------- end ----------------");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,133 +0,0 @@
|
||||
package cn.minoa.dataRequestInterface;
|
||||
|
||||
import org.json.JSONObject;
|
||||
|
||||
import cn.minoa.MainApp;
|
||||
|
||||
public class DataTestMain {
|
||||
//文件操作命令
|
||||
static private String getFileActionJson(String uuid,String cmd) {
|
||||
JSONObject jsonObject =new JSONObject();
|
||||
String commandString="/fileAction";
|
||||
String usernameString="wefree";
|
||||
String uuidString=uuid;
|
||||
String cmdString=cmd;
|
||||
String filename="/";
|
||||
try {
|
||||
jsonObject.put("command", commandString);
|
||||
jsonObject.put("username", usernameString);
|
||||
jsonObject.put("uuid", uuidString);
|
||||
jsonObject.put("fileCmd", cmdString);
|
||||
jsonObject.put("filename", filename);
|
||||
} catch (Exception e) {
|
||||
// TODO: handle exception
|
||||
System.out.println("exception: " + e.getMessage());
|
||||
}
|
||||
return jsonObject.toString();
|
||||
}
|
||||
|
||||
//发送消息
|
||||
static private String getSendRTMsgJson(String uuid,String msgTail) {
|
||||
JSONObject jsonObject =new JSONObject();
|
||||
String commandString="/sendRTMsg";
|
||||
String fromString="oa_wefree";
|
||||
String toString="wefree";
|
||||
String uuidString=uuid;
|
||||
String msgString="hello,wefree. iam oa_wefree. --"+msgTail;
|
||||
try {
|
||||
jsonObject.put("command", commandString);
|
||||
jsonObject.put("from", fromString);
|
||||
jsonObject.put("to", toString);
|
||||
jsonObject.put("uuid", uuidString);
|
||||
jsonObject.put("msg", msgString);
|
||||
} catch (Exception e) {
|
||||
// TODO: handle exception
|
||||
System.out.println("exception: " + e.getMessage());
|
||||
}
|
||||
return jsonObject.toString();
|
||||
}
|
||||
|
||||
//请求通知消息
|
||||
static private String getGetInformJson(Integer pageNo,String uuidString) {
|
||||
JSONObject jsonObject =new JSONObject();
|
||||
String commandString="/getInform";
|
||||
String usernameString="wefree";
|
||||
Integer pageNoInteger=pageNo;
|
||||
Integer pageSizeInteger=10;
|
||||
try {
|
||||
jsonObject.put("command", commandString);
|
||||
jsonObject.put("username", usernameString);
|
||||
jsonObject.put("uuid", uuidString);
|
||||
jsonObject.put("pageNo", pageNoInteger);
|
||||
jsonObject.put("pageSize", pageSizeInteger);
|
||||
} catch (Exception e) {
|
||||
// TODO: handle exception
|
||||
System.out.println("exception: " + e.getMessage());
|
||||
}
|
||||
return jsonObject.toString();
|
||||
}
|
||||
|
||||
public static void main(String args[]){
|
||||
MainApp mainApp=new MainApp();
|
||||
MinoaDataAPI minoaDataAPI=new MinoaDataAPI(mainApp);
|
||||
//test register
|
||||
// minoaDataAPI.executeOrder("/register", orderInfo);
|
||||
//test login
|
||||
OrderInfo loginOrderInfo=new OrderInfo();
|
||||
loginOrderInfo.setSeq((long) 0);
|
||||
loginOrderInfo.setLoginJson();
|
||||
minoaDataAPI.executeOrder("/login", loginOrderInfo);
|
||||
ResponseData responseData=minoaDataAPI.dataCacheQueue.getResponseDataBySeq((long) 0);
|
||||
responseData.printSelf();
|
||||
String uuidString=responseData.getUuidByPraseLoginData();
|
||||
//test getUsers
|
||||
// minoaDataAPI.executeOrder("/getUsers", orderInfo);
|
||||
//test sendRTMsg
|
||||
// minoaDataAPI.executeOrder("/sendRTMsg", orderInfo);
|
||||
//test getRTMsg
|
||||
// minoaDataAPI.executeOrder("/getRTMsg", orderInfo);
|
||||
//test getRTMsgLog
|
||||
// minoaDataAPI.executeOrder("/getRTMsgLog", orderInfo);
|
||||
|
||||
//制造点假数据出来[wefree=>oa_wefree]
|
||||
// OrderInfo orderInfo=new OrderInfo();
|
||||
// String sendJsonString;
|
||||
// for(int i=1;i<5;i++) {
|
||||
// orderInfo.setSeq((long) i);
|
||||
// sendJsonString=getSendRTMsgJson(uuidString,String.valueOf(i));
|
||||
// orderInfo.setJsonString(sendJsonString);
|
||||
// minoaDataAPI.executeOrder("/sendRTMsg", orderInfo);
|
||||
// responseData=minoaDataAPI.dataCacheQueue.getResponseDataBySeq((long) i);
|
||||
// responseData.printSelf();
|
||||
// }
|
||||
|
||||
//测试请求通知信息
|
||||
// OrderInfo orderInfo=new OrderInfo();
|
||||
// orderInfo.setSeq((long)1);
|
||||
// orderInfo.setJsonString(getGetInformJson(0,uuidString));
|
||||
// minoaDataAPI.executeOrder("/getInform", orderInfo);
|
||||
// responseData=minoaDataAPI.dataCacheQueue.getResponseDataBySeq((long) 1);
|
||||
// responseData.printSelf();
|
||||
|
||||
//测试云文件上传下载
|
||||
OrderInfo orderInfo=new OrderInfo();
|
||||
|
||||
orderInfo.setSeq((long)1);
|
||||
orderInfo.setJsonString(getFileActionJson(uuidString, "ls"));
|
||||
minoaDataAPI.executeOrder("/fileAction", orderInfo);
|
||||
responseData=minoaDataAPI.dataCacheQueue.getResponseDataBySeq((long) 1);
|
||||
responseData.printSelf();
|
||||
|
||||
orderInfo.setSeq((long)2);
|
||||
orderInfo.setJsonString(getFileActionJson(uuidString, "rm"));
|
||||
minoaDataAPI.executeOrder("/fileAction", orderInfo);
|
||||
responseData=minoaDataAPI.dataCacheQueue.getResponseDataBySeq((long) 2);
|
||||
responseData.printSelf();
|
||||
|
||||
orderInfo.setSeq((long)3);
|
||||
orderInfo.setJsonString(getFileActionJson(uuidString, "mkdir"));
|
||||
minoaDataAPI.executeOrder("/fileAction", orderInfo);
|
||||
responseData=minoaDataAPI.dataCacheQueue.getResponseDataBySeq((long) 3);
|
||||
responseData.printSelf();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
package cn.minoa.dataRequestInterface;
|
||||
// 多线程上传下载:数据收发接口【3/3】
|
||||
import cn.minoa.MainApp;
|
||||
import org.json.JSONObject;
|
||||
|
||||
/**
|
||||
* @author mac
|
||||
* @description
|
||||
* @date 2020-03-16 11:16
|
||||
*/
|
||||
public class DownAndUpLoadData {
|
||||
|
||||
/**
|
||||
* 构造下载文件的json信息
|
||||
* @param filename
|
||||
* @param sliceNo
|
||||
* @return
|
||||
*/
|
||||
public static String getDownloadFileJson(String filename, Integer sliceNo) {
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
String commandString;
|
||||
if(filename.contains("/")){
|
||||
commandString = "/downloadFile";
|
||||
}else{
|
||||
commandString="/downloadShareFile";
|
||||
}
|
||||
String usernameString = MainApp.loginer.getUserName();
|
||||
String uuidString = MainApp.loginer.getUuid();
|
||||
String filenameString = filename;
|
||||
Integer sliceNoInteger = sliceNo;
|
||||
try {
|
||||
jsonObject.put("command", commandString);
|
||||
jsonObject.put("username", usernameString);
|
||||
jsonObject.put("uuid", uuidString);
|
||||
jsonObject.put("filename", filenameString);
|
||||
jsonObject.put("sliceNo", sliceNoInteger);
|
||||
} catch (Exception e) {
|
||||
// TODO: handle exception
|
||||
System.out.println("exception: " + e.getMessage());
|
||||
}
|
||||
System.out.println("getDownloadFileJson: "+jsonObject.toString());
|
||||
return jsonObject.toString();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 构造上传文件的json字符串
|
||||
* @param filename
|
||||
* @param offset
|
||||
* @return
|
||||
*/
|
||||
public static String getUploadFile(String filename, Long offset) {
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
String commandString = "/uploadFile";
|
||||
String usernameString = MainApp.loginer.getUserName();
|
||||
String uuidString = MainApp.loginer.getUuid();
|
||||
String filenameString = filename;
|
||||
Long offsetInteger = offset;
|
||||
try {
|
||||
jsonObject.put("command", commandString);
|
||||
jsonObject.put("username", usernameString);
|
||||
jsonObject.put("uuid", uuidString);
|
||||
jsonObject.put("filename", filenameString);
|
||||
jsonObject.put("offset", offsetInteger);
|
||||
} catch (Exception e) {
|
||||
// TODO: handle exception
|
||||
System.out.println("exception: " + e.getMessage());
|
||||
}
|
||||
return jsonObject.toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,331 @@
|
||||
package cn.minoa.dataRequestInterface;
|
||||
|
||||
import cn.minoa.MainApp;
|
||||
import net.named_data.jndn.*;
|
||||
import net.named_data.jndn.security.KeyChain;
|
||||
import net.named_data.jndn.security.SecurityException;
|
||||
import net.named_data.jndn.security.pib.PibImpl;
|
||||
import net.named_data.jndn.util.Blob;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
/**
|
||||
* @author mac
|
||||
* @description
|
||||
* @date 2020-03-22 18:28
|
||||
*/
|
||||
public class DownLoadClientBasedFacePool {
|
||||
|
||||
// 下载前缀
|
||||
private String orderPrefix = "/downloadFile";
|
||||
|
||||
// 要下载的文件的服务器路径
|
||||
private String filename;
|
||||
// 下载到的文件路径
|
||||
private String localDir;
|
||||
// 要下载的文件的总数据片个数
|
||||
private Integer sliceNumber;
|
||||
|
||||
// 当前排到应该下载的数据片序号
|
||||
private Integer currentSliceNo = 0;
|
||||
|
||||
// FacePool
|
||||
private FacePool facePool;
|
||||
|
||||
// 下载到本地的文件对象
|
||||
private RandomAccessFile randomAccessFile;
|
||||
|
||||
|
||||
// 滑动窗口控制类
|
||||
private CongestionWindow congestionWindow = new CongestionWindow();
|
||||
|
||||
// 存放发送失败数据的文件偏移
|
||||
private ConcurrentLinkedQueue<Integer> failedSlice = new ConcurrentLinkedQueue<>();
|
||||
|
||||
// 收到回复的数量
|
||||
public AtomicLong recvCount = new AtomicLong(0);
|
||||
|
||||
//发送的数据是否发送成功,key:第几个数据片,从0开始,value:该数据片超时次数
|
||||
private Map<Integer, Integer> timeOutNums = new ConcurrentHashMap<>();
|
||||
// 超时重传上限数值,某个兴趣包的重传次数超过此数值,则放弃重传,直接返回false
|
||||
private Integer timeoutCeil=15;
|
||||
|
||||
public DownLoadClientBasedFacePool(String filename, String localDir,
|
||||
Integer sliceNumber, Integer facepoolnumber) {
|
||||
this.filename = filename;
|
||||
this.localDir = localDir;
|
||||
System.out.println("localDir: "+this.localDir);
|
||||
this.sliceNumber = sliceNumber;
|
||||
this.facePool=new FacePool(facepoolnumber);
|
||||
this.facePool.start(MinoaDataAPI.minoaServerIpString, MinoaDataAPI.minoaServerPortInteger);
|
||||
System.out.println("***********FacePool中并发数:"+facepoolnumber+"***********");
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是否含有超时次数超过阈值的
|
||||
* @return
|
||||
*/
|
||||
private boolean isTimeOut(){
|
||||
for (Map.Entry<Integer, Integer> entry : timeOutNums.entrySet()) {
|
||||
System.out.println("Key = " + entry.getKey() + ", Value = " + entry.getValue());
|
||||
if(entry.getValue() > timeoutCeil){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 下载数据的主函数
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean downloadData() {
|
||||
// 先初始化一个本地文件
|
||||
try {
|
||||
String localName= MinoaDataAPI.getPureFileName(filename);
|
||||
this.randomAccessFile = new RandomAccessFile(localDir + localName, "rw");
|
||||
System.out.println("本地文件打开");
|
||||
} catch (FileNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
while (true) {
|
||||
//判断是否已经上传安成
|
||||
if (recvCount.longValue()>=this.sliceNumber) {
|
||||
break;
|
||||
}
|
||||
|
||||
// 判断是否已经被用户终止上传
|
||||
if(MainApp.isCancelFileTransferFlag){
|
||||
System.out.println("用户已主动中断下载");
|
||||
try {
|
||||
this.randomAccessFile.close();
|
||||
System.out.println("本地文件关闭");
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// 每一次发送数据
|
||||
int cwnd = 0;
|
||||
// 获取此次可以发送数据的个数
|
||||
while ((cwnd = congestionWindow.getAvailableCwnd()) <= 0) {
|
||||
try {
|
||||
Thread.sleep(1);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < cwnd; i++) {
|
||||
//TODO 首先发送failedmap中的数据
|
||||
if (failedSlice.size() > 0) {
|
||||
//首先发送failedslice中的数据
|
||||
Integer failSliceNo = failedSlice.poll();
|
||||
System.out.println("发送数据, name: " + filename + ", failSliceNo:" + failSliceNo+ ", failedSlice Size:" + failedSlice.size());
|
||||
recvData(failSliceNo);
|
||||
} else {
|
||||
if (this.currentSliceNo < this.sliceNumber) {
|
||||
System.out.println("发送数据, name: " + filename + ",current SliceNo:" + currentSliceNo + ", failedSlice Size:" + failedSlice.size());
|
||||
recvData(currentSliceNo);
|
||||
currentSliceNo++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(isTimeOut()){
|
||||
System.out.println("丢包超过阈值: "+timeoutCeil+" ,文件传输主动中断");
|
||||
this.facePool.shutdownNow();
|
||||
try {
|
||||
this.randomAccessFile.close();
|
||||
System.out.println("本地文件关闭");
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
this.facePool.shutdownNow();
|
||||
try {
|
||||
this.randomAccessFile.close();
|
||||
System.out.println("本地文件关闭");
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 下载一个数据片
|
||||
*
|
||||
* @param sliceNo
|
||||
*/
|
||||
private void recvData(Integer sliceNo) {
|
||||
facePool.submit(freeface -> {
|
||||
// 设置JSON请求命令
|
||||
OrderInfo orderInfo = new OrderInfo();
|
||||
Long seqLong = MainApp.getNewDataReqId();
|
||||
orderInfo.setSeq(seqLong);
|
||||
String testStr = DownAndUpLoadData.getDownloadFileJson(filename, sliceNo);
|
||||
System.out.println("*******************DownloadJson:" + testStr + "*******************");
|
||||
orderInfo.setJsonString(testStr);
|
||||
|
||||
// 发送兴趣包
|
||||
Name name = new Name(MinoaDataAPI.globalPrefixString + orderPrefix + "/" + seqLong);
|
||||
Interest interest = new Interest(name);
|
||||
interest.setMustBeFresh(true);
|
||||
interest.setInterestLifetimeMilliseconds(5000);
|
||||
try {
|
||||
ResponseData responseData = new ResponseData();
|
||||
responseData.setPrefix(orderPrefix);
|
||||
// 签名
|
||||
try {
|
||||
// 赋值兴趣包的附带信息,并标志区块链
|
||||
interest.setApplicationParameters(new Blob(orderInfo.getJsonString()));
|
||||
KeyManager.INSTANCE.getKeyChain().sign(interest);
|
||||
// MinoaDataAPI.keyChain.sign(interest);
|
||||
} catch (PibImpl.Error e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
} catch (KeyChain.Error e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
} catch (net.named_data.jndn.security.tpm.TpmBackEnd.Error e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
} catch (SecurityException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
String purefilename = MinoaDataAPI.getPureFileName(filename);
|
||||
DownLoadData downLoadData = new DownLoadData(this.localDir, purefilename, sliceNo);
|
||||
// 使用tcp发送数据请求兴趣包
|
||||
freeface.expressInterest(interest, downLoadData, downLoadData, downLoadData);
|
||||
// 滑动窗口:flight++
|
||||
congestionWindow.inFlightIncrease();
|
||||
// 滑动窗口:outInterest++
|
||||
congestionWindow.nOutInterestIncrease();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
public class DownLoadData implements OnData, OnTimeout, OnNetworkNack {
|
||||
// 下载到的本地路径
|
||||
private String localDir;
|
||||
//下载到本地后重命名的文件名称
|
||||
private String localName;
|
||||
// 下载到本地路径后的文件名称
|
||||
private Integer sliceNo;
|
||||
// 标记是否拿到网络回复(数据信息/超时信息)
|
||||
public boolean isFinished = false;
|
||||
|
||||
public DownLoadData(String localDir,String localName, Integer sliceNo) {
|
||||
this.localDir = localDir;
|
||||
this.localName = localName;
|
||||
this.sliceNo = sliceNo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onData(Interest interest, Data data) {
|
||||
// 将文件数据片写入本地文件
|
||||
try {
|
||||
synchronized (randomAccessFile) {
|
||||
System.out.println("开始写入文件数据分片... :" + localDir + localName);
|
||||
// RandomAccessFile randomAccessFile = new RandomAccessFile(localDir + localName, "rw");
|
||||
// int contentSize = data.getContent().size();
|
||||
// System.out.println("该数据分片长度为:" + contentSize);
|
||||
// byte[] content = new byte[contentSize];
|
||||
// for (int i = 0; i < contentSize; i++) {
|
||||
// content[i] = data.getContent().buf().get(i);
|
||||
// }
|
||||
// 设置数据分片写入到文件的起点位置
|
||||
randomAccessFile.seek(sliceNo * MainApp.sliceSize);
|
||||
// 写入数据分片
|
||||
randomAccessFile.write(data.getContent().getImmutableArray());
|
||||
// randomAccessFile.write(content, 0, contentSize);
|
||||
// randomAccessFile.close();
|
||||
System.out.println("写入文件数据分片完毕:" + localDir + localName);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
// 滑动窗口:flight--
|
||||
congestionWindow.inFlightDecrease();
|
||||
// 收到成功数据的数量++
|
||||
recvCount.incrementAndGet();
|
||||
// 滑动窗口:inData++
|
||||
congestionWindow.nIndataIncrease();
|
||||
System.out.println("第" + sliceNo + "片下载成功!");
|
||||
|
||||
// 处理拥塞:拥塞标记返回值,无意义,大于0就表示拥塞,直接进行窗口减小操作即可
|
||||
if (data.getCongestionMark() > 0) {
|
||||
System.out.println("&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&网络拥塞,滑动窗口减小,getCongestionMark:" + data.getCongestionMark());
|
||||
// 滑动窗口:cwndDecrease()
|
||||
congestionWindow.cwndDecrease();
|
||||
}else{
|
||||
// 滑动窗口:cwndIncrease()
|
||||
congestionWindow.cwndIncrease();
|
||||
}
|
||||
|
||||
if(timeOutNums.containsKey(this.sliceNo)){
|
||||
timeOutNums.remove(this.sliceNo);
|
||||
}
|
||||
|
||||
// 处理完成
|
||||
isFinished = true;
|
||||
}
|
||||
|
||||
// 处理兴趣包超时
|
||||
@Override
|
||||
public void onTimeout(Interest interest) {
|
||||
// 滑动窗口:flight--
|
||||
congestionWindow.inFlightDecrease();
|
||||
// 加入失败队列
|
||||
failedSlice.add(sliceNo);
|
||||
// 打印超时信息
|
||||
System.out.println("########## Time out for interest " + interest.getName()+"###########");
|
||||
|
||||
if(timeOutNums.containsKey(this.sliceNo)){
|
||||
int value = timeOutNums.get(this.sliceNo) + 1;
|
||||
timeOutNums.put(this.sliceNo,value);
|
||||
}else{
|
||||
timeOutNums.put(this.sliceNo,1);
|
||||
}
|
||||
// 处理完成
|
||||
isFinished = true;
|
||||
}
|
||||
|
||||
// 处理收到一个Nack包
|
||||
@Override
|
||||
public void onNetworkNack(Interest interest, NetworkNack networkNack){
|
||||
congestionWindow.inFlightDecrease();
|
||||
failedSlice.add(sliceNo);
|
||||
if(timeOutNums.containsKey(this.sliceNo)){
|
||||
int value = timeOutNums.get(this.sliceNo) + 1;
|
||||
timeOutNums.put(this.sliceNo,value);
|
||||
}else{
|
||||
timeOutNums.put(this.sliceNo,1);
|
||||
}
|
||||
// 打印超时信息
|
||||
System.out.println("########## Nack for interest " + interest.getName()
|
||||
+", Nack: "+networkNack.toString());
|
||||
isFinished=true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,162 @@
|
||||
package cn.minoa.dataRequestInterface;
|
||||
|
||||
import net.named_data.jndn.Face;
|
||||
import net.named_data.jndn.encoding.EncodingException;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
|
||||
/**
|
||||
* Face 池,里面可以创建多个face连接,每个face单独一个线程处理
|
||||
*/
|
||||
public class FacePool {
|
||||
private int poolSize;
|
||||
|
||||
// 采用阻塞队列来记录任务
|
||||
private LinkedBlockingQueue<Face> faceLinkedBlockingQueue;
|
||||
|
||||
private ArrayList<Face> faces;
|
||||
|
||||
private ExecutorService processEventThreadPool;
|
||||
private ExecutorService faceDealThreadPool;
|
||||
|
||||
public FacePool(int poolSize) {
|
||||
this.poolSize = poolSize;
|
||||
faces = new ArrayList<>();
|
||||
processEventThreadPool = Executors.newFixedThreadPool(poolSize);
|
||||
faceDealThreadPool = Executors.newFixedThreadPool(poolSize);
|
||||
faceLinkedBlockingQueue = new LinkedBlockingQueue<>();
|
||||
}
|
||||
|
||||
public FacePool start(String host, int port) {
|
||||
for (int i = 0; i < poolSize; i++) {
|
||||
faces.add(new Face(host, port));
|
||||
final int finalI = i;
|
||||
ProcessEventTask processEventTask = new ProcessEventTask(host, port, faces.get(i), i, task -> {
|
||||
// 发生错误则自动重新创建face,建立连接,然后将processEvent任务提交到线程池当中
|
||||
processEventThreadPool.submit(task);
|
||||
faces.set(finalI, task.getFace());
|
||||
});
|
||||
processEventThreadPool.submit(processEventTask);
|
||||
|
||||
// 初始时Face池里所有的Face都是可用的
|
||||
faceLinkedBlockingQueue.add(faces.get(i));
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public FacePool submit(AsyncUseFaceCallback asyncUseFaceCallback) {
|
||||
faceDealThreadPool.submit(() -> {
|
||||
try {
|
||||
Face face = faceLinkedBlockingQueue.take();
|
||||
asyncUseFaceCallback.onFaceAvailable(face);
|
||||
faceLinkedBlockingQueue.put(face);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
return this;
|
||||
}
|
||||
|
||||
public void shutdownNow() {
|
||||
if (!processEventThreadPool.isShutdown()) {
|
||||
processEventThreadPool.shutdownNow();
|
||||
}
|
||||
if (!faceDealThreadPool.isShutdown()) {
|
||||
faceDealThreadPool.shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
///// Callback
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
public interface AsyncUseFaceCallback {
|
||||
void onFaceAvailable(Face face);
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
///// Tasks
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static class ProcessEventTask implements Runnable {
|
||||
private Face face;
|
||||
private int id;
|
||||
private String host;
|
||||
private int port;
|
||||
private StatusCallback statusCallback;
|
||||
|
||||
public ProcessEventTask(String host, int port, Face face, int id, StatusCallback statusCallback) {
|
||||
this.face = face;
|
||||
this.id = id;
|
||||
this.host = host;
|
||||
this.port = port;
|
||||
this.statusCallback = statusCallback;
|
||||
}
|
||||
|
||||
public Face getFace() {
|
||||
return face;
|
||||
}
|
||||
|
||||
public void setFace(Face face) {
|
||||
this.face = face;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getHost() {
|
||||
return host;
|
||||
}
|
||||
|
||||
public void setHost(String host) {
|
||||
this.host = host;
|
||||
}
|
||||
|
||||
public int getPort() {
|
||||
return port;
|
||||
}
|
||||
|
||||
public void setPort(int port) {
|
||||
this.port = port;
|
||||
}
|
||||
|
||||
public StatusCallback getStatusCallback() {
|
||||
return statusCallback;
|
||||
}
|
||||
|
||||
public void setStatusCallback(StatusCallback statusCallback) {
|
||||
this.statusCallback = statusCallback;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
// System.out.println("faceId: " + id + "(host: " + host + ", port: " + port + ") -> start");
|
||||
try {
|
||||
while (true) {
|
||||
face.processEvents();
|
||||
// System.out.println("faceId: " + id + " -> processEvent");
|
||||
Thread.sleep(1);
|
||||
}
|
||||
} catch (IOException | EncodingException | InterruptedException e) {
|
||||
System.out.println(e.getMessage());
|
||||
this.face = new Face(this.host, this.port);
|
||||
if (this.statusCallback != null) {
|
||||
this.statusCallback.onError(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
interface StatusCallback {
|
||||
void onError(ProcessEventTask task);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
package cn.minoa.dataRequestInterface;
|
||||
|
||||
import net.named_data.jndn.Name;
|
||||
import net.named_data.jndn.security.KeyChain;
|
||||
import net.named_data.jndn.security.pib.Pib;
|
||||
import net.named_data.jndn.security.pib.PibIdentity;
|
||||
import net.named_data.jndn.security.pib.PibImpl;
|
||||
import net.named_data.jndn.security.pib.PibSqlite3;
|
||||
import net.named_data.jndn.security.tpm.Tpm;
|
||||
import net.named_data.jndn.security.tpm.TpmBackEnd;
|
||||
import net.named_data.jndn.security.tpm.TpmBackEndFile;
|
||||
import net.named_data.jndn.security.v2.CertificateV2;
|
||||
|
||||
public enum KeyManager {
|
||||
INSTANCE;
|
||||
private KeyChain keyChain = null;
|
||||
|
||||
KeyManager() {
|
||||
try {
|
||||
this.keyChain = getOrBuildKeyChain("/default");
|
||||
} catch (KeyChain.Error | PibImpl.Error | Pib.Error | Tpm.Error | TpmBackEnd.Error | CertificateV2.Error error) {
|
||||
error.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public KeyManager initKeyChain(String identityName) throws Pib.Error, Tpm.Error, TpmBackEnd.Error,
|
||||
CertificateV2.Error, KeyChain.Error, PibImpl.Error {
|
||||
this.keyChain = getOrBuildKeyChain(identityName);
|
||||
return this;
|
||||
}
|
||||
|
||||
public CertificateV2 getCertification(String identityName, String keyName) throws Pib.Error, PibImpl.Error,
|
||||
CertificateV2.Error, Tpm.Error, KeyChain.Error, TpmBackEnd.Error {
|
||||
return KeyManager.INSTANCE.initKeyChain(identityName)
|
||||
.getKeyChain()
|
||||
.getPib()
|
||||
.getIdentity(new Name(identityName))
|
||||
.getKey(new Name(keyName))
|
||||
.getDefaultCertificate();
|
||||
}
|
||||
|
||||
private KeyChain getOrBuildKeyChain(String identityName) throws
|
||||
KeyChain.Error, PibImpl.Error, Pib.Error, Tpm.Error, TpmBackEnd.Error, CertificateV2.Error {
|
||||
KeyChain keyChain = null;
|
||||
PibSqlite3 pibSqlite3 = new PibSqlite3("./ndn/pid");
|
||||
TpmBackEndFile tpmBackEndFile = new TpmBackEndFile("./ndn/tpm");
|
||||
try {
|
||||
keyChain = new KeyChain(pibSqlite3, tpmBackEndFile);
|
||||
PibIdentity identity = keyChain.getPib().getIdentity(new Name(identityName));
|
||||
keyChain.setDefaultIdentity(identity);
|
||||
} catch (Pib.Error error) {
|
||||
error.printStackTrace();
|
||||
System.out.println(error.getMessage());
|
||||
// 获取本地记录的用户的身份失败,可能是一个新的身份
|
||||
PibIdentity identity = keyChain.createIdentityV2(new Name(identityName));
|
||||
keyChain.setDefaultIdentity(identity);
|
||||
pibSqlite3.setDefaultKeyOfIdentity(identity.getName(), identity.getDefaultKey().getName());
|
||||
}
|
||||
return keyChain;
|
||||
}
|
||||
|
||||
// 判断本地是否有某个标识名对应的证书
|
||||
public boolean isInKeyChain(String identityName) throws
|
||||
KeyChain.Error, PibImpl.Error, Pib.Error, Tpm.Error, TpmBackEnd.Error, CertificateV2.Error {
|
||||
KeyChain keyChain = null;
|
||||
PibSqlite3 pibSqlite3 = new PibSqlite3("./ndn/pid");
|
||||
TpmBackEndFile tpmBackEndFile = new TpmBackEndFile("./ndn/tpm");
|
||||
try {
|
||||
keyChain = new KeyChain(pibSqlite3, tpmBackEndFile);
|
||||
PibIdentity identity = keyChain.getPib().getIdentity(new Name(identityName));
|
||||
keyChain.setDefaultIdentity(identity);
|
||||
return true;
|
||||
} catch (Pib.Error error) {
|
||||
// error.printStackTrace();
|
||||
System.out.println(error.getMessage());
|
||||
System.out.println("本地无该标识名称对应的证书:"+identityName);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public CertificateV2 getCertification(String identityName) throws Pib.Error, PibImpl.Error {
|
||||
return keyChain.getPib().getIdentity(new Name(identityName)).getDefaultKey().getDefaultCertificate();
|
||||
}
|
||||
|
||||
public KeyChain getKeyChain() {
|
||||
return keyChain;
|
||||
}
|
||||
|
||||
public void setKeyChain(KeyChain keyChain) {
|
||||
this.keyChain = keyChain;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -4,20 +4,24 @@ package cn.minoa.dataRequestInterface;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import cn.minoa.model.SingleNotice;
|
||||
import cn.minoa.util.KeyStorageUtil;
|
||||
import cn.minoa.util.StringByteLengthUtil;
|
||||
import net.named_data.jndn.*;
|
||||
import net.named_data.jndn.security.pib.Pib;
|
||||
import net.named_data.jndn.security.pib.PibImpl;
|
||||
import net.named_data.jndn.security.tpm.Tpm;
|
||||
import net.named_data.jndn.security.tpm.TpmBackEnd;
|
||||
import net.named_data.jndn.security.v2.CertificateV2;
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import cn.minoa.MainApp;
|
||||
import cn.minoa.model.SingleMessage;
|
||||
import net.named_data.jndn.Data;
|
||||
import net.named_data.jndn.Face;
|
||||
import net.named_data.jndn.Interest;
|
||||
import net.named_data.jndn.Name;
|
||||
import net.named_data.jndn.OnData;
|
||||
import net.named_data.jndn.encoding.EncodingException;
|
||||
import net.named_data.jndn.security.KeyChain;
|
||||
import net.named_data.jndn.security.SecurityException;
|
||||
@@ -28,73 +32,118 @@ import net.named_data.jndn.security.tpm.TpmBackEndMemory;
|
||||
import net.named_data.jndn.util.Blob;
|
||||
|
||||
public class MinoaDataAPI {
|
||||
static private String keyChainNameString = "/wefree";
|
||||
private String minoaServerIpString;
|
||||
private Integer minoaServerPortInteger;
|
||||
private String globalPrefixString;
|
||||
private String pidDbPathString;
|
||||
// private String minoaServerIpString = "121.15.171.89";
|
||||
// private Integer minoaServerPortInteger=6363;
|
||||
// private String globalPrefixString = "/ndn/edu/pkusz/OA";
|
||||
public static String keyChainNameString = "/default";
|
||||
public static String minoaServerIpString;
|
||||
public static Integer minoaServerPortInteger;
|
||||
public static String globalPrefixString;
|
||||
// public static String pidDbPathString;
|
||||
|
||||
KeyChain keyChain;
|
||||
Face face;
|
||||
public DataCacheQueue dataCacheQueue;
|
||||
// 同一兴趣包超时或丢包次数达到上限时的错误信息
|
||||
public static String timeoutError = "timeout times reaches the upper limit.";
|
||||
// 由于连接问题(多次超时/丢包),返回给主线程的错误码
|
||||
public static Integer timeoutCodeInteger = 333;
|
||||
// 同一兴趣包超时或丢包次数达到上限时的错误信息
|
||||
public static String nackError = "receive nack.";
|
||||
// 由于连接问题(多次超时/丢包),返回给主线程的错误码
|
||||
public static Integer nackCodeInteger = 334;
|
||||
|
||||
// KeyChain keyChain;
|
||||
public static Face face;
|
||||
public volatile DataCacheQueue dataCacheQueue;
|
||||
private MainApp mainApp;
|
||||
|
||||
// 标志连接是否正常
|
||||
private boolean isConnected;
|
||||
|
||||
//发送的数据是否发送成功,key:第几个数据片,从0开始,value:该数据片超时次数
|
||||
private Map<Long, Integer> timeOutNums = new ConcurrentHashMap<>();
|
||||
// 超时重传上限数值,某个兴趣包的重传次数超过此数值,则放弃重传,直接返回false
|
||||
private Integer timeoutCeil = 10;
|
||||
|
||||
public MinoaDataAPI(MainApp mainApp) {
|
||||
// TODO Auto-generated constructor stub
|
||||
minoaServerIpString=mainApp.minoaServerIpString;
|
||||
minoaServerPortInteger=mainApp.minoaServerPortInteger;
|
||||
globalPrefixString=mainApp.globalPrefixString;
|
||||
this.face = new Face(minoaServerIpString,minoaServerPortInteger);
|
||||
isConnected=false;
|
||||
this.dataCacheQueue = new DataCacheQueue();
|
||||
this.mainApp = mainApp;
|
||||
pidDbPathString=mainApp.getClientPath()+ File.separator+"ndn";
|
||||
System.out.println("pidDbPathString: "+pidDbPathString);
|
||||
runFace();
|
||||
// pidDbPathString=mainApp.getClientPath()+ File.separator+"ndn";
|
||||
// System.out.println("pidDbPathString: "+pidDbPathString);
|
||||
runFace(minoaServerIpString, minoaServerPortInteger);
|
||||
// 首先按照"/default"初始化KeyChain
|
||||
try {
|
||||
// 密钥“黑盒”
|
||||
PibSqlite3 pibSqlite3 = new PibSqlite3(pidDbPathString);
|
||||
TpmBackEndMemory tpmBackEndMemory = new TpmBackEndMemory();
|
||||
keyChain = new KeyChain(pibSqlite3, tpmBackEndMemory);
|
||||
PibIdentity identity = keyChain.getPib().getIdentity(new Name(keyChainNameString));
|
||||
keyChain.setDefaultIdentity(identity);
|
||||
|
||||
System.out.println(keyChain.getDefaultCertificateName().toUri());
|
||||
} catch (Exception e) {
|
||||
// TODO: handle exception
|
||||
System.out.println("exception: " + e.getMessage());
|
||||
KeyManager.INSTANCE.initKeyChain(keyChainNameString);
|
||||
} catch (Pib.Error | PibImpl.Error | Tpm.Error | TpmBackEnd.Error | CertificateV2.Error | KeyChain.Error error) {
|
||||
error.printStackTrace();
|
||||
}
|
||||
// 从本地初始化keyName
|
||||
String keyString= KeyStorageUtil.getKeyName();
|
||||
try {
|
||||
// 如果本地keyName指向的证书确实在keyChain中,就将该证书取出
|
||||
if((keyString!=null)&&(KeyManager.INSTANCE.isInKeyChain(keyString))){
|
||||
keyChainNameString=keyString;
|
||||
System.out.println("keyChainNameString: "+keyChainNameString);
|
||||
// 再次按照本地证书前缀初始化KeyChain
|
||||
try {
|
||||
KeyManager.INSTANCE.initKeyChain(keyChainNameString);
|
||||
} catch (Pib.Error | Error | Tpm.Error | TpmBackEnd.Error | CertificateV2.Error | KeyChain.Error error) {
|
||||
error.printStackTrace();
|
||||
}
|
||||
}
|
||||
} catch (Pib.Error | PibImpl.Error | Tpm.Error | TpmBackEnd.Error | CertificateV2.Error | KeyChain.Error error) {
|
||||
error.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断某个key对应的兴趣包的超时次数是否超过阈值
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private boolean isInterestTimeOut(Long timeoutMapKey) {
|
||||
if (timeOutNums.get(timeoutMapKey) > timeoutCeil) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// 开辟线程运行face
|
||||
private void runFace() {
|
||||
public boolean runFace(String ipString, Integer portInteger) {
|
||||
if (isConnected) {
|
||||
return true;
|
||||
}
|
||||
this.face = new Face(ipString, portInteger);
|
||||
isConnected = true;
|
||||
Thread thread = new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
// System.out.println("face is trying to link...");
|
||||
// TODO Auto-generated method stub
|
||||
try {
|
||||
while (true) {
|
||||
face.processEvents();
|
||||
// 线程暂时休眠
|
||||
try {
|
||||
Thread.sleep(5);
|
||||
} catch (InterruptedException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
Thread.sleep(1);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
} catch (InterruptedException | EncodingException | IOException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
} catch (EncodingException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
// e.printStackTrace();
|
||||
System.out.println(e.getMessage());
|
||||
isConnected = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
thread.start();
|
||||
return isConnected;
|
||||
}
|
||||
|
||||
public boolean runFace(String ipString) {
|
||||
return this.runFace(ipString, minoaServerPortInteger);
|
||||
}
|
||||
|
||||
public boolean runFace() {
|
||||
return this.runFace(minoaServerIpString, minoaServerPortInteger);
|
||||
}
|
||||
|
||||
// 开辟线程监听新消息/新通知/新审批
|
||||
@@ -303,14 +352,6 @@ public class MinoaDataAPI {
|
||||
singleMessage.setTime(timeLong);
|
||||
singleMessage.setToName(mainApp.loginer.getUserName());
|
||||
singleMessage.setMsgId(idInteger);
|
||||
// 加入前端数据内存
|
||||
// System.out.println("MinoaDataAPI-addNewMessage-singleMessageString: "+singleMessageString);
|
||||
// System.out.println("MinoaDataAPI-addNewMessage-fromName: "+fromNameString);
|
||||
// mainApp.messageLogMap.get(fromNameString).add(singleMessage);
|
||||
// //加入未读消息的列表中
|
||||
// mainApp.notReadMessageList.addNotReadMessage(singleMessage);
|
||||
// // 产生消息气泡
|
||||
// mainApp.newMessageBubble(singleMessage);
|
||||
// 将这条新消息交给mainApp处理
|
||||
mainApp.handleGetNewMessage(singleMessage);
|
||||
System.out.println("MinoaDataAPI-handleGetNewMessage success: " + singleMessageString);
|
||||
@@ -320,99 +361,6 @@ public class MinoaDataAPI {
|
||||
}
|
||||
}
|
||||
|
||||
// //判断是否有新消息产生=>废了,换接口了
|
||||
// private boolean judgeNewMessageProdution() {
|
||||
// //发送数据请求
|
||||
// Long seqLong=mainApp.getNewDataReqId();
|
||||
// OrderInfo orderInfo=new OrderInfo();
|
||||
// orderInfo.setSeq(seqLong);
|
||||
// orderInfo.setJsonString(getHasNewsJson());
|
||||
// mainApp.minoaDataAPI.executeOrder("/hasNews", orderInfo);
|
||||
// //获取回复消息
|
||||
// ResponseData responseData=mainApp.minoaDataAPI.dataCacheQueue.getResponseDataBySeq(seqLong);
|
||||
// JSONObject jsonObject=responseData.praseRequestData();
|
||||
//// System.out.println("hasNews-JSON: "+jsonObject.toString());
|
||||
// Integer codeInteger = null;
|
||||
// try {
|
||||
// codeInteger = jsonObject.getInt("code");
|
||||
// } catch (JSONException e) {
|
||||
// // TODO Auto-generated catch block
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
// if(codeInteger==200) {
|
||||
// String dataString;
|
||||
// try {
|
||||
// dataString = jsonObject.getString("data");
|
||||
// JSONObject dataJSONObject=new JSONObject(dataString);
|
||||
// Integer msgInteger=dataJSONObject.getInt("msg");
|
||||
// if(msgInteger>0) {
|
||||
// System.out.println(msgInteger);
|
||||
// return true;
|
||||
// }
|
||||
// } catch (JSONException e) {
|
||||
// // TODO Auto-generated catch block
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
// }
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// //获取是否有新消息产生的json字符串
|
||||
// private String getHasNewsJson() {
|
||||
// JSONObject jsonObject =new JSONObject();
|
||||
// String commandString="/hasNews";
|
||||
// String userNameString=mainApp.loginer.getUserName();
|
||||
// String uuidString=mainApp.loginer.getUuid();
|
||||
// try {
|
||||
// jsonObject.put("command", commandString);
|
||||
// jsonObject.put("username", userNameString);
|
||||
// jsonObject.put("uuid", uuidString);
|
||||
// } catch (Exception e) {
|
||||
// // TODO: handle exception
|
||||
// System.out.println("exception: " + e.getMessage());
|
||||
// }
|
||||
// return jsonObject.toString();
|
||||
// }
|
||||
|
||||
// 获取注册请求字符串
|
||||
// static private String getRegisterJson() {
|
||||
// JSONObject jsonObject = new JSONObject();
|
||||
// String mPubKey = "Bv0CsQcuCAR3Z2gwCANLRVkICH9+4yjVUHZaCAxjZXJ0LXJlcXVlc3QICf0AAAFv\nEUSBehQJGAECGQQANu6AFf0BJjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC\nggEBANbFutCAZqFjHEa16tYvy4lBgi9/zixKWQzE9I72vaG2Imym+6KR30qkAQOK\nh0uE5RD2YsGhRK99rde+JOqIfk2/sunhp4nctOS5f4DeuOty58ekrO+Co9ZFmNBI\nmyk5i/hakjBEd/vdD7b1VadDRep5mWs3rgCinZOUfVaZ4oKqSws7ZWMvOSlRMOOi\nVzj53P4poY109S6aWmi3xKw/D76vfJapjdOB9Dg7S3rz0Rve1F/ajHCXWLt4XU3k\nUCiBn3Qmt6UD/MyDBaaUCfOvHTN6yVPtN6aOtYJVBAWt/P1ahLYhWkSm6KvrwMt0\nRzy2lw/lPriT99REItc/0wK6XwkCAwEAARZGGwEBHBcHFQgEd2doMAgDS0VZCAh/\nfuMo1VB2Wv0A/Sb9AP4PMjAxOTEyMTdUMDAzMTQw/QD/DzIwMTkxMjI3VDAwMzEz\nORf9AQCM+8WROXfi8WD9DydfLuSUxV0v3KW/Gn422/puDrkwwi1R2ogsAUc2O8pp\npuMLjWrQOTgE6ZTg80uWoDSUjjk44aMjkL2SAfp62vHRbGFx7+dckHAtF+DS6NH7\nX2vojFHOg6fksOE1M7XqLHmEEctZrFVSnQO7nB3DfRg+BqzZC/iy+8YAvTIvqA1c\nNsKYkmNITB80aM1v2H7fKnV4ZJpZnW71G5vbaPUseeklalQ2vEuBgWdd/1PL/0Ml\nI52npzqoeKAEpLp+vBwGN5ryGtWKB12nNimpMfevQAn/9BVIg59lZ7DIlE0sWmgW\nnwDxIXKebdViOejHlKwNAykxRRWw";
|
||||
// String commandString = "/register";
|
||||
// String userNameString = "oa_wefree";
|
||||
// String passWordString = "12345678";
|
||||
// String phoneString = "10000000006";
|
||||
// Integer levelInteger = 0;
|
||||
// try {
|
||||
// jsonObject.put("command", commandString);
|
||||
// jsonObject.put("username", userNameString);
|
||||
// jsonObject.put("password", passWordString);
|
||||
// jsonObject.put("phone", phoneString);
|
||||
// jsonObject.put("publicKey", mPubKey);
|
||||
// jsonObject.put("level", levelInteger);
|
||||
// } catch (Exception e) {
|
||||
// System.out.println("exception: " + e.getMessage());
|
||||
// }
|
||||
// return jsonObject.toString();
|
||||
// }
|
||||
|
||||
// //"获取最近三天未读实时消息"
|
||||
// static private String getGetRTMsgJson() {
|
||||
// JSONObject jsonObject =new JSONObject();
|
||||
// String commandString="/getRTMsg";
|
||||
// String userNameString="oa_wefree";
|
||||
// String uuidString="29c8f0a4-52d7-4478-90f0-6136996dbe96";
|
||||
// try {
|
||||
// jsonObject.put("command", commandString);
|
||||
// jsonObject.put("username", userNameString);
|
||||
// jsonObject.put("uuid", uuidString);
|
||||
// } catch (Exception e) {
|
||||
// // TODO: handle exception
|
||||
// System.out.println("exception: " + e.getMessage());
|
||||
// }
|
||||
// return jsonObject.toString();
|
||||
// }
|
||||
|
||||
// 根据命令前缀获取相应的请求字符串【JSON】
|
||||
static private String getRequestStr(String orderPrefix, OrderInfo orderInfo) {
|
||||
String requestStr;
|
||||
@@ -475,77 +423,6 @@ public class MinoaDataAPI {
|
||||
return requestStr;
|
||||
}
|
||||
|
||||
// 执行文件下载的特殊数据请求语句
|
||||
// 执行数据请求语句
|
||||
public boolean executeOrder(String orderPrefix, OrderInfo orderInfo, String localDir, String localName) {
|
||||
// 获取json格式的数据请求字符串
|
||||
String requestStr = getRequestStr(orderPrefix, orderInfo);
|
||||
// System.out.println("requestStr: "+requestStr);
|
||||
// 命令前缀格式不对的情况下返回false
|
||||
if (requestStr.equals("*wrong command string*")) {
|
||||
System.out.println(requestStr);
|
||||
return false;
|
||||
}
|
||||
|
||||
// 发送数据兴趣包
|
||||
Name name = new Name(globalPrefixString + orderPrefix + "/" + orderInfo.getSeq());
|
||||
Interest interest = new Interest(name);
|
||||
interest.setMustBeFresh(true);
|
||||
try {
|
||||
// 文件下载
|
||||
interest.setApplicationParameters(new Blob(requestStr));
|
||||
// 密钥“黑盒”
|
||||
keyChain.sign(interest);
|
||||
this.expressTheDownloadInterest(orderPrefix, interest, orderInfo,localDir,localName);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
System.out.println("exception: " + e.getMessage());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// 执行数据请求语句
|
||||
public boolean executeOrder(String orderPrefix, OrderInfo orderInfo,String serverpath) {
|
||||
// 获取json格式的数据请求字符串
|
||||
String requestStr = getRequestStr(orderPrefix, orderInfo);
|
||||
// System.out.println("requestStr: "+requestStr);
|
||||
// 命令前缀格式不对的情况下返回false
|
||||
if (requestStr.equals("*wrong command string*")) {
|
||||
System.out.println(requestStr);
|
||||
return false;
|
||||
}
|
||||
|
||||
// 发送数据兴趣包
|
||||
Name name = new Name(globalPrefixString + orderPrefix + "/" + orderInfo.getSeq());
|
||||
Interest interest = new Interest(name);
|
||||
interest.setMustBeFresh(true);
|
||||
// System.out.println("interest name: "+name.toString());
|
||||
try {
|
||||
if (orderPrefix.equals("/downloadFile")) {
|
||||
// 文件下载
|
||||
interest.setApplicationParameters(new Blob(requestStr));
|
||||
// 密钥“黑盒”
|
||||
keyChain.sign(interest);
|
||||
this.expressTheDownloadInterest(orderPrefix, interest, orderInfo);
|
||||
} else if (orderPrefix.equals("/uploadFile")) {
|
||||
// 文件上传[interest和keyChain的参数设置在函数体内]
|
||||
this.expressTheUploadInterest(orderPrefix, interest, orderInfo,serverpath);
|
||||
}else {
|
||||
interest.setApplicationParameters(new Blob(requestStr));
|
||||
// System.out.println("setApplicationParameters-blob: "+requestStr);
|
||||
// 密钥“黑盒”
|
||||
keyChain.sign(interest);
|
||||
// System.out.println(interest.toUri());
|
||||
this.expressTheInterest(orderPrefix, interest, orderInfo.getSeq());
|
||||
}
|
||||
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
System.out.println("exception: " + e.getMessage());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// 执行数据请求语句
|
||||
public boolean executeOrder(String orderPrefix, OrderInfo orderInfo) {
|
||||
// 获取json格式的数据请求字符串
|
||||
@@ -561,322 +438,28 @@ public class MinoaDataAPI {
|
||||
Name name = new Name(globalPrefixString + orderPrefix + "/" + orderInfo.getSeq());
|
||||
Interest interest = new Interest(name);
|
||||
interest.setMustBeFresh(true);
|
||||
// System.out.println("interest name: "+name.toString());
|
||||
interest.setApplicationParameters(new Blob(requestStr));
|
||||
interest.setInterestLifetimeMilliseconds(2000);
|
||||
try {
|
||||
if (orderPrefix.equals("/downloadFile")) {
|
||||
// 文件下载
|
||||
interest.setApplicationParameters(new Blob(requestStr));
|
||||
// 密钥“黑盒”
|
||||
keyChain.sign(interest);
|
||||
this.expressTheDownloadInterest(orderPrefix, interest, orderInfo);
|
||||
} else if (orderPrefix.equals("/uploadFile")) {
|
||||
// 文件上传[interest和keyChain的参数设置在函数体内]
|
||||
this.expressTheUploadInterest(orderPrefix, interest, orderInfo,"/");
|
||||
}else {
|
||||
interest.setApplicationParameters(new Blob(requestStr));
|
||||
// System.out.println("setApplicationParameters-blob: "+requestStr);
|
||||
// 密钥“黑盒”
|
||||
keyChain.sign(interest);
|
||||
// System.out.println(interest.toUri());
|
||||
this.expressTheInterest(orderPrefix, interest, orderInfo.getSeq());
|
||||
}
|
||||
|
||||
// keyChain.sign(interest);
|
||||
// 使用KeyManager管理兴趣包签名
|
||||
KeyManager.INSTANCE.getKeyChain().sign(interest);
|
||||
this.expressTheInterest(orderPrefix, interest, orderInfo.getSeq());
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
System.out.println("exception: " + e.getMessage());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//文件上传到指定服务器路径下
|
||||
private void expressTheUploadInterest(String orderPrefix, Interest interest, OrderInfo orderInfo,String serverpath) {
|
||||
// 设置回执前缀
|
||||
ResponseData responseData = new ResponseData();
|
||||
responseData.setPrefix(orderPrefix);
|
||||
byte[] requestByte = null; // 请求数据
|
||||
// 重写ondata
|
||||
try {
|
||||
// 解析并修改文件名【window转server】
|
||||
String localFilePath = "";
|
||||
String serverFilePath = "";
|
||||
Integer offsetInteger = 0;
|
||||
try {
|
||||
// 解析
|
||||
JSONObject jsonObject = new JSONObject(orderInfo.getJsonString());
|
||||
offsetInteger = jsonObject.getInt("offset");
|
||||
localFilePath = jsonObject.getString("filename");
|
||||
serverFilePath = serverpath + getPureFileNameFromWindows(localFilePath);
|
||||
// 修改
|
||||
jsonObject.remove("filename");
|
||||
jsonObject.put("filename", serverFilePath);
|
||||
orderInfo.setJsonString(jsonObject.toString());
|
||||
System.out.println("request head str: " + orderInfo.getJsonString());
|
||||
System.out.println("head str length: "+orderInfo.getJsonString().length());
|
||||
System.out.println("head str byte length: "+ StringByteLengthUtil.getByteLength(orderInfo.getJsonString()));
|
||||
} catch (JSONException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
// 从本地读取数据
|
||||
byte[] content = new byte[10000]; // 文件分片内容
|
||||
try {
|
||||
RandomAccessFile randomAccessFile = new RandomAccessFile(localFilePath, "rw");
|
||||
// 设置文件的读取起点
|
||||
randomAccessFile.seek(offsetInteger);
|
||||
// 尝试读取数据
|
||||
int readLen = randomAccessFile.read(content, 0, 7000);
|
||||
randomAccessFile.close();
|
||||
System.out.println("file slice readLen == " + readLen);
|
||||
// int jsonLen = orderInfo.getJsonString().length();
|
||||
int jsonLen=StringByteLengthUtil.getByteLength(orderInfo.getJsonString());
|
||||
requestByte = new byte[jsonLen + 1 + readLen];
|
||||
System.arraycopy(orderInfo.getJsonString().getBytes("utf-8"), 0, requestByte, 0, jsonLen);
|
||||
requestByte[jsonLen] = 0;
|
||||
System.arraycopy(content, 0, requestByte, jsonLen + 1, readLen);
|
||||
} catch (IOException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
// 赋值兴趣包的附带信息,并标志区块链
|
||||
System.out.println("requestByte-len: " + requestByte.length);
|
||||
System.out.println("requestByte: " + requestByte);
|
||||
interest.setApplicationParameters(new Blob(requestByte));
|
||||
System.out.println("interest.getApplicationParameters().size(): "+interest.getApplicationParameters().size());
|
||||
// 密钥“黑盒”
|
||||
try {
|
||||
keyChain.sign(interest);
|
||||
} catch (Error e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
} catch (KeyChain.Error e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
} catch (net.named_data.jndn.security.tpm.TpmBackEnd.Error e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
} catch (SecurityException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
// 使用匿名内部类,发送数据请求兴趣包
|
||||
face.expressInterest(interest, new OnData() {
|
||||
@Override
|
||||
public void onData(Interest interest, Data data) {
|
||||
// 返回成功写入或失败写入消息
|
||||
responseData.setResponseData(data.getContent().toString());
|
||||
dataCacheQueue.setResponseData(orderInfo.getSeq(), responseData);
|
||||
}
|
||||
});
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
//文件上传=>默认上传到根目录;此函数应废弃不予使用
|
||||
// private void expressTheUploadInterest(String orderPrefix, Interest interest, OrderInfo orderInfo) {
|
||||
// // 设置回执前缀
|
||||
// ResponseData responseData = new ResponseData();
|
||||
// responseData.setPrefix(orderPrefix);
|
||||
// byte[] requestByte = null; // 请求数据
|
||||
// // 重写ondata
|
||||
// try {
|
||||
// // 解析并修改文件名【window转server】
|
||||
// String localFilePath = "";
|
||||
// String serverFilePath = "";
|
||||
// Integer offsetInteger = 0;
|
||||
// try {
|
||||
// // 解析
|
||||
// JSONObject jsonObject = new JSONObject(orderInfo.getJsonString());
|
||||
// offsetInteger = jsonObject.getInt("offset");
|
||||
// localFilePath = jsonObject.getString("filename");
|
||||
// serverFilePath = mainApp.fileServerBinPath + getPureFileNameFromWindows(localFilePath);
|
||||
// // 修改
|
||||
// jsonObject.remove("filename");
|
||||
// jsonObject.put("filename", serverFilePath);
|
||||
// orderInfo.setJsonString(jsonObject.toString());
|
||||
// System.out.println("request head str: " + orderInfo.getJsonString());
|
||||
// } catch (JSONException e) {
|
||||
// // TODO Auto-generated catch block
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
// // 从本地读取数据
|
||||
// byte[] content = new byte[10000]; // 文件分片内容
|
||||
// try {
|
||||
// RandomAccessFile randomAccessFile = new RandomAccessFile(localFilePath, "rw");
|
||||
// // 设置文件的读取起点
|
||||
// randomAccessFile.seek(offsetInteger);
|
||||
// // 尝试读取数据
|
||||
// int readLen = randomAccessFile.read(content, 0, 7000);
|
||||
// randomAccessFile.close();
|
||||
// System.out.println("file slice readLen == " + readLen);
|
||||
// int jsonLen = StringByteLengthUtil.getByteLength(orderInfo.getJsonString());
|
||||
// requestByte = new byte[jsonLen + 1 + readLen];
|
||||
// System.arraycopy(orderInfo.getJsonString().getBytes("utf-8"), 0, requestByte, 0, jsonLen);
|
||||
// requestByte[jsonLen] = 0;
|
||||
// System.arraycopy(content, 0, requestByte, jsonLen + 1, readLen);
|
||||
// } catch (IOException e) {
|
||||
// // TODO Auto-generated catch block
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
// // 赋值兴趣包的附带信息,并标志区块链
|
||||
// System.out.println("requestByte-len: " + requestByte.length);
|
||||
// System.out.println("requestByte: " + requestByte);
|
||||
// interest.setApplicationParameters(new Blob(requestByte));
|
||||
// // 密钥“黑盒”
|
||||
// try {
|
||||
// keyChain.sign(interest);
|
||||
// } catch (Error e) {
|
||||
// // TODO Auto-generated catch block
|
||||
// e.printStackTrace();
|
||||
// } catch (KeyChain.Error e) {
|
||||
// // TODO Auto-generated catch block
|
||||
// e.printStackTrace();
|
||||
// } catch (net.named_data.jndn.security.tpm.TpmBackEnd.Error e) {
|
||||
// // TODO Auto-generated catch block
|
||||
// e.printStackTrace();
|
||||
// } catch (SecurityException e) {
|
||||
// // TODO Auto-generated catch block
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
// // 使用匿名内部类,发送数据请求兴趣包
|
||||
// face.expressInterest(interest, new OnData() {
|
||||
// @Override
|
||||
// public void onData(Interest interest, Data data) {
|
||||
// // 返回成功写入或失败写入消息
|
||||
// responseData.setResponseData(data.getContent().toString());
|
||||
// dataCacheQueue.setResponseData(orderInfo.getSeq(), responseData);
|
||||
// }
|
||||
// });
|
||||
// } catch (IOException e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
// }
|
||||
|
||||
// // 合并两个Byte[]
|
||||
// public byte[] byteMerger(byte[] bt1, byte[] bt2) {
|
||||
// byte[] bt3 = new byte[bt1.length + bt2.length];
|
||||
// System.arraycopy(bt1, 0, bt3, 0, bt1.length);
|
||||
// System.arraycopy(bt2, 0, bt3, bt1.length, bt2.length);
|
||||
// return bt3;
|
||||
// }
|
||||
|
||||
//下载文件的数据分片到指定路径,并将文件重命名为指定文件名
|
||||
private void expressTheDownloadInterest(String orderPrefix, Interest interest, OrderInfo orderInfo,String localDir,String localName) {
|
||||
// 设置回执前缀
|
||||
ResponseData responseData = new ResponseData();
|
||||
responseData.setPrefix(orderPrefix);
|
||||
try {
|
||||
// 使用匿名内部类,发送数据请求兴趣包
|
||||
face.expressInterest(interest, new OnData() {
|
||||
@Override
|
||||
public void onData(Interest interest, Data data) {
|
||||
// 解析文件名、分片编号
|
||||
String filePathString = localDir;
|
||||
Integer sliceSizeInteger = mainApp.sliceSize;
|
||||
String filenameString = localName;
|
||||
Integer sliceNoInteger = null;
|
||||
try {
|
||||
JSONObject jsonObject = new JSONObject(orderInfo.getJsonString());
|
||||
sliceNoInteger = jsonObject.getInt("sliceNo");
|
||||
} catch (JSONException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
// 写入本地文件
|
||||
Integer successInfoInteger = 1;
|
||||
try {
|
||||
System.out.println("开始写入文件数据分片... :" + filePathString + filenameString);
|
||||
RandomAccessFile randomAccessFile = new RandomAccessFile(filePathString + filenameString, "rw");
|
||||
int contentSize = data.getContent().size();
|
||||
System.out.println("该数据分片长度为:" + contentSize);
|
||||
byte[] content = new byte[contentSize];
|
||||
for (int i = 0; i < contentSize; i++) {
|
||||
content[i] = data.getContent().buf().get(i);
|
||||
}
|
||||
// 设置数据分片写入到文件的起点位置
|
||||
randomAccessFile.seek(sliceNoInteger * sliceSizeInteger);
|
||||
// 写入数据分片
|
||||
randomAccessFile.write(content, 0, contentSize);
|
||||
randomAccessFile.close();
|
||||
System.out.println("写入文件数据分片完毕:" + filePathString + filenameString);
|
||||
successInfoInteger = 0;
|
||||
} catch (IOException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
// 返回成功写入或失败写入消息
|
||||
responseData.setResponseData(successInfoInteger.toString());
|
||||
dataCacheQueue.setResponseData(orderInfo.getSeq(), responseData);
|
||||
}
|
||||
});
|
||||
} catch (IOException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
//下载文件的数据分片到默认路径
|
||||
private void expressTheDownloadInterest(String orderPrefix, Interest interest, OrderInfo orderInfo) {
|
||||
// 设置回执前缀
|
||||
ResponseData responseData = new ResponseData();
|
||||
responseData.setPrefix(orderPrefix);
|
||||
try {
|
||||
// 使用匿名内部类,发送数据请求兴趣包
|
||||
face.expressInterest(interest, new OnData() {
|
||||
@Override
|
||||
public void onData(Interest interest, Data data) {
|
||||
// 解析文件名、分片编号
|
||||
String filePathString = mainApp.fileLocalPath;
|
||||
Integer sliceSizeInteger = mainApp.sliceSize;
|
||||
String filenameString = null;
|
||||
Integer sliceNoInteger = null;
|
||||
try {
|
||||
JSONObject jsonObject = new JSONObject(orderInfo.getJsonString());
|
||||
filenameString = getPureFileName(jsonObject.getString("filename"));
|
||||
sliceNoInteger = jsonObject.getInt("sliceNo");
|
||||
} catch (JSONException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
// 写入本地文件
|
||||
Integer successInfoInteger = 1;
|
||||
try {
|
||||
System.out.println("开始写入文件数据分片... :" + filePathString + filenameString);
|
||||
RandomAccessFile randomAccessFile = new RandomAccessFile(filePathString + filenameString, "rw");
|
||||
int contentSize = data.getContent().size();
|
||||
System.out.println("该数据分片长度为:" + contentSize);
|
||||
byte[] content = new byte[contentSize];
|
||||
for (int i = 0; i < contentSize; i++) {
|
||||
content[i] = data.getContent().buf().get(i);
|
||||
}
|
||||
// 设置数据分片写入到文件的起点位置
|
||||
randomAccessFile.seek(sliceNoInteger * sliceSizeInteger);
|
||||
// 写入数据分片
|
||||
randomAccessFile.write(content, 0, contentSize);
|
||||
randomAccessFile.close();
|
||||
System.out.println("写入文件数据分片完毕:" + filePathString + filenameString);
|
||||
successInfoInteger = 0;
|
||||
} catch (IOException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
// 返回成功写入或失败写入消息
|
||||
responseData.setResponseData(successInfoInteger.toString());
|
||||
dataCacheQueue.setResponseData(orderInfo.getSeq(), responseData);
|
||||
}
|
||||
});
|
||||
} catch (IOException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private void expressTheInterest(String orderPrefix, Interest interest, Long dataReqId) {
|
||||
ResponseData responseData = new ResponseData();
|
||||
responseData.setPrefix(orderPrefix);
|
||||
HandleInterestTimeOutAndNack handleInterestTimeOutAndNack =
|
||||
new HandleInterestTimeOutAndNack(orderPrefix, interest, dataReqId);
|
||||
try {
|
||||
// 使用匿名内部类,发送数据请求兴趣包
|
||||
if(orderPrefix.equals("/getDataSlice")) {
|
||||
if (orderPrefix.equals("/getDataSlice")) {
|
||||
//接收数据块
|
||||
face.expressInterest(interest, new OnData() {
|
||||
@Override
|
||||
@@ -886,15 +469,19 @@ public class MinoaDataAPI {
|
||||
byte[] content = new byte[contentSize];
|
||||
for (int i = 0; i < contentSize; i++) {
|
||||
content[i] = data.getContent().buf().get(i);
|
||||
System.out.print(i+": "+content[i]+" ");
|
||||
System.out.print(i + ": " + content[i] + " ");
|
||||
}
|
||||
System.out.println("");
|
||||
System.out.println("notice content: "+content);
|
||||
System.out.println("notice content: " + content);
|
||||
responseData.setFileSlice(content);
|
||||
dataCacheQueue.setResponseData(dataReqId, responseData);
|
||||
// 重置其超时次数记录
|
||||
if (timeOutNums.containsKey(dataReqId)) {
|
||||
timeOutNums.remove(dataReqId);
|
||||
}
|
||||
}
|
||||
});
|
||||
}else {
|
||||
}, handleInterestTimeOutAndNack, handleInterestTimeOutAndNack);
|
||||
} else {
|
||||
face.expressInterest(interest, new OnData() {
|
||||
@Override
|
||||
public void onData(Interest interest, Data data) {
|
||||
@@ -904,8 +491,12 @@ public class MinoaDataAPI {
|
||||
// System.out.println("ondata data: "+data.getContent().toString());
|
||||
responseData.setResponseData(data.getContent().toString());
|
||||
dataCacheQueue.setResponseData(dataReqId, responseData);
|
||||
// 重置其超时次数记录
|
||||
if (timeOutNums.containsKey(dataReqId)) {
|
||||
timeOutNums.remove(dataReqId);
|
||||
}
|
||||
}
|
||||
});
|
||||
}, handleInterestTimeOutAndNack, handleInterestTimeOutAndNack);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
// TODO Auto-generated catch block
|
||||
@@ -913,15 +504,8 @@ public class MinoaDataAPI {
|
||||
}
|
||||
}
|
||||
|
||||
// 写头像
|
||||
// public Integer writeHeadPhotoIntoLocalFile(String filenameString,
|
||||
// Integer sliceNo,Integer sliceSize,byte[] bytes) {
|
||||
// String pathString=mainApp.fileLocalPath;
|
||||
// return writeIntoLocalFile(pathString, filenameString, sliceNo, sliceSize, bytes);
|
||||
// }
|
||||
|
||||
// 根据包含路径的文件名获取纯文件名[linux下]
|
||||
public String getPureFileName(String pathfilename) {
|
||||
public static String getPureFileName(String pathfilename) {
|
||||
// 标记最后一个/的下标
|
||||
int indexLeft = -1;
|
||||
for (int i = 0; i < pathfilename.length(); i++) {
|
||||
@@ -939,7 +523,7 @@ public class MinoaDataAPI {
|
||||
}
|
||||
|
||||
// 根据包含路径的文件名获取纯文件名[windows本地]
|
||||
public String getPureFileNameFromWindows(String pathfilename) {
|
||||
public static String getPureFileNameFromWindows(String pathfilename) {
|
||||
// 标记最后一个/的下标
|
||||
int indexLeft = -1;
|
||||
for (int i = 0; i < pathfilename.length(); i++) {
|
||||
@@ -955,21 +539,91 @@ public class MinoaDataAPI {
|
||||
return pathfilename.substring(indexLeft + 1, pathfilename.length());
|
||||
}
|
||||
}
|
||||
// // 向指定本地文件写入指定数据分片=》被ondata调用
|
||||
// public Integer writeIntoLocalFile(String pathString,String filenameString,
|
||||
// Integer sliceNo,Integer sliceSize,byte[] bytes) {
|
||||
// try {
|
||||
// @SuppressWarnings("resource")
|
||||
// RandomAccessFile randomAccessFile=new RandomAccessFile(pathString+filenameString, "rw");
|
||||
// int contentSize=
|
||||
// randomAccessFile.write(bytes,sliceNo*sliceSize,bytes.length);
|
||||
// return 0;
|
||||
// } catch (IOException e) {
|
||||
// // TODO Auto-generated catch block
|
||||
// e.printStackTrace();
|
||||
// return 1;
|
||||
// }
|
||||
// }
|
||||
|
||||
// 解决处理兴趣包超时之后的重传问题[除上传下载外的兴趣包]
|
||||
public class HandleInterestTimeOutAndNack implements OnTimeout, OnNetworkNack {
|
||||
// 命令前缀
|
||||
private String orderPrefix;
|
||||
// 兴趣包
|
||||
private Interest interest;
|
||||
// 请求序列号
|
||||
private Long dataReqId;
|
||||
// 标记是否拿到网络回复(数据信息/超时信息):测试使用
|
||||
public boolean isFinished = false;
|
||||
|
||||
public HandleInterestTimeOutAndNack(String orderPrefix, Interest interest, Long dataReqId) {
|
||||
this.orderPrefix = orderPrefix;
|
||||
this.interest = interest;
|
||||
this.interest.setInterestLifetimeMilliseconds(2000);
|
||||
this.dataReqId = dataReqId;
|
||||
}
|
||||
|
||||
// 处理兴趣包超时
|
||||
@Override
|
||||
public void onTimeout(Interest interest) {
|
||||
// 打印超时信息
|
||||
System.out.println("########## Time out for interest " + interest.getName() + "###########");
|
||||
// 记录此次丢包/超时
|
||||
if (timeOutNums.containsKey(this.dataReqId)) {
|
||||
int value = timeOutNums.get(this.dataReqId) + 1;
|
||||
timeOutNums.put(this.dataReqId, value);
|
||||
} else {
|
||||
timeOutNums.put(this.dataReqId, 1);
|
||||
}
|
||||
// 根据是否多次超时,决定是否重传该兴趣包:暂时是全部重传
|
||||
// 后期可以改作,超时次数超过阈值时候,
|
||||
// 自拟定一个指定值放入数据回复缓存区,前端控制类收到该值,就
|
||||
// 判定网络极其拥塞,进行弹窗提示。
|
||||
if (!isInterestTimeOut(this.dataReqId)) {
|
||||
// 超时次数没有超过阈值:重传该兴趣包
|
||||
expressTheInterest(this.orderPrefix, this.interest, this.dataReqId);
|
||||
} else {
|
||||
// 超时次数超过阈值
|
||||
System.out.println("该兴趣包的超时次数超过阈值:" + timeoutCeil + "!!!");
|
||||
// 返回一个timeout信息放入datacache
|
||||
ResponseData responseData = new ResponseData();
|
||||
responseData.setPrefix(this.orderPrefix);
|
||||
responseData.setResponseData(getWrongAnswerJson(timeoutCodeInteger, timeoutError));
|
||||
dataCacheQueue.setResponseData(this.dataReqId, responseData);
|
||||
}
|
||||
// 打印重传信息
|
||||
System.out.println("########## Resend the interest " + interest.getName() + "###########");
|
||||
// 处理完成
|
||||
isFinished = true;
|
||||
}
|
||||
|
||||
// 处理收到一个Nack包
|
||||
@Override
|
||||
public void onNetworkNack(Interest interest, NetworkNack networkNack) {
|
||||
// 打印超时信息
|
||||
System.out.println("########## Nack for interest " + interest.getName()
|
||||
+ ", Nack: " + networkNack.toString());
|
||||
// 返回一个nack信息放入datacache
|
||||
ResponseData responseData = new ResponseData();
|
||||
responseData.setPrefix(this.orderPrefix);
|
||||
responseData.setResponseData(getWrongAnswerJson(nackCodeInteger, nackError));
|
||||
dataCacheQueue.setResponseData(this.dataReqId,responseData);
|
||||
isFinished = true;
|
||||
}
|
||||
}
|
||||
|
||||
// 构造一个json,给前端返回一个可以进行JSON解析的错误信息
|
||||
// 用以避免界面卡死
|
||||
public static String getWrongAnswerJson(Integer wrongAnswerCode, String wrongAnswerString) {
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
Integer code = wrongAnswerCode;
|
||||
String errMsg = wrongAnswerString;
|
||||
String data = "";
|
||||
try {
|
||||
jsonObject.put("code", code);
|
||||
jsonObject.put("errMsg", errMsg);
|
||||
jsonObject.put("data", data);
|
||||
} catch (Exception e) {
|
||||
// TODO: handle exception
|
||||
System.out.println("exception: " + e.getMessage());
|
||||
}
|
||||
return jsonObject.toString();
|
||||
}
|
||||
|
||||
// 关闭数据连接
|
||||
public void closeDataConn() {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package cn.minoa.dataRequestInterface;
|
||||
|
||||
import cn.minoa.MainApp;
|
||||
import org.json.JSONObject;
|
||||
|
||||
//请求数据时的附加请求信息
|
||||
@@ -19,6 +20,17 @@ public class OrderInfo {
|
||||
|
||||
public void setSeq(Long seqLong) {
|
||||
this.seqLong=seqLong;
|
||||
// 查看是否连接正常,否,重新尝试连接;
|
||||
// 重新连接失败,默认是ip有问题,返回一个错误包
|
||||
if(!MainApp.isFaceLinked()){
|
||||
System.out.println("!!!face link error!!!");
|
||||
ResponseData responseData=new ResponseData();
|
||||
String wrongAnswer=MinoaDataAPI.getWrongAnswerJson(336,
|
||||
"face link error");
|
||||
responseData.setPrefix("/wrongAnswer");
|
||||
responseData.setResponseData(wrongAnswer);
|
||||
MainApp.minoaDataAPI.dataCacheQueue.setResponseData(seqLong,responseData);
|
||||
}
|
||||
}
|
||||
|
||||
public Long getSeq() {
|
||||
|
||||
@@ -0,0 +1,396 @@
|
||||
package cn.minoa.dataRequestInterface;
|
||||
|
||||
import cn.minoa.MainApp;
|
||||
import cn.minoa.util.StringByteLengthUtil;
|
||||
import net.named_data.jndn.*;
|
||||
import net.named_data.jndn.security.KeyChain;
|
||||
import net.named_data.jndn.security.SecurityException;
|
||||
import net.named_data.jndn.security.pib.PibImpl;
|
||||
import net.named_data.jndn.util.Blob;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
/**
|
||||
* @author mac
|
||||
* @description
|
||||
* @date 2020-03-22 18:28
|
||||
*/
|
||||
public class UpLoadClientBasedFacePool {
|
||||
|
||||
private String orderPrefix = "/uploadFile";
|
||||
|
||||
private String serverPath;
|
||||
|
||||
private File file;
|
||||
//总数据片大小
|
||||
private Long sliceNumbers;
|
||||
|
||||
private Long currentOffset = 0L;
|
||||
|
||||
private CongestionWindow congestionWindow = new CongestionWindow();
|
||||
|
||||
private FacePool facePool;
|
||||
|
||||
// 要上传的本地文件对象
|
||||
private RandomAccessFile randomAccessFile;
|
||||
|
||||
//发送失败,需要重新发送的数据。key:第几个数据片,从0开始计数,value:文件偏移
|
||||
// private Map<Long, Long> failedSlice = new ConcurrentHashMap<>();
|
||||
//存放发送失败数据的文件偏移
|
||||
private ConcurrentLinkedQueue<Long> failedSlice = new ConcurrentLinkedQueue<>();
|
||||
|
||||
//发送的数据是否发送成功,key:第几个数据片,从0开始,value:是否发送成功
|
||||
private Map<Long, Boolean> sendRes = new ConcurrentHashMap<>();
|
||||
|
||||
//收到回复的数量
|
||||
public AtomicLong recvCount = new AtomicLong(0);
|
||||
|
||||
//发送的数据是否发送成功,key:第几个数据片,从0开始,value:该数据片超时次数
|
||||
private Map<Long, Integer> timeOutNums = new ConcurrentHashMap<>();
|
||||
// 超时重传上限数值,某个兴趣包的重传次数超过此数值,则放弃重传,直接返回false
|
||||
private Integer timeoutCeil=15;
|
||||
|
||||
public UpLoadClientBasedFacePool(File file, String serverPath, Integer facepoolnumber){
|
||||
this.file = file;
|
||||
this.serverPath = serverPath;
|
||||
this.facePool=new FacePool(facepoolnumber);
|
||||
this.facePool.start(MinoaDataAPI.minoaServerIpString, MinoaDataAPI.minoaServerPortInteger);
|
||||
System.out.println("***********FacePool中并发数:"+facepoolnumber+"***********");
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是否含有超时次数超过阈值的
|
||||
* @return
|
||||
*/
|
||||
private boolean isTimeOut(){
|
||||
for (Map.Entry<Long, Integer> entry : timeOutNums.entrySet()) {
|
||||
System.out.println("Key = " + entry.getKey() + ", Value = " + entry.getValue());
|
||||
if(entry.getValue() > timeoutCeil){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传数据的主函数
|
||||
* @return
|
||||
*/
|
||||
public boolean uploadData(){
|
||||
// 先初始化一个本地文件
|
||||
try {
|
||||
this.randomAccessFile = new RandomAccessFile(this.file.getAbsolutePath(), "rw");
|
||||
System.out.println("本地文件打开");
|
||||
} catch (FileNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
if(file.length()% MainApp.sliceSize == 0){
|
||||
sliceNumbers = file.length()/ MainApp.sliceSize;
|
||||
}else{
|
||||
sliceNumbers = file.length()/ MainApp.sliceSize + 1;
|
||||
}
|
||||
|
||||
while(true){
|
||||
//判断是否已经上传安成
|
||||
if(sliceNumbers <= recvCount.longValue()){
|
||||
break;
|
||||
}
|
||||
|
||||
// 判断是否已经被用户终止上传
|
||||
if(MainApp.isCancelFileTransferFlag){
|
||||
System.out.println("用户已主动中断上传");
|
||||
try {
|
||||
this.randomAccessFile.close();
|
||||
System.out.println("本地文件关闭");
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//每一次发送数据
|
||||
int cwnd = 0;
|
||||
//获取此次可以发送数据的个数
|
||||
while((cwnd = congestionWindow.getAvailableCwnd()) <= 0){
|
||||
try {
|
||||
Thread.sleep(1);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
for(int i=0; i<cwnd; i++){
|
||||
//TODO 首先发送failedmap中的数据
|
||||
if(failedSlice.size() > 0){
|
||||
//首先发送failedslice中的数据
|
||||
Long failOffset = failedSlice.poll();
|
||||
System.out.println("发送数据, name: " + file.getName() +",offset:" + currentOffset + ", failedSlice:" + failedSlice.size() );
|
||||
sendData(failOffset);
|
||||
}else{
|
||||
if(currentOffset < file.length()){
|
||||
System.out.println("发送数据, name: " + file.getName() +",offset:" + currentOffset + ", failedSlice:" + failedSlice.size() );
|
||||
sendData(currentOffset);
|
||||
currentOffset += MainApp.sliceSize;
|
||||
}
|
||||
}
|
||||
congestionWindow.inFlightIncrease();
|
||||
congestionWindow.nOutInterestIncrease();
|
||||
|
||||
}
|
||||
|
||||
if(isTimeOut()){
|
||||
System.out.println("丢包超过阈值: "+timeoutCeil+" ,文件传输主动中断");
|
||||
this.facePool.shutdownNow();
|
||||
try {
|
||||
this.randomAccessFile.close();
|
||||
System.out.println("本地文件关闭");
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
try {
|
||||
this.randomAccessFile.close();
|
||||
System.out.println("本地文件关闭");
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
this.facePool.shutdownNow();
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送一个数据片
|
||||
* @param offset
|
||||
*/
|
||||
private void sendData(Long offset){
|
||||
facePool.submit(freeface -> {
|
||||
OrderInfo orderInfo = new OrderInfo();
|
||||
Long seqLong = MainApp.getNewDataReqId();
|
||||
orderInfo.setSeq(seqLong);
|
||||
String testStr = DownAndUpLoadData.getUploadFile(file.getAbsolutePath(), offset);
|
||||
//System.out.println("*******************:" + testStr + "*******************");
|
||||
orderInfo.setJsonString(testStr);
|
||||
|
||||
// 获取json格式的数据请求字符串
|
||||
//String requestStr = MinoaDataAPI.getRequestStr(orderPrefix, orderInfo);
|
||||
|
||||
// 发送数据兴趣包
|
||||
Name name = new Name(MinoaDataAPI.globalPrefixString + orderPrefix + "/" + seqLong);
|
||||
Interest interest = new Interest(name);
|
||||
interest.setMustBeFresh(true);
|
||||
try {
|
||||
ResponseData responseData = new ResponseData();
|
||||
responseData.setPrefix(orderPrefix);
|
||||
byte[] requestByte = null; // 请求数据
|
||||
// 重写ondata
|
||||
try {
|
||||
// 解析并修改文件名【window转server】
|
||||
String localFilePath = "";
|
||||
String serverFilePath = "";
|
||||
try {
|
||||
// 解析
|
||||
JSONObject jsonObject = new JSONObject(orderInfo.getJsonString());
|
||||
localFilePath = jsonObject.getString("filename");
|
||||
// serverFilePath = serverpath + getPureFileNameFromWindows(localFilePath);
|
||||
serverFilePath = serverPath + MinoaDataAPI.getPureFileNameFromWindows(localFilePath);
|
||||
// 修改
|
||||
jsonObject.remove("filename");
|
||||
jsonObject.put("filename", serverFilePath);
|
||||
orderInfo.setJsonString(jsonObject.toString());
|
||||
System.out.println("request head str: " + orderInfo.getJsonString());
|
||||
System.out.println("head str length: " + orderInfo.getJsonString().length());
|
||||
System.out.println("head str byte length: " + StringByteLengthUtil.getByteLength(orderInfo.getJsonString()));
|
||||
} catch (JSONException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
// 从本地读取数据
|
||||
byte[] content = new byte[10000]; // 文件分片内容
|
||||
try {
|
||||
synchronized (randomAccessFile) {
|
||||
// RandomAccessFile randomAccessFile = new RandomAccessFile(localFilePath, "rw");
|
||||
// 设置文件的读取起点
|
||||
randomAccessFile.seek(offset);
|
||||
// 尝试读取数据
|
||||
int readLen = randomAccessFile.read(content, 0, 7000);
|
||||
int jsonLen = StringByteLengthUtil.getByteLength(orderInfo.getJsonString());
|
||||
requestByte = new byte[jsonLen + 1 + readLen];
|
||||
System.arraycopy(orderInfo.getJsonString().getBytes("utf-8"), 0, requestByte, 0, jsonLen);
|
||||
requestByte[jsonLen] = 0;
|
||||
System.arraycopy(content, 0, requestByte, jsonLen + 1, readLen);
|
||||
// randomAccessFile.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
// 赋值兴趣包的附带信息,并标志区块链
|
||||
interest.setApplicationParameters(new Blob(requestByte));
|
||||
//超时
|
||||
interest.setInterestLifetimeMilliseconds(5000);
|
||||
// 密钥“黑盒”
|
||||
try {
|
||||
// MinoaDataAPI.keyChain.sign(interest);
|
||||
KeyManager.INSTANCE.getKeyChain().sign(interest);
|
||||
} catch (PibImpl.Error e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
} catch (KeyChain.Error e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
} catch (net.named_data.jndn.security.tpm.TpmBackEnd.Error e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
} catch (SecurityException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
UpLoadData upLoadData = new UpLoadData(orderInfo.getSeq(), responseData, offset / MainApp.sliceSize);
|
||||
UpLoadTimeout upLoadTimeout = new UpLoadTimeout(upLoadData);
|
||||
UpLoadOnNetWorkNack upLoadOnNetWorkNack = new UpLoadOnNetWorkNack(upLoadData);
|
||||
// 使用tcp发送数据请求兴趣包
|
||||
// MinoaDataAPI.runFace();
|
||||
freeface.expressInterest(interest, upLoadData, upLoadTimeout, upLoadOnNetWorkNack);
|
||||
|
||||
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
System.out.println("exception: " + e.getMessage());
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
public class UpLoadData implements OnData {
|
||||
|
||||
private Long seq;
|
||||
private ResponseData responseData;
|
||||
//第几个数据片
|
||||
public Long sliceNum;
|
||||
|
||||
public boolean isFinished = false;
|
||||
|
||||
public UpLoadData(Long seq, ResponseData responseData, Long sliceNum){
|
||||
this.seq = seq;
|
||||
this.responseData = responseData;
|
||||
this.sliceNum = sliceNum;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onData(Interest interest, Data data){
|
||||
responseData.setResponseData(data.getContent().toString());
|
||||
JSONObject jsonObject = responseData.praseRequestData();
|
||||
|
||||
congestionWindow.inFlightDecrease();
|
||||
// 解析数据,是否成功上传
|
||||
Integer codeInteger = null;
|
||||
try {
|
||||
codeInteger = jsonObject.getInt("code");
|
||||
} catch (JSONException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (codeInteger == 200) {
|
||||
recvCount.incrementAndGet();
|
||||
congestionWindow.cwndIncrease();
|
||||
System.out.println("第" + sliceNum + "片上传成功!");
|
||||
}else{
|
||||
failedSlice.add(sliceNum* MainApp.sliceSize);
|
||||
System.out.println("第" + sliceNum + "片上传失败!");
|
||||
}
|
||||
//拥塞标记返回值,无意义,大于0就表示拥塞,直接进行窗口减小操作即可
|
||||
if(data.getCongestionMark() > 0){
|
||||
System.out.println("&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&网络拥塞,滑动窗口减小,getCongestionMark:" + data.getCongestionMark());
|
||||
congestionWindow.cwndDecrease();
|
||||
}else{
|
||||
//如果没有检测到拥塞,则增加窗口
|
||||
congestionWindow.nIndataIncrease();
|
||||
}
|
||||
|
||||
if(timeOutNums.containsKey(sliceNum)){
|
||||
timeOutNums.remove(sliceNum);
|
||||
}
|
||||
|
||||
isFinished = true;
|
||||
|
||||
}
|
||||
public int callbackCount = 0 ;
|
||||
|
||||
}
|
||||
|
||||
public class UpLoadTimeout implements OnTimeout {
|
||||
|
||||
|
||||
|
||||
private UpLoadData upLoadData;
|
||||
public int callbackCount = 0 ;
|
||||
|
||||
public UpLoadTimeout(UpLoadData upLoadData) {
|
||||
this.upLoadData = upLoadData;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTimeout(Interest interest){
|
||||
congestionWindow.inFlightDecrease();
|
||||
failedSlice.add(upLoadData.sliceNum* MainApp.sliceSize);
|
||||
callbackCount ++ ;
|
||||
System.out.println("Time out for interest " + interest.getName());
|
||||
upLoadData.isFinished = false;
|
||||
|
||||
//
|
||||
if(timeOutNums.containsKey(upLoadData.sliceNum)){
|
||||
int value = timeOutNums.get(upLoadData.sliceNum) + 1;
|
||||
timeOutNums.put(upLoadData.sliceNum,value);
|
||||
}else{
|
||||
timeOutNums.put(upLoadData.sliceNum,1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class UpLoadOnNetWorkNack implements OnNetworkNack {
|
||||
|
||||
private UpLoadData upLoadData;
|
||||
public int callbackCount = 0 ;
|
||||
|
||||
public UpLoadOnNetWorkNack(UpLoadData upLoadData) {
|
||||
this.upLoadData = upLoadData;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNetworkNack(Interest var1, NetworkNack var2){
|
||||
congestionWindow.inFlightDecrease();
|
||||
failedSlice.add(upLoadData.sliceNum* MainApp.sliceSize);
|
||||
//
|
||||
if(timeOutNums.containsKey(upLoadData.sliceNum)){
|
||||
int value = timeOutNums.get(upLoadData.sliceNum) + 1;
|
||||
timeOutNums.put(upLoadData.sliceNum,value);
|
||||
}else{
|
||||
timeOutNums.put(upLoadData.sliceNum,1);
|
||||
}
|
||||
callbackCount ++ ;
|
||||
System.out.println("onNetworkNack " + var1.getName());
|
||||
upLoadData.isFinished = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
package cn.minoa.dataRequestInterface;
|
||||
|
||||
import net.named_data.jndn.*;
|
||||
import net.named_data.jndn.security.KeyChain;
|
||||
|
||||
import net.named_data.jndn.security.pib.PibIdentity;
|
||||
import net.named_data.jndn.security.pib.PibSqlite3;
|
||||
import net.named_data.jndn.security.tpm.TpmBackEndMemory;
|
||||
//import net.named_data.jndn.util.Blob;
|
||||
//import org.json.JSONObject;
|
||||
|
||||
//生成密钥
|
||||
public class creatNDNKey {
|
||||
static private String pidDbPathString="";
|
||||
// static private String pidDbPathString="E:\\MyCode\\newEclipseWorkspace\\minoa_client_windows_JavaFX11";
|
||||
static private String keyChainNameString="/wefree";
|
||||
static private String pidIdentityString="wefree";
|
||||
|
||||
public static void main(String args[]){
|
||||
KeyChain keyChain ;
|
||||
try{
|
||||
//密钥“黑盒”
|
||||
PibSqlite3 pibSqlite3 = new PibSqlite3(pidDbPathString);
|
||||
TpmBackEndMemory tpmBackEndMemory = new TpmBackEndMemory() ;
|
||||
keyChain = new KeyChain(pibSqlite3,tpmBackEndMemory ) ;
|
||||
keyChain.createIdentityV2(new Name(keyChainNameString)) ;
|
||||
PibIdentity identity = keyChain.getPib().getIdentity(new Name(pidIdentityString)); ;
|
||||
keyChain.setDefaultIdentity(identity);
|
||||
//输出测试
|
||||
System.out.println(keyChain.getDefaultCertificateName().toUri());
|
||||
System.out.println(keyChain.getPib().getPibLocator());
|
||||
}catch (Exception e){
|
||||
System.out.println("exception: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
package cn.minoa.dataRequestInterface;
|
||||
// 在注册的界面未完成之前用于注册新用户
|
||||
|
||||
import org.json.JSONObject;
|
||||
|
||||
public class registerUser {
|
||||
// 获取注册请求字符串
|
||||
@SuppressWarnings("unused")
|
||||
static private String getRegisterJson() {
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
String mPubKey = "Bv0CsQcuCAR3Z2gwCANLRVkICH9+4yjVUHZaCAxjZXJ0LXJlcXVlc3QICf0AAAFv\nEUSBehQJGAECGQQANu6AFf0BJjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC\nggEBANbFutCAZqFjHEa16tYvy4lBgi9/zixKWQzE9I72vaG2Imym+6KR30qkAQOK\nh0uE5RD2YsGhRK99rde+JOqIfk2/sunhp4nctOS5f4DeuOty58ekrO+Co9ZFmNBI\nmyk5i/hakjBEd/vdD7b1VadDRep5mWs3rgCinZOUfVaZ4oKqSws7ZWMvOSlRMOOi\nVzj53P4poY109S6aWmi3xKw/D76vfJapjdOB9Dg7S3rz0Rve1F/ajHCXWLt4XU3k\nUCiBn3Qmt6UD/MyDBaaUCfOvHTN6yVPtN6aOtYJVBAWt/P1ahLYhWkSm6KvrwMt0\nRzy2lw/lPriT99REItc/0wK6XwkCAwEAARZGGwEBHBcHFQgEd2doMAgDS0VZCAh/\nfuMo1VB2Wv0A/Sb9AP4PMjAxOTEyMTdUMDAzMTQw/QD/DzIwMTkxMjI3VDAwMzEz\nORf9AQCM+8WROXfi8WD9DydfLuSUxV0v3KW/Gn422/puDrkwwi1R2ogsAUc2O8pp\npuMLjWrQOTgE6ZTg80uWoDSUjjk44aMjkL2SAfp62vHRbGFx7+dckHAtF+DS6NH7\nX2vojFHOg6fksOE1M7XqLHmEEctZrFVSnQO7nB3DfRg+BqzZC/iy+8YAvTIvqA1c\nNsKYkmNITB80aM1v2H7fKnV4ZJpZnW71G5vbaPUseeklalQ2vEuBgWdd/1PL/0Ml\nI52npzqoeKAEpLp+vBwGN5ryGtWKB12nNimpMfevQAn/9BVIg59lZ7DIlE0sWmgW\nnwDxIXKebdViOejHlKwNAykxRRWw";
|
||||
String commandString = "/register";
|
||||
String userNameString = "oa_wefree";
|
||||
String passWordString = "12345678";
|
||||
String phoneString = "10000000006";
|
||||
Integer levelInteger = 0;
|
||||
try {
|
||||
jsonObject.put("command", commandString);
|
||||
jsonObject.put("username", userNameString);
|
||||
jsonObject.put("password", passWordString);
|
||||
jsonObject.put("phone", phoneString);
|
||||
jsonObject.put("publicKey", mPubKey);
|
||||
jsonObject.put("level", levelInteger);
|
||||
} catch (Exception e) {
|
||||
System.out.println("exception: " + e.getMessage());
|
||||
}
|
||||
return jsonObject.toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
package cn.minoa.model;
|
||||
// 存储一个file或一个文件夹的属性
|
||||
|
||||
public class SingleFile {
|
||||
//文件名
|
||||
private String filename;
|
||||
//文件路径
|
||||
private String filepath;
|
||||
//文件ID
|
||||
private String fileId;
|
||||
//文件创建时间
|
||||
private Long time;
|
||||
//文件类型
|
||||
private String type;
|
||||
//文件大小
|
||||
private Long size;
|
||||
|
||||
public SingleFile(){
|
||||
}
|
||||
|
||||
public SingleFile(String fileId){
|
||||
this.fileId=fileId;
|
||||
}
|
||||
// public SingleFile(){}
|
||||
|
||||
public String getFilename() {
|
||||
return filename;
|
||||
}
|
||||
|
||||
public void setFilename(String filename) {
|
||||
this.filename = filename;
|
||||
}
|
||||
|
||||
public String getFileId() {
|
||||
return fileId;
|
||||
}
|
||||
|
||||
public void setFileId(String fileId) {
|
||||
this.fileId = fileId;
|
||||
}
|
||||
|
||||
public String getFilepath() {
|
||||
return filepath;
|
||||
}
|
||||
|
||||
public void setFilepath(String filepath) {
|
||||
this.filepath = filepath;
|
||||
}
|
||||
|
||||
public Long getTime() {
|
||||
return time;
|
||||
}
|
||||
|
||||
public void setTime(Long time) {
|
||||
this.time = time;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public Long getSize() {
|
||||
return size;
|
||||
}
|
||||
|
||||
public void setSize(Long size) {
|
||||
this.size = size;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,139 @@
|
||||
package cn.minoa.util;
|
||||
|
||||
import javax.crypto.*;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.math.BigInteger;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.SecureRandom;
|
||||
|
||||
public class EncryptionUtil {
|
||||
|
||||
public static String getMD5String(String str) {
|
||||
try {
|
||||
// 生成一个MD5加密计算摘要
|
||||
MessageDigest md = MessageDigest.getInstance("MD5");
|
||||
// 计算md5函数
|
||||
md.update(str.getBytes("utf-8"));
|
||||
// digest()最后确定返回md5 hash值,返回值为8位字符串。因为md5 hash值是16位的hex值,实际上就是8位的字符
|
||||
// BigInteger函数则将8位的字符串转换成16位hex值,用字符串来表示;得到字符串形式的hash值
|
||||
//一个byte是八位二进制,也就是2位十六进制字符(2的8次方等于16的2次方)
|
||||
String res = new BigInteger(1, md.digest()).toString(16);
|
||||
System.out.println(str + " MD5加密结果: " + res);
|
||||
return res;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
public static String encryptBasedAES(String content) {
|
||||
byte[] encrypt=encryptBasedAES(content,"123");
|
||||
return ParseSystemUtil.parseByte2HexStr(encrypt);
|
||||
}
|
||||
|
||||
// public static byte[] encryptBasedAES(String content) {
|
||||
// return encryptBasedAES(content, "123");
|
||||
// }
|
||||
|
||||
/**
|
||||
* AES加密字符串
|
||||
*
|
||||
* @param content 需要被加密的字符串
|
||||
* @param password 加密需要的密码
|
||||
* @return 密文
|
||||
*/
|
||||
public static byte[] encryptBasedAES(String content, String password) {
|
||||
try {
|
||||
KeyGenerator kgen = KeyGenerator.getInstance("AES");// 创建AES的Key生产者
|
||||
// kgen.init(128, new SecureRandom(password.getBytes()));// 利用用户密码作为随机数初始化出
|
||||
SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
|
||||
secureRandom.setSeed(password.getBytes("utf-8"));
|
||||
kgen.init(128, secureRandom);
|
||||
//加密没关系,SecureRandom是生成安全随机数序列,password.getBytes()是种子,只要种子相同,序列就一样,所以解密只要有password就行
|
||||
SecretKey secretKey = kgen.generateKey();// 根据用户密码,生成一个密钥
|
||||
byte[] enCodeFormat = secretKey.getEncoded();// 返回基本编码格式的密钥,如果此密钥不支持编码,则返回
|
||||
SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");// 转换为AES专用密钥
|
||||
Cipher cipher = Cipher.getInstance("AES");// 创建密码器
|
||||
byte[] byteContent = content.getBytes("utf-8");
|
||||
cipher.init(Cipher.ENCRYPT_MODE, key);// 初始化为加密模式的密码器
|
||||
byte[] result = cipher.doFinal(byteContent);// 加密
|
||||
return result;
|
||||
} catch (NoSuchPaddingException e) {
|
||||
e.printStackTrace();
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
e.printStackTrace();
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
e.printStackTrace();
|
||||
} catch (InvalidKeyException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IllegalBlockSizeException e) {
|
||||
e.printStackTrace();
|
||||
} catch (BadPaddingException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static String decryptBasedAES(String hexStr) {
|
||||
byte[] byte2 = ParseSystemUtil.parseHexStr2Byte(hexStr);
|
||||
try {
|
||||
return new String(decryptBasedAES(byte2, "123"));
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// public static byte[] decryptBasedAES(byte[] content) {
|
||||
// return decryptBasedAES(content, "123");
|
||||
// }
|
||||
|
||||
/**
|
||||
* 解密AES加密过的字符串
|
||||
*
|
||||
* @param content AES加密过过的内容
|
||||
* @param password 加密时的密码
|
||||
* @return 明文
|
||||
*/
|
||||
public static byte[] decryptBasedAES(byte[] content, String password) throws UnsupportedEncodingException {
|
||||
try {
|
||||
KeyGenerator kgen = KeyGenerator.getInstance("AES");// 创建AES的Key生产者
|
||||
// kgen.init(128, new SecureRandom(password.getBytes()));
|
||||
SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
|
||||
secureRandom.setSeed(password.getBytes("utf-8"));
|
||||
kgen.init(128, secureRandom);
|
||||
SecretKey secretKey = kgen.generateKey();// 根据用户密码,生成一个密钥
|
||||
byte[] enCodeFormat = secretKey.getEncoded();// 返回基本编码格式的密钥
|
||||
SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");// 转换为AES专用密钥
|
||||
Cipher cipher = Cipher.getInstance("AES");// 创建密码器
|
||||
cipher.init(Cipher.DECRYPT_MODE, key);// 初始化为解密模式的密码器
|
||||
byte[] result = cipher.doFinal(content);
|
||||
return result; // 明文
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
e.printStackTrace();
|
||||
} catch (NoSuchPaddingException e) {
|
||||
e.printStackTrace();
|
||||
} catch (InvalidKeyException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IllegalBlockSizeException e) {
|
||||
e.printStackTrace();
|
||||
} catch (BadPaddingException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// 测试主函数
|
||||
// public static void main(String[] args) throws Exception {
|
||||
// String content = "哈哈哈";
|
||||
// System.out.println("需要加密的内容:" + content);
|
||||
// String enc=encryptBasedAES(content);
|
||||
// System.out.println("加密后的16进制密文:" + enc);
|
||||
// String dec=decryptBasedAES(enc);
|
||||
// System.out.println("解密后的内容:" + dec);
|
||||
// }
|
||||
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package cn.minoa.util;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
|
||||
public class FileUtil {
|
||||
|
||||
/**
|
||||
* 格式化时间
|
||||
* @param format 格式化格式,基础格式为yyyy-MM-dd HH:mm:ss
|
||||
* @param time 精确到ms
|
||||
* @return
|
||||
*/
|
||||
public static String formatTime(String format, long time)
|
||||
{
|
||||
SimpleDateFormat df = new SimpleDateFormat(format);
|
||||
return df.format(new Date(time));
|
||||
}
|
||||
|
||||
// 后台返回的Long类型时间戳(精确到s)转日期
|
||||
public static String timeToDateString(Long time){
|
||||
String timeString = formatTime("yyyy-MM-dd HH:mm:ss", time*1000);
|
||||
System.out.println(timeString);
|
||||
return timeString;
|
||||
}
|
||||
|
||||
// 文件大小根据具体大小,转成B/KB/M/G/T
|
||||
public static String sizeToShowSize(Long size){
|
||||
if(size<1024){
|
||||
return size+" B";
|
||||
}
|
||||
Double sizeKB=size/1024.0;
|
||||
if(sizeKB<1024){
|
||||
return String.format("%.3f",sizeKB)+" KB";
|
||||
}
|
||||
Double sizeM=sizeKB/1024.0;
|
||||
if(sizeM<1024){
|
||||
return String.format("%.3f",sizeM)+" M";
|
||||
}
|
||||
Double sizeG=sizeM/1024.0;
|
||||
if(sizeG<1024){
|
||||
return String.format("%.3f",sizeG)+" G";
|
||||
}
|
||||
Double sizeT=sizeG/1024.0;
|
||||
return String.format("%.3f",sizeT)+" T";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
package cn.minoa.util;
|
||||
|
||||
import cn.minoa.MainApp;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.Properties;
|
||||
|
||||
public class KeyStorageUtil {
|
||||
|
||||
// 存数据
|
||||
public static void setKeyName(String keyName){
|
||||
InputStream inputStream = null;
|
||||
OutputStream outputStream=null;
|
||||
try {
|
||||
//如果 classPath 不存在,则获取的输入流会为 null
|
||||
inputStream=new BufferedInputStream(new FileInputStream(MainApp.getClientPath()+ File.separator+"ndn"+File.separator+"settings.properties"));
|
||||
if (inputStream == null) {
|
||||
System.out.println("没有找到配置文件...");
|
||||
}
|
||||
Properties settingProperties = new Properties();
|
||||
settingProperties.load(inputStream);
|
||||
settingProperties.setProperty("KeyName", keyName);
|
||||
outputStream=new BufferedOutputStream(new FileOutputStream(MainApp.getClientPath()+ File.separator+"ndn"+File.separator+"settings.properties"));
|
||||
settingProperties.store(outputStream,"修改配置文件");
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}finally{
|
||||
//关闭输入流
|
||||
if (inputStream != null) {
|
||||
try {
|
||||
inputStream.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
//关闭输出流
|
||||
if (outputStream != null) {
|
||||
try {
|
||||
outputStream.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 取数据
|
||||
public static String getKeyName() {
|
||||
InputStream inputStream = null;
|
||||
try {
|
||||
//如果 classPath 不存在,则获取的输入流会为 null
|
||||
inputStream = new BufferedInputStream(new FileInputStream(MainApp.getClientPath() + File.separator + "ndn" + File.separator + "settings.properties"));
|
||||
// inputStream = MainApp.class.getClassLoader().getResourceAsStream("/ndn/settings.properties");
|
||||
if (inputStream == null) {
|
||||
System.out.println("没有找到配置文件...");
|
||||
}
|
||||
Properties settingProperties = new Properties();
|
||||
settingProperties.load(inputStream);
|
||||
String keyName = settingProperties.getProperty("KeyName");
|
||||
return keyName;
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
//关闭输入流
|
||||
if (inputStream != null) {
|
||||
try {
|
||||
inputStream.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
package cn.minoa.util;
|
||||
|
||||
//import java.time.LocalDate;
|
||||
//import javax.xml.bind.annotation.adapters.XmlAdapter;
|
||||
|
||||
//使得JAXB可以转换日期到XML
|
||||
//public class LocalDateAdapter extends XmlAdapter<String,LocalDate> {
|
||||
//
|
||||
// public LocalDate unmarshal(String v) throws Exception{
|
||||
// return LocalDate.parse(v);
|
||||
// }
|
||||
//
|
||||
// public String marshal(LocalDate v) throws Exception{
|
||||
// return v.toString();
|
||||
// }
|
||||
//}
|
||||
@@ -0,0 +1,32 @@
|
||||
package cn.minoa.util;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
|
||||
public class LoggerUtil {
|
||||
|
||||
// 将文件名、文件操作、传输耗时等信息写入日志.
|
||||
public static void insertFileAction(String filename, String fileaction, String usedtime) {
|
||||
try {
|
||||
File file = new File("./ndn/log.txt");
|
||||
FileOutputStream fos = null;
|
||||
if (!file.exists()) {
|
||||
file.createNewFile();//如果文件不存在,就创建该文件
|
||||
fos = new FileOutputStream(file);//首次写入获取
|
||||
} else {
|
||||
//如果文件已存在,那么就在文件末尾追加写入
|
||||
fos = new FileOutputStream(file, true);//这里构造方法多了一个参数true,表示在文件末尾追加写入
|
||||
}
|
||||
|
||||
OutputStreamWriter osw = new OutputStreamWriter(fos, "UTF-8");//指定以UTF-8格式写入文件
|
||||
osw.write("文件名:"+filename+" 文件操作:"+fileaction+" 文件耗时:"+usedtime);
|
||||
osw.write("\r\n");
|
||||
//写入完成关闭流
|
||||
osw.close();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package cn.minoa.util;
|
||||
|
||||
/**
|
||||
* 进制转换工具类
|
||||
*/
|
||||
public class ParseSystemUtil {
|
||||
|
||||
/**将二进制转换成16进制
|
||||
* @param buf
|
||||
* @return
|
||||
*/
|
||||
public static String parseByte2HexStr(byte buf[]) {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
for (int i = 0; i < buf.length; i++) {
|
||||
String hex = Integer.toHexString(buf[i] & 0xFF);
|
||||
if (hex.length() == 1) {
|
||||
hex = '0' + hex;
|
||||
}
|
||||
sb.append(hex.toUpperCase());
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**将16进制转换为二进制
|
||||
* @param hexStr
|
||||
* @return
|
||||
*/
|
||||
public static byte[] parseHexStr2Byte(String hexStr) {
|
||||
if (hexStr.length() < 1)
|
||||
return null;
|
||||
byte[] result = new byte[hexStr.length()/2];
|
||||
for (int i = 0;i< hexStr.length()/2; i++) {
|
||||
int high = Integer.parseInt(hexStr.substring(i*2, i*2+1), 16);
|
||||
int low = Integer.parseInt(hexStr.substring(i*2+1, i*2+2), 16);
|
||||
result[i] = (byte) (high * 16 + low);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,207 @@
|
||||
package cn.minoa.util;
|
||||
|
||||
import cn.minoa.dataRequestInterface.KeyManager;
|
||||
import cn.minoa.dataRequestInterface.MinoaDataAPI;
|
||||
import net.named_data.jndn.encoding.EncodingException;
|
||||
import net.named_data.jndn.security.KeyChain;
|
||||
import net.named_data.jndn.security.SafeBag;
|
||||
import net.named_data.jndn.security.pib.Pib;
|
||||
import net.named_data.jndn.security.pib.PibImpl;
|
||||
import net.named_data.jndn.security.tpm.TpmBackEnd;
|
||||
import net.named_data.jndn.security.v2.CertificateV2;
|
||||
import net.named_data.jndn.util.Blob;
|
||||
|
||||
import java.io.*;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.FileChannel;
|
||||
|
||||
public class SecretKeyManageUtil {
|
||||
|
||||
// 导出密钥
|
||||
public static boolean exportSafeBag(String filepathname) {
|
||||
try {
|
||||
// 得到指定identity的证书(包含秘钥信息)
|
||||
CertificateV2 certificateV2 = KeyManager.INSTANCE
|
||||
.getCertification(MinoaDataAPI.keyChainNameString);
|
||||
|
||||
// 通过KeyChain导出SafeBag
|
||||
// exportSafeBag支持设置密码
|
||||
SafeBag safeBag = KeyManager.INSTANCE
|
||||
.getKeyChain().exportSafeBag(certificateV2);
|
||||
|
||||
// 将safeBag进行编码
|
||||
Blob blob = safeBag.wireEncode();
|
||||
|
||||
// 接着就可以将编码后的数据写入到一个文件当中
|
||||
writeByteToFile(blob.getImmutableArray(), blob.size(),filepathname);
|
||||
return true;
|
||||
}catch (PibImpl.Error | Pib.Error | KeyChain.Error e){
|
||||
e.printStackTrace();
|
||||
System.out.println(e.getMessage());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// 导入密钥
|
||||
public static String importSafeBag(String filepathname) {
|
||||
try {
|
||||
System.out.println("密钥文件:"+filepathname);
|
||||
// 读取文件,得到字节数组,
|
||||
// ByteBuffer bb = readByteBuffFromFile(filepathname);
|
||||
byte[] b=readByteFromFile(filepathname);
|
||||
|
||||
if (b == null) {
|
||||
return "The read file is empty.";
|
||||
}
|
||||
Blob blob=new Blob(b);
|
||||
// 使用SafeBag的其中一种构造方法
|
||||
SafeBag safeBag = new SafeBag(blob);
|
||||
|
||||
String name=safeBag.getCertificate().getName().toString();
|
||||
System.out.println("导入文件的证书名称:"+name);
|
||||
|
||||
// 然后用KeyChain导入
|
||||
// 如果exportSafeBag时设置了密码,importSafeBag的时候也要传入密码
|
||||
KeyManager.INSTANCE
|
||||
.getKeyChain()
|
||||
.importSafeBag(safeBag);
|
||||
return "success";
|
||||
} catch (EncodingException | Pib.Error | TpmBackEnd.Error |
|
||||
KeyChain.Error | PibImpl.Error | CertificateV2.Error | IOException e) {
|
||||
// e.printStackTrace();
|
||||
System.out.println(e.getMessage());
|
||||
return e.getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
public static ByteBuffer encodeValue(byte[] value) {
|
||||
ByteBuffer byteBuffer = ByteBuffer.allocate(value.length);
|
||||
byteBuffer.clear();
|
||||
byteBuffer.get(value, 0, value.length);
|
||||
return byteBuffer;
|
||||
}
|
||||
|
||||
// 读取文件到一个byte
|
||||
public static byte[] readByteFromFile(String filepathname) throws IOException {
|
||||
File f = new File(filepathname);
|
||||
if (!f.exists()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
FileChannel channel = null;
|
||||
FileInputStream fs = null;
|
||||
try {
|
||||
fs = new FileInputStream(f);
|
||||
channel = fs.getChannel();
|
||||
ByteBuffer byteBuffer = ByteBuffer.allocate((int) channel.size());
|
||||
while ((channel.read(byteBuffer)) > 0) {
|
||||
// do nothing
|
||||
// System.out.println("reading");
|
||||
}
|
||||
return byteBuffer.array();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
throw e;
|
||||
} finally {
|
||||
try {
|
||||
channel.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
try {
|
||||
fs.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 读取文件数据到一个bytebuff
|
||||
public static ByteBuffer readByteBuffFromFile() throws IOException {
|
||||
return readByteBuffFromFile("./ndn/SecretKey.txt");
|
||||
}
|
||||
/**
|
||||
* NIO way
|
||||
*
|
||||
* @param
|
||||
* @return
|
||||
* @throws IOException
|
||||
*/
|
||||
public static ByteBuffer readByteBuffFromFile(String filepathname) throws IOException {
|
||||
File f = new File(filepathname);
|
||||
if (!f.exists()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
FileChannel channel = null;
|
||||
FileInputStream fs = null;
|
||||
try {
|
||||
fs = new FileInputStream(f);
|
||||
channel = fs.getChannel();
|
||||
ByteBuffer byteBuffer = ByteBuffer.allocate((int) channel.size());
|
||||
while ((channel.read(byteBuffer)) > 0) {
|
||||
// do nothing
|
||||
// System.out.println("reading");
|
||||
}
|
||||
return byteBuffer;
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
throw e;
|
||||
} finally {
|
||||
try {
|
||||
channel.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
try {
|
||||
fs.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 写入byte数组到文件
|
||||
private static void writeByteToFile(byte[] content, int len) {
|
||||
writeByteToFile(content,len,"./ndn/SecretKeyMIN");
|
||||
}
|
||||
|
||||
// 写入byte数组到文件
|
||||
private static void writeByteToFile(byte[] content, int len,String filepathname) {
|
||||
try {
|
||||
File file = new File(filepathname);
|
||||
FileOutputStream fos = null;
|
||||
if (file.exists()) {
|
||||
file.delete();
|
||||
}
|
||||
file.createNewFile();//如果文件不存在,就创建该文件
|
||||
fos = new FileOutputStream(file);//首次写入获取
|
||||
fos.write(content, 0, len);
|
||||
//写入完成关闭流
|
||||
fos.close();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
// 写入字符串到文件
|
||||
private static void writeStringToFile(String content) {
|
||||
try {
|
||||
File file = new File("./ndn/SecretKey.txt");
|
||||
FileOutputStream fos = null;
|
||||
if (file.exists()) {
|
||||
file.delete();
|
||||
}
|
||||
file.createNewFile();//如果文件不存在,就创建该文件
|
||||
fos = new FileOutputStream(file);//首次写入获取
|
||||
OutputStreamWriter osw = new OutputStreamWriter(fos, "UTF-8");//指定以UTF-8格式写入文件
|
||||
osw.write(content);
|
||||
//写入完成关闭流
|
||||
osw.close();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
package cn.minoa.view.home;
|
||||
|
||||
import cn.minoa.MainApp;
|
||||
import cn.minoa.dataRequestInterface.DownLoadClientBasedFacePool;
|
||||
import cn.minoa.dataRequestInterface.OrderInfo;
|
||||
import cn.minoa.dataRequestInterface.ResponseData;
|
||||
import cn.minoa.model.Email;
|
||||
@@ -118,8 +119,20 @@ public class DealSingleReimbursementController {
|
||||
}
|
||||
|
||||
System.out.println("开始下载... :"+pathfilename);
|
||||
int flag=mainApp.downloadFileByPathfilename(pathfilename,localDirString);
|
||||
if(flag==0) {
|
||||
// int flag=mainApp.downloadFileByPathfilename(pathfilename,localDirString);
|
||||
Long filelen= mainApp.getServerFileByteLength(pathfilename);
|
||||
Integer sliceNum = (int)(filelen / mainApp.sliceSize);
|
||||
if (filelen % mainApp.sliceSize != 0) {
|
||||
sliceNum++;
|
||||
}
|
||||
Long startTime = System.currentTimeMillis();
|
||||
DownLoadClientBasedFacePool downLoadClient = new DownLoadClientBasedFacePool(pathfilename,
|
||||
localDirString,sliceNum,mainApp.threadNumberForFileTransfer);
|
||||
// 下载文件
|
||||
boolean res = downLoadClient.downloadData();
|
||||
Long endTime = System.currentTimeMillis();
|
||||
System.out.println("耗时:" + (endTime - startTime) + "ms");
|
||||
if(res) {
|
||||
// 弹窗参考:https://code.makery.ch/blog/javafx-dialogs-official/
|
||||
Alert alert = new Alert(Alert.AlertType.INFORMATION);
|
||||
alert.setTitle("下载成功");
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
package cn.minoa.view.home;
|
||||
|
||||
import cn.minoa.MainApp;
|
||||
import cn.minoa.dataRequestInterface.DownLoadClientBasedFacePool;
|
||||
import cn.minoa.model.Reimbursement;
|
||||
import cn.minoa.view.login.LoginOverviewController;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.scene.control.Alert;
|
||||
import javafx.scene.control.ListView;
|
||||
@@ -106,8 +108,21 @@ public class SingleReimbursementDetailsController {
|
||||
}
|
||||
|
||||
System.out.println("开始下载... :"+pathfilename);
|
||||
int flag=mainApp.downloadFileByPathfilename(pathfilename,localDirString);
|
||||
if(flag==0) {
|
||||
// int flag=mainApp.downloadFileByPathfilename(pathfilename,localDirString);
|
||||
Long filelen= mainApp.getServerFileByteLength(pathfilename);
|
||||
Integer sliceNum = (int)(filelen / mainApp.sliceSize);
|
||||
if (filelen % mainApp.sliceSize != 0) {
|
||||
sliceNum++;
|
||||
}
|
||||
Long startTime = System.currentTimeMillis();
|
||||
DownLoadClientBasedFacePool downLoadClient = new DownLoadClientBasedFacePool(pathfilename,
|
||||
localDirString,sliceNum,mainApp.threadNumberForFileTransfer);
|
||||
// 下载文件
|
||||
boolean res = downLoadClient.downloadData();
|
||||
Long endTime = System.currentTimeMillis();
|
||||
System.out.println("耗时:" + (endTime - startTime) + "ms");
|
||||
// 每个分片都下载成功
|
||||
if(res) {
|
||||
// 弹窗参考:https://code.makery.ch/blog/javafx-dialogs-official/
|
||||
Alert alert = new Alert(Alert.AlertType.INFORMATION);
|
||||
alert.setTitle("下载成功");
|
||||
|
||||
@@ -313,8 +313,8 @@ public class WrittenReimbursementController {
|
||||
String pathfilename = reimbursementFilesList.get(i);
|
||||
//上传该文件到服务器共享文件夹目录下
|
||||
File file = new File(pathfilename);
|
||||
Integer res=mainApp.uploadFileToServerSharedFolder(file);
|
||||
if(res<0){
|
||||
boolean res=mainApp.uploadFileToServerSharedFolder(file);
|
||||
if(!res){
|
||||
flag=false;
|
||||
}
|
||||
//将该文件信息[服务器文件路径地址]写入邮件信息中
|
||||
|
||||
@@ -0,0 +1,154 @@
|
||||
package cn.minoa.view.login;
|
||||
|
||||
import cn.minoa.MainApp;
|
||||
import cn.minoa.model.Loginer;
|
||||
import cn.minoa.util.EncryptionUtil;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.Properties;
|
||||
|
||||
// 维持长登录状态
|
||||
public class KeepLoginStatus {
|
||||
|
||||
public static void setLoginStatus(boolean flag){
|
||||
InputStream inputStream = null;
|
||||
OutputStream outputStream=null;
|
||||
try {
|
||||
//如果 classPath 不存在,则获取的输入流会为 null
|
||||
inputStream=new BufferedInputStream(new FileInputStream(MainApp.getClientPath()+ File.separator+"ndn"+File.separator+"settings.properties"));
|
||||
if (inputStream == null) {
|
||||
System.out.println("没有找到配置文件...");
|
||||
}
|
||||
Properties settingProperties = new Properties();
|
||||
settingProperties.load(inputStream);
|
||||
if(flag==true){
|
||||
settingProperties.setProperty("LoginStatus","true");
|
||||
}else{
|
||||
settingProperties.setProperty("LoginStatus","false");
|
||||
}
|
||||
outputStream=new BufferedOutputStream(new FileOutputStream(MainApp.getClientPath()+ File.separator+"ndn"+File.separator+"settings.properties"));
|
||||
settingProperties.store(outputStream,"修改配置文件");
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}finally{
|
||||
//关闭输入流
|
||||
if (inputStream != null) {
|
||||
try {
|
||||
inputStream.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
//关闭输出流
|
||||
if (outputStream != null) {
|
||||
try {
|
||||
outputStream.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void setLoginInfo(Loginer loginer){
|
||||
InputStream inputStream = null;
|
||||
OutputStream outputStream=null;
|
||||
try {
|
||||
//如果 classPath 不存在,则获取的输入流会为 null
|
||||
inputStream=new BufferedInputStream(new FileInputStream(MainApp.getClientPath()+ File.separator+"ndn"+File.separator+"settings.properties"));
|
||||
if (inputStream == null) {
|
||||
System.out.println("没有找到配置文件...");
|
||||
}
|
||||
Properties settingProperties = new Properties();
|
||||
settingProperties.load(inputStream);
|
||||
settingProperties.setProperty("loginUserName", EncryptionUtil.encryptBasedAES(loginer.getUserName()));
|
||||
settingProperties.setProperty("loginPassWord", EncryptionUtil.encryptBasedAES(loginer.getPassWord()));
|
||||
outputStream=new BufferedOutputStream(new FileOutputStream(MainApp.getClientPath()+ File.separator+"ndn"+File.separator+"settings.properties"));
|
||||
settingProperties.store(outputStream,"修改配置文件");
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}finally{
|
||||
//关闭输入流
|
||||
if (inputStream != null) {
|
||||
try {
|
||||
inputStream.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
//关闭输出流
|
||||
if (outputStream != null) {
|
||||
try {
|
||||
outputStream.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static Loginer getLoginerInfo(){
|
||||
Loginer m_loginer=new Loginer();
|
||||
InputStream inputStream = null;
|
||||
try {
|
||||
//如果 classPath 不存在,则获取的输入流会为 null
|
||||
inputStream = new BufferedInputStream(new FileInputStream(MainApp.getClientPath() + File.separator + "ndn" + File.separator + "settings.properties"));
|
||||
// inputStream = MainApp.class.getClassLoader().getResourceAsStream("/ndn/settings.properties");
|
||||
if (inputStream == null) {
|
||||
System.out.println("没有找到配置文件...");
|
||||
}
|
||||
Properties settingProperties = new Properties();
|
||||
settingProperties.load(inputStream);
|
||||
String username = EncryptionUtil.decryptBasedAES(settingProperties.getProperty("loginUserName"));
|
||||
String password = EncryptionUtil.decryptBasedAES(settingProperties.getProperty("loginPassWord"));
|
||||
// System.out.println("username: " + username);
|
||||
// System.out.println("password: " + password);
|
||||
m_loginer.setUserName(username);
|
||||
m_loginer.setPassWord(password);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
//关闭输入流
|
||||
if (inputStream != null) {
|
||||
try {
|
||||
inputStream.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
return m_loginer;
|
||||
}
|
||||
|
||||
public static boolean getLogineStatus(){
|
||||
InputStream inputStream = null;
|
||||
try {
|
||||
//如果 classPath 不存在,则获取的输入流会为 null
|
||||
inputStream = new BufferedInputStream(new FileInputStream(MainApp.getClientPath() + File.separator + "ndn" + File.separator + "settings.properties"));
|
||||
// inputStream = MainApp.class.getClassLoader().getResourceAsStream("/ndn/settings.properties");
|
||||
if (inputStream == null) {
|
||||
System.out.println("没有找到配置文件...");
|
||||
}
|
||||
Properties settingProperties = new Properties();
|
||||
settingProperties.load(inputStream);
|
||||
String LoginStatus = settingProperties.getProperty("LoginStatus");
|
||||
if(LoginStatus.equals("true")){
|
||||
return true;
|
||||
}else{
|
||||
return false;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
} finally {
|
||||
//关闭输入流
|
||||
if (inputStream != null) {
|
||||
try {
|
||||
inputStream.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,16 +6,26 @@ import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
|
||||
import cn.minoa.dataRequestInterface.MinoaDataAPI;
|
||||
import cn.minoa.dataRequestInterface.*;
|
||||
import cn.minoa.model.Loginer;
|
||||
import cn.minoa.util.EncryptionUtil;
|
||||
import cn.minoa.util.KeyStorageUtil;
|
||||
import cn.minoa.util.SecretKeyManageUtil;
|
||||
import javafx.scene.image.Image;
|
||||
import javafx.scene.image.ImageView;
|
||||
import javafx.stage.FileChooser;
|
||||
import javafx.stage.Stage;
|
||||
import net.named_data.jndn.security.KeyChain;
|
||||
import net.named_data.jndn.security.pib.Pib;
|
||||
import net.named_data.jndn.security.pib.PibImpl;
|
||||
import net.named_data.jndn.security.tpm.Tpm;
|
||||
import net.named_data.jndn.security.tpm.TpmBackEnd;
|
||||
import net.named_data.jndn.security.v2.CertificateV2;
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import cn.minoa.MainApp;
|
||||
import cn.minoa.dataRequestInterface.OrderInfo;
|
||||
import cn.minoa.dataRequestInterface.ResponseData;
|
||||
import cn.minoa.model.Person;
|
||||
import cn.minoa.model.SingleMessage;
|
||||
import cn.minoa.model.SingleNotice;
|
||||
@@ -90,22 +100,67 @@ public class LoginOverviewController {
|
||||
private void handleLogin() {
|
||||
// 实例化
|
||||
// mainApp.minoaDataAPI = new MinoaDataAPI(mainApp);
|
||||
String userNameString=userNameFiled.getText().trim();
|
||||
String passWordString=passwordFiled.getText().trim();
|
||||
if(userNameString.equals("")){
|
||||
return ;
|
||||
}
|
||||
// 登录之前先查看本地是否有该用户拥有的证书
|
||||
String keyChainNameString="/"+userNameString;
|
||||
try {
|
||||
if(!KeyManager.INSTANCE.isInKeyChain(keyChainNameString)){
|
||||
// 弹窗参考:https://code.makery.ch/blog/javafx-dialogs-official/
|
||||
Alert alert = new Alert(AlertType.WARNING);
|
||||
alert.setTitle("密钥错误");
|
||||
alert.setHeaderText("本地没有你的密钥");
|
||||
alert.setContentText("请导入密钥/证书。");
|
||||
alert.showAndWait();
|
||||
return;
|
||||
}
|
||||
} catch (Pib.Error | PibImpl.Error | Tpm.Error | TpmBackEnd.Error | CertificateV2.Error | KeyChain.Error error) {
|
||||
error.printStackTrace();
|
||||
return;
|
||||
}
|
||||
// 每次手动登录之前,将keyChain初始化一下
|
||||
MinoaDataAPI.keyChainNameString=keyChainNameString;
|
||||
try {
|
||||
KeyManager.INSTANCE.initKeyChain(keyChainNameString);
|
||||
} catch (Pib.Error | PibImpl.Error | Tpm.Error | TpmBackEnd.Error | CertificateV2.Error | KeyChain.Error error) {
|
||||
error.printStackTrace();
|
||||
}
|
||||
// 登录验证
|
||||
String loginString = getLoginJsonString();
|
||||
boolean isRight = checkPass(loginString);
|
||||
if (isRight) {
|
||||
// 持久化保存当前用户名和密码
|
||||
keepLoginInfo(true,userNameString,passWordString);
|
||||
// 持久化保存当前keyName
|
||||
KeyStorageUtil.setKeyName(keyChainNameString);
|
||||
// 修改登录状态
|
||||
mainApp.isNeedKnowLoginStatus=true;
|
||||
mainApp.iniShow();
|
||||
} else {
|
||||
// 弹窗参考:https://code.makery.ch/blog/javafx-dialogs-official/
|
||||
Alert alert = new Alert(AlertType.WARNING);
|
||||
alert.setTitle("Wrong UserName or Password");
|
||||
alert.setHeaderText("Please correct UserName or Password.");
|
||||
alert.setContentText("Please correct UserName or Password.");
|
||||
alert.setTitle("用户名或密码错误");
|
||||
alert.setHeaderText("请核对用户名或密码");
|
||||
alert.setContentText("请核对用户名或密码。\n" +
|
||||
"如果你故意导入了首字段与用户名相同的密钥证书,但" +
|
||||
"该证书是非法生成的,也将弹出该弹窗!!!");
|
||||
alert.showAndWait();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean checkPass(String loginJsonString) {
|
||||
// 将账号密码保存在本地
|
||||
private void keepLoginInfo(boolean flag,String username,String passord){
|
||||
Loginer m_loginer=new Loginer();
|
||||
m_loginer.setUserName(username);
|
||||
m_loginer.setPassWord(passord);
|
||||
KeepLoginStatus.setLoginStatus(flag);
|
||||
KeepLoginStatus.setLoginInfo(m_loginer);
|
||||
}
|
||||
|
||||
public boolean checkPass(String loginJsonString) {
|
||||
System.out.println("checking your password...");
|
||||
boolean flag = false;
|
||||
// 发送数据请求
|
||||
@@ -156,7 +211,7 @@ public class LoginOverviewController {
|
||||
}
|
||||
|
||||
// 请求服务器某文件的大小:返回-1表示没有该文件或登录失效
|
||||
public Integer getServerFileLength(String filename) {
|
||||
public Long getServerFileLength(String filename) {
|
||||
// 发送数据请求
|
||||
Long seqLong = mainApp.getNewDataReqId();
|
||||
orderInfo.setSeq(seqLong);
|
||||
@@ -179,196 +234,70 @@ public class LoginOverviewController {
|
||||
try {
|
||||
dataString = jsonObject.getString("data");
|
||||
JSONObject dataJsonObject = new JSONObject(dataString);
|
||||
Integer fileSize= dataJsonObject.getInt("fileSize");
|
||||
Long fileSize= dataJsonObject.getLong("fileSize");
|
||||
return fileSize;
|
||||
} catch (JSONException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
return (long)-1;
|
||||
}
|
||||
|
||||
// 下载文件[返回0:已经成功接收所有回执数据并写入本地文件]
|
||||
public Integer downloadFile(String filename) {
|
||||
// 发送数据请求
|
||||
Long seqLong = mainApp.getNewDataReqId();
|
||||
orderInfo.setSeq(seqLong);
|
||||
orderInfo.setJsonString(getFileInfoJson(filename));
|
||||
mainApp.minoaDataAPI.executeOrder("/fileInfo", orderInfo);
|
||||
// 获取头像信息
|
||||
ResponseData responseData = mainApp.minoaDataAPI.dataCacheQueue.getResponseDataBySeq(seqLong);
|
||||
JSONObject jsonObject = responseData.praseRequestData();
|
||||
System.out.println("fileInfo-JSON: " + jsonObject.toString());
|
||||
Integer codeInteger = null;
|
||||
try {
|
||||
codeInteger = jsonObject.getInt("code");
|
||||
} catch (JSONException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (codeInteger == 200) {
|
||||
String dataString;
|
||||
try {
|
||||
dataString = jsonObject.getString("data");
|
||||
JSONObject dataJsonObject = new JSONObject(dataString);
|
||||
Integer sliceNumInteger;
|
||||
sliceNumInteger = dataJsonObject.getInt("sliceNum");
|
||||
// 根据分片信息获取每个分片,并合并成一个完整比特流
|
||||
Integer flagInteger = 0;
|
||||
for (int i = 0; i < sliceNumInteger; i++) {
|
||||
flagInteger += downLoadFileBySlice(filename, i);
|
||||
// 导入密钥
|
||||
@FXML
|
||||
private void importSafeBag(){
|
||||
// SecretKeyManageUtil.testSecretKey(KeyStorageUtil.getKeyName());
|
||||
// System.out.println("#####test end#####");
|
||||
FileChooser fileChooser = new FileChooser();
|
||||
fileChooser.setTitle("选择密钥文件");
|
||||
Stage selectFileStage = new Stage();
|
||||
File file = fileChooser.showOpenDialog(selectFileStage);
|
||||
if (file != null) {
|
||||
// 文件不为空,且不是文件夹
|
||||
if (file.isFile()) {
|
||||
//判断文件长度是否为0
|
||||
System.out.println("file length: " + file.length());
|
||||
if (file.length() == 0) {
|
||||
// 弹窗参考:https://code.makery.ch/blog/javafx-dialogs-official/
|
||||
Alert alert = new Alert(AlertType.WARNING);
|
||||
alert.setTitle("空文件错误");
|
||||
alert.setHeaderText("您选择的是一个空文件");
|
||||
alert.setContentText("您选择的是一个空文件,请重新选择。");
|
||||
alert.showAndWait();
|
||||
return;
|
||||
}
|
||||
System.out.println("下载分片的消息回执[0表示全部数据分片已经被写入本地]: " + flagInteger);
|
||||
return flagInteger;
|
||||
} catch (JSONException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
return 1;
|
||||
} else {
|
||||
// 弹窗参考:https://code.makery.ch/blog/javafx-dialogs-official/
|
||||
Alert alert = new Alert(AlertType.WARNING);
|
||||
alert.setTitle("文件类型错误");
|
||||
alert.setHeaderText("你的文件类型错误");
|
||||
alert.setContentText("请确保你选中的是一个文件而非文件夹。");
|
||||
alert.showAndWait();
|
||||
return ;
|
||||
}
|
||||
}else{
|
||||
return ;
|
||||
}
|
||||
// 将所选文件导入密钥
|
||||
String res= SecretKeyManageUtil.importSafeBag(file.getAbsolutePath());
|
||||
if(res.equals("success")){
|
||||
// 弹窗参考:https://code.makery.ch/blog/javafx-dialogs-official/
|
||||
Alert alert = new Alert(Alert.AlertType.INFORMATION);
|
||||
alert.setTitle("密钥导入成功");
|
||||
alert.setHeaderText("密钥导入成功");
|
||||
alert.setContentText("你已成功导入密钥");
|
||||
alert.showAndWait();
|
||||
}else{
|
||||
// 弹窗参考:https://code.makery.ch/blog/javafx-dialogs-official/
|
||||
Alert alert = new Alert(Alert.AlertType.WARNING);
|
||||
alert.setTitle("密钥导入失败");
|
||||
alert.setHeaderText("密钥导入失败");
|
||||
alert.setContentText("由于如下原因,密钥导入时出现了问题:\n"+res);
|
||||
alert.showAndWait();
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* @param filename 要下载的文件的“服务器路径+文件名称”,即写入请求的名称
|
||||
*
|
||||
* @param localDir 要下载文件到的本地地址
|
||||
*
|
||||
* @param localName 要下载的文件重命名之后的本地名称
|
||||
*
|
||||
* @return 0表示已经成功接收所有回执数据并写入本地文件,否则出现error
|
||||
*
|
||||
* 目的是下载头像到指定路径,并重命名之。
|
||||
*/
|
||||
private Integer downloadRenamedFileToSpecifiedDir(String filename, String localDir, String localName) {
|
||||
// 发送数据请求
|
||||
Long seqLong = mainApp.getNewDataReqId();
|
||||
orderInfo.setSeq(seqLong);
|
||||
orderInfo.setJsonString(getFileInfoJson(filename));
|
||||
mainApp.minoaDataAPI.executeOrder("/fileInfo", orderInfo);
|
||||
// 获取头像信息
|
||||
ResponseData responseData = mainApp.minoaDataAPI.dataCacheQueue.getResponseDataBySeq(seqLong);
|
||||
JSONObject jsonObject = responseData.praseRequestData();
|
||||
System.out.println("fileInfo-JSON: " + jsonObject.toString());
|
||||
Integer codeInteger = null;
|
||||
try {
|
||||
codeInteger = jsonObject.getInt("code");
|
||||
} catch (JSONException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (codeInteger == 200) {
|
||||
String dataString;
|
||||
try {
|
||||
dataString = jsonObject.getString("data");
|
||||
JSONObject dataJsonObject = new JSONObject(dataString);
|
||||
Integer sliceNumInteger;
|
||||
sliceNumInteger = dataJsonObject.getInt("sliceNum");
|
||||
// 根据分片信息获取每个分片,并合并成一个完整比特流
|
||||
Integer flagInteger = 0;
|
||||
for (int i = 0; i < sliceNumInteger; i++) {
|
||||
flagInteger += downLoadFileBySlice(filename, i, localDir, localName);
|
||||
}
|
||||
System.out.println("下载分片的消息回执[0表示全部数据分片已经被写入本地]: " + flagInteger);
|
||||
return flagInteger;
|
||||
} catch (JSONException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* @param filename 要下载的文件的“服务器路径+文件名称”,即写入请求的名称
|
||||
*
|
||||
* @param localDir 要下载文件到的本地地址
|
||||
*
|
||||
* @return 0表示已经成功接收所有回执数据并写入本地文件,否则出现error
|
||||
*
|
||||
* .下载服务器文件到本地指定目录下
|
||||
*/
|
||||
public Integer downloadFileToSpecifiedDir(String filename, String localDir) {
|
||||
// 下载到本地的文件名称
|
||||
String localName = getPureFileName(filename);
|
||||
// 发送数据请求
|
||||
Long seqLong = mainApp.getNewDataReqId();
|
||||
orderInfo.setSeq(seqLong);
|
||||
orderInfo.setJsonString(getFileInfoJson(filename));
|
||||
mainApp.minoaDataAPI.executeOrder("/fileInfo", orderInfo);
|
||||
// 获取文件信息
|
||||
ResponseData responseData = mainApp.minoaDataAPI.dataCacheQueue.getResponseDataBySeq(seqLong);
|
||||
JSONObject jsonObject = responseData.praseRequestData();
|
||||
System.out.println("fileInfo-JSON: " + jsonObject.toString());
|
||||
Integer codeInteger = null;
|
||||
try {
|
||||
codeInteger = jsonObject.getInt("code");
|
||||
} catch (JSONException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (codeInteger == 200) {
|
||||
String dataString;
|
||||
try {
|
||||
dataString = jsonObject.getString("data");
|
||||
JSONObject dataJsonObject = new JSONObject(dataString);
|
||||
Integer sliceNumInteger;
|
||||
sliceNumInteger = dataJsonObject.getInt("sliceNum");
|
||||
// 根据分片信息获取每个分片,并合并成一个完整比特流
|
||||
Integer flagInteger = 0;
|
||||
for (int i = 0; i < sliceNumInteger; i++) {
|
||||
flagInteger += downLoadFileBySlice(filename, i, localDir, localName);
|
||||
}
|
||||
System.out.println("下载分片的消息回执[0表示全部数据分片已经被写入本地]: " + flagInteger);
|
||||
return flagInteger;
|
||||
} catch (JSONException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
// 请求文件分片数据=>返回0表示分片数据被成功下载
|
||||
public Integer downLoadFileBySlice(String filename, Integer sliceNo, String localDir, String localName) {
|
||||
Integer flagInteger;
|
||||
// 发送数据请求
|
||||
Long seqLong = mainApp.getNewDataReqId();
|
||||
orderInfo.setSeq(seqLong);
|
||||
orderInfo.setJsonString(getDownloadFileJson(filename, sliceNo));
|
||||
mainApp.minoaDataAPI.executeOrder("/downloadFile", orderInfo, localDir, localName);
|
||||
// 获取头像信息
|
||||
ResponseData responseData = mainApp.minoaDataAPI.dataCacheQueue.getResponseDataBySeq(seqLong);
|
||||
// JSONObject jsonObject=responseData.praseRequestData();
|
||||
System.out.println("downloadFileSlice-JSON: " + responseData.getResponseJsonDataString());
|
||||
flagInteger = Integer.parseInt(responseData.getResponseJsonDataString());
|
||||
return flagInteger;
|
||||
}
|
||||
|
||||
// 生成本地文件=>没有用到
|
||||
// public void creatLocalFile(String filename,byte[] fileBytes) {
|
||||
// FileOutputStream out;
|
||||
// try {
|
||||
// out = new FileOutputStream(new File(filename));
|
||||
// try {
|
||||
// out.write(fileBytes);
|
||||
// out.flush();
|
||||
// System.out.println("download success");
|
||||
// out.close();
|
||||
// } catch (IOException e) {
|
||||
// // TODO Auto-generated catch block
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
// } catch (FileNotFoundException e) {
|
||||
// // TODO Auto-generated catch block
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
// }
|
||||
|
||||
// 根据包含路径的文件名获取纯文件名[linux下]
|
||||
public String getPureFileName(String pathfilename) {
|
||||
// 标记最后一个/的下标
|
||||
@@ -387,40 +316,6 @@ public class LoginOverviewController {
|
||||
}
|
||||
}
|
||||
|
||||
// 根据包含路径的文件名获取纯文件名
|
||||
// public String getPureFileName(String pathfilename) {
|
||||
// // 文件名称切割
|
||||
// while (pathfilename.indexOf('/') > 0) {
|
||||
// pathfilename = pathfilename.substring(pathfilename.indexOf('/') + 1, pathfilename.length());
|
||||
// }
|
||||
// System.out.println("pure file name: " + pathfilename);
|
||||
// return pathfilename;
|
||||
// }
|
||||
|
||||
// 合并两个Byte[]
|
||||
// public Byte[] byteMerger(Byte[] bt1, Byte[] bt2){
|
||||
// Byte[] bt3 = new Byte[bt1.length+bt2.length];
|
||||
// System.arraycopy(bt1, 0, bt3, 0, bt1.length);
|
||||
// System.arraycopy(bt2, 0, bt3, bt1.length, bt2.length);
|
||||
// return bt3;
|
||||
// }
|
||||
|
||||
// 请求文件分片数据=>返回0表示分片数据被成功下载
|
||||
private Integer downLoadFileBySlice(String filename, Integer sliceNo) {
|
||||
Integer flagInteger;
|
||||
// 发送数据请求
|
||||
Long seqLong = mainApp.getNewDataReqId();
|
||||
orderInfo.setSeq(seqLong);
|
||||
orderInfo.setJsonString(getDownloadFileJson(filename, sliceNo));
|
||||
mainApp.minoaDataAPI.executeOrder("/downloadFile", orderInfo);
|
||||
// 获取头像信息
|
||||
ResponseData responseData = mainApp.minoaDataAPI.dataCacheQueue.getResponseDataBySeq(seqLong);
|
||||
// JSONObject jsonObject=responseData.praseRequestData();
|
||||
System.out.println("downloadFileSlice-JSON: " + responseData.getResponseJsonDataString());
|
||||
flagInteger = Integer.parseInt(responseData.getResponseJsonDataString());
|
||||
return flagInteger;
|
||||
}
|
||||
|
||||
// 获取要下载的文件信息
|
||||
public String getFileInfoJson(String filename) {
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
@@ -440,22 +335,18 @@ public class LoginOverviewController {
|
||||
return jsonObject.toString();
|
||||
}
|
||||
|
||||
// 获取要下载的文件信息
|
||||
private String getDownloadFileJson(String filename, Integer sliceNo) {
|
||||
public String getLoginJsonString(String userNameString,String passWordString) {
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
String commandString = "/downloadFile";
|
||||
String usernameString = mainApp.loginer.getUserName();
|
||||
String uuidString = mainApp.loginer.getUuid();
|
||||
String filenameString = filename;
|
||||
Integer sliceNoInteger = sliceNo;
|
||||
String commandString = "/login";
|
||||
// 对密码进行哈希加密
|
||||
passWordString= EncryptionUtil.getMD5String(passWordString);
|
||||
mainApp.loginer.setUserName(userNameString);
|
||||
mainApp.loginer.setPassWord(passWordString);
|
||||
try {
|
||||
jsonObject.put("command", commandString);
|
||||
jsonObject.put("username", usernameString);
|
||||
jsonObject.put("uuid", uuidString);
|
||||
jsonObject.put("filename", filenameString);
|
||||
jsonObject.put("sliceNo", sliceNoInteger);
|
||||
jsonObject.put("username", userNameString);
|
||||
jsonObject.put("password", passWordString);
|
||||
} catch (Exception e) {
|
||||
// TODO: handle exception
|
||||
System.out.println("exception: " + e.getMessage());
|
||||
}
|
||||
return jsonObject.toString();
|
||||
@@ -467,14 +358,8 @@ public class LoginOverviewController {
|
||||
String commandString = "/login";
|
||||
String userNameString = userNameFiled.getText().trim();
|
||||
String passWordString = passwordFiled.getText().trim();
|
||||
if (userNameString == null || passWordString == null) {
|
||||
// 弹窗参考:https://code.makery.ch/blog/javafx-dialogs-official/
|
||||
Alert alert = new Alert(AlertType.WARNING);
|
||||
alert.setTitle("UserName or Password is null");
|
||||
alert.setHeaderText("Please correct UserName or Password.");
|
||||
alert.setContentText("Please correct UserName or Password.");
|
||||
alert.showAndWait();
|
||||
}
|
||||
// 对密码进行哈希加密
|
||||
passWordString= EncryptionUtil.getMD5String(passWordString);
|
||||
mainApp.loginer.setUserName(userNameString);
|
||||
mainApp.loginer.setPassWord(passWordString);
|
||||
try {
|
||||
@@ -1076,112 +961,51 @@ public class LoginOverviewController {
|
||||
return jsonObject.toString();
|
||||
}
|
||||
|
||||
// //"获取2019年9月1日之后与该选中人的100条互发消息"
|
||||
// private String getGetRTMsgLogJson(Person selectedPerson) {
|
||||
// JSONObject jsonObject =new JSONObject();
|
||||
// String commandString="/getRTMsgLog";
|
||||
// String userNameString=mainApp.loginer.getUserName();
|
||||
// String uuidString=mainApp.loginer.getUuid();
|
||||
// String peerString=selectedPerson.getUserName();
|
||||
// Long timestampLong = null;
|
||||
// try {
|
||||
// timestampLong=get20190901();
|
||||
// } catch (ParseException e1) {
|
||||
// // TODO Auto-generated catch block
|
||||
// e1.printStackTrace();
|
||||
// }
|
||||
// //期望获取的信息条数
|
||||
// Integer limitInteger=100;
|
||||
// //0表示时间节点之后,1表示之前
|
||||
// Integer directInteger=0;
|
||||
// try {
|
||||
// jsonObject.put("command", commandString);
|
||||
// jsonObject.put("username", userNameString);
|
||||
// jsonObject.put("uuid", uuidString);
|
||||
// jsonObject.put("peer", peerString);
|
||||
// jsonObject.put("timestamp", timestampLong);
|
||||
// jsonObject.put("limit", limitInteger);
|
||||
// jsonObject.put("direct", directInteger);
|
||||
// } catch (Exception e) {
|
||||
// // TODO: handle exception
|
||||
// System.out.println("exception: " + e.getMessage());
|
||||
// }
|
||||
// return jsonObject.toString();
|
||||
// }
|
||||
|
||||
//获取上传文件的json格式
|
||||
public String getUploadFile(String filename, Integer offset) {
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
String commandString = "/uploadFile";
|
||||
String usernameString = mainApp.loginer.getUserName();
|
||||
String uuidString = mainApp.loginer.getUuid();
|
||||
String filenameString = filename;
|
||||
Integer offsetInteger = offset;
|
||||
try {
|
||||
jsonObject.put("command", commandString);
|
||||
jsonObject.put("username", usernameString);
|
||||
jsonObject.put("uuid", uuidString);
|
||||
jsonObject.put("filename", filenameString);
|
||||
jsonObject.put("offset", offsetInteger);
|
||||
} catch (Exception e) {
|
||||
// TODO: handle exception
|
||||
System.out.println("exception: " + e.getMessage());
|
||||
}
|
||||
// 调试输出
|
||||
System.out.println("getUploadFile: "+jsonObject.toString());
|
||||
return jsonObject.toString();
|
||||
}
|
||||
|
||||
/*
|
||||
* .文件上传操作
|
||||
* @param serverpath 将该文件上传到的指定服务器路径
|
||||
* @param file 要上传的本地文件
|
||||
* @return 返回0表示传输成功;返回-1表示传输失败
|
||||
* @param filename 要下载的文件的“服务器路径+文件名称”,即写入请求的名称
|
||||
*
|
||||
* @param localDir 要下载文件到的本地地址
|
||||
*
|
||||
* @param localName 要下载的文件重命名之后的本地名称
|
||||
*
|
||||
* @return 0表示已经成功接收所有回执数据并写入本地文件,否则出现error
|
||||
*
|
||||
* 目的是下载头像到指定路径,并重命名之。
|
||||
*/
|
||||
public Integer sendFileToServer(File file, String serverpath) {
|
||||
//获取要上传文件的文件长度,计算上传次数
|
||||
long filelen = file.length();
|
||||
int cycle = (int) filelen / mainApp.sliceSize;
|
||||
int remainder=(int)filelen%mainApp.sliceSize;
|
||||
if((cycle>0)&&(remainder==0)) {
|
||||
cycle--;
|
||||
private Integer downloadRenamedFileToSpecifiedDir(String filename, String localDir, String localName){
|
||||
Long filelen=getServerFileLength(filename);
|
||||
Integer sliceNum = (int)(filelen / mainApp.sliceSize);
|
||||
if (filelen % mainApp.sliceSize != 0) {
|
||||
sliceNum++;
|
||||
}
|
||||
System.out.println("file-len: " + filelen);
|
||||
System.out.println("cycle: " + cycle);
|
||||
//发送上传命令给上传接口,接口自行取本地数据
|
||||
int flagSuccess = 0; //记录收到200回复的次数
|
||||
for (int i = 0; i <= cycle; i++) {
|
||||
OrderInfo orderInfo = new OrderInfo();
|
||||
ResponseData responseData = new ResponseData();
|
||||
Long seqLong = mainApp.getNewDataReqId();
|
||||
orderInfo.setSeq(seqLong);
|
||||
//此时传入的文件路径是windows下的绝对路径
|
||||
orderInfo.setJsonString(getUploadFile(file.getAbsolutePath(), i * mainApp.sliceSize));
|
||||
|
||||
mainApp.minoaDataAPI.executeOrder("/uploadFile", orderInfo, serverpath);
|
||||
responseData = mainApp.minoaDataAPI.dataCacheQueue.getResponseDataBySeq(seqLong);
|
||||
// System.out.println("上传文件的数据回执(200表示成功):"+responseData.getResponseJsonDataString());
|
||||
JSONObject jsonObject = responseData.praseRequestData();
|
||||
responseData.printSelf();
|
||||
// 解析数据
|
||||
Integer codeInteger = null;
|
||||
try {
|
||||
codeInteger = jsonObject.getInt("code");
|
||||
} catch (JSONException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (codeInteger == 200) {
|
||||
flagSuccess++;
|
||||
}
|
||||
}
|
||||
//每个分片都上传成功
|
||||
if (flagSuccess == (cycle + 1)) {
|
||||
System.out.println("已成功将文件" + file.getAbsolutePath() + "上传至服务器" + serverpath + "目录下。");
|
||||
Long startTime = System.currentTimeMillis();
|
||||
DownLoadClientBasedFacePool downLoadClient = new DownLoadClientBasedFacePool(filename,
|
||||
localDir,sliceNum,mainApp.threadNumberForFileTransfer);
|
||||
// 下载文件
|
||||
boolean res = downLoadClient.downloadData();
|
||||
Long endTime = System.currentTimeMillis();
|
||||
System.out.println("耗时:" + (endTime - startTime) + "ms");
|
||||
// 每个分片都下载成功
|
||||
if (res) {
|
||||
// 重命名该文件
|
||||
String fromPathName=localDir
|
||||
+MinoaDataAPI.getPureFileName(filename);
|
||||
String toPathName=localDir+localName;
|
||||
renameLocalFile(fromPathName,toPathName);
|
||||
return 0;
|
||||
} else {
|
||||
System.out.println("由于未知原因,本地文件" + file.getAbsolutePath() + "上传服务器失败。");
|
||||
}else{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
// 重命名本地文件
|
||||
private void renameLocalFile(String fromPathName,String toPathName){
|
||||
File file=new File(fromPathName);
|
||||
if (file.exists()) {
|
||||
File toPathNameFile= new File(toPathName);
|
||||
file.renameTo(toPathNameFile);
|
||||
}else{
|
||||
System.out.println("要重命名的文件不存在");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,294 @@
|
||||
package cn.minoa.view.login;
|
||||
// 与区块链建立TCP连接,发送注册请求
|
||||
|
||||
import cn.minoa.MainApp;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.Socket;
|
||||
|
||||
public class NDNBlockChainConnectClient {
|
||||
|
||||
private String NDNBlockChainIPAddress;
|
||||
private Integer NDNBlockChainPortAddress;
|
||||
|
||||
public NDNBlockChainConnectClient(){
|
||||
// this.NDNBlockChainIPAddress="116.77.74.144";
|
||||
// this.NDNBlockChainIPAddress="121.15.171.86";
|
||||
// this.NDNBlockChainPortAddress=8010;
|
||||
this.NDNBlockChainIPAddress= MainApp.NDNBlockChainIPAddress;
|
||||
System.out.println("区块链IP:"+ MainApp.NDNBlockChainIPAddress);
|
||||
this.NDNBlockChainPortAddress= MainApp.NDNBlockChainPortAddress;
|
||||
System.out.println("区块链Port:"+ MainApp.NDNBlockChainPortAddress);
|
||||
}
|
||||
|
||||
public NDNBlockChainConnectClient(String ipAddress, Integer portAddress){
|
||||
this.NDNBlockChainIPAddress= ipAddress;
|
||||
this.NDNBlockChainPortAddress=portAddress;
|
||||
}
|
||||
|
||||
// 添加白名单
|
||||
public String addWhiteUser(String phone){
|
||||
// 获取注册数组
|
||||
byte[] registerByte=getBlockChainWhiteBuffer(phone);
|
||||
System.out.println("whiteuser length: "+registerByte.length);
|
||||
// 通过TCP连接区块链后台
|
||||
Socket blockchainClient;
|
||||
try {
|
||||
blockchainClient=new Socket(NDNBlockChainIPAddress,NDNBlockChainPortAddress);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
System.out.println("连接不可达:"+NDNBlockChainIPAddress+":"+NDNBlockChainPortAddress);
|
||||
return e.getMessage();
|
||||
}
|
||||
System.out.println("已成功建立TCP连接:"+NDNBlockChainIPAddress+":"+NDNBlockChainPortAddress
|
||||
+"; 远程主机地址:"+blockchainClient.getRemoteSocketAddress());
|
||||
try {
|
||||
OutputStream outToServer = blockchainClient.getOutputStream();
|
||||
DataOutputStream out = new DataOutputStream(outToServer);
|
||||
|
||||
out.write(registerByte);
|
||||
InputStream inFromServer = blockchainClient.getInputStream();
|
||||
DataInputStream in = new DataInputStream(inFromServer);
|
||||
System.out.println("正在等待服务器响应...");
|
||||
byte[] res = new byte[4];
|
||||
in.read(res);
|
||||
int resSize = Bytes2Int_LE(res);
|
||||
System.out.println("返回值长度为:"+ resSize);
|
||||
res = new byte[resSize];
|
||||
in.read(res);
|
||||
System.out.println("返回值内容为:" + new String(res));
|
||||
blockchainClient.close();
|
||||
System.out.println("已关闭此次TCP连接:"+NDNBlockChainIPAddress+":"+NDNBlockChainPortAddress);
|
||||
// System.out.println("服务器响应: " );
|
||||
// 解析返回来的数据,如果是200,就返回true
|
||||
try {
|
||||
String resString=new String(res);
|
||||
System.out.println("resString: "+resString);
|
||||
JSONObject resObject=new JSONObject(resString);
|
||||
int resCode=resObject.getInt("StatusCode");
|
||||
String message=resObject.getString("Message");
|
||||
if(resCode==200){
|
||||
System.out.println("区块链添加白名单成功:"+phone);
|
||||
return "true";
|
||||
}else{
|
||||
return message;
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
return e.getMessage();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
System.out.println("添加白名单时数据交换出错:"+NDNBlockChainIPAddress+":"+NDNBlockChainPortAddress);
|
||||
return e.getMessage();
|
||||
}
|
||||
// return true;
|
||||
}
|
||||
|
||||
// 注册用户
|
||||
public String registeNewUser(String username,String phone,String pubkey){
|
||||
// 获取注册数组
|
||||
byte[] registerByte=getBlockChainRegisterBuffer(username,phone, pubkey);
|
||||
System.out.println("register length: "+registerByte.length);
|
||||
// 通过TCP连接区块链后台
|
||||
Socket blockchainClient;
|
||||
try {
|
||||
blockchainClient=new Socket(NDNBlockChainIPAddress,NDNBlockChainPortAddress);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
System.out.println("连接不可达:"+NDNBlockChainIPAddress+":"+NDNBlockChainPortAddress);
|
||||
return e.getMessage();
|
||||
}
|
||||
System.out.println("已成功建立TCP连接:"+NDNBlockChainIPAddress+":"+NDNBlockChainPortAddress
|
||||
+"; 远程主机地址:"+blockchainClient.getRemoteSocketAddress());
|
||||
try {
|
||||
OutputStream outToServer = blockchainClient.getOutputStream();
|
||||
DataOutputStream out = new DataOutputStream(outToServer);
|
||||
|
||||
out.write(registerByte);
|
||||
InputStream inFromServer = blockchainClient.getInputStream();
|
||||
DataInputStream in = new DataInputStream(inFromServer);
|
||||
System.out.println("正在等待服务器响应...");
|
||||
byte[] res = new byte[4];
|
||||
in.read(res);
|
||||
int resSize = Bytes2Int_LE(res);
|
||||
System.out.println("返回值长度为:"+ resSize);
|
||||
res = new byte[resSize];
|
||||
in.read(res);
|
||||
System.out.println("返回值内容为:" + new String(res));
|
||||
System.out.println("服务器响应: " );
|
||||
blockchainClient.close();
|
||||
System.out.println("已关闭此次TCP连接:"+NDNBlockChainIPAddress+":"+NDNBlockChainPortAddress);
|
||||
// System.out.println("服务器响应: " );
|
||||
// 解析返回来的数据,如果是200,就返回true
|
||||
try {
|
||||
String resString=new String(res);
|
||||
System.out.println("resString: "+resString);
|
||||
JSONObject resObject=new JSONObject(resString);
|
||||
int resCode=resObject.getInt("StatusCode");
|
||||
String message=resObject.getString("Message");
|
||||
if(resCode==200){
|
||||
System.out.println("区块链注册用户成功:"+username);
|
||||
return "true";
|
||||
}else{
|
||||
return message;
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
return e.getMessage();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
System.out.println("注册时数据交换出错:"+NDNBlockChainIPAddress+":"+NDNBlockChainPortAddress);
|
||||
return e.getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private byte[] getBlockChainRegisterBuffer(String username,String phone, String pubkey) {
|
||||
String registerString=getBlockChainRegisterJsonString(username,phone, pubkey);
|
||||
System.out.println("json: "+registerString);
|
||||
int jsonLen = registerString.getBytes().length;
|
||||
System.out.println("json len: "+jsonLen);
|
||||
byte[] registerByte=new byte[jsonLen+4];
|
||||
// System.arraycopy(intToBytesLittle(jsonLen),0,
|
||||
// registerByte,0,4);
|
||||
System.arraycopy(intToBytesLittle(jsonLen),0,
|
||||
registerByte,0,4);
|
||||
try {
|
||||
System.arraycopy(registerString.getBytes("utf-8"),
|
||||
0,registerByte,4,jsonLen);
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return registerByte;
|
||||
}
|
||||
|
||||
private byte[] getBlockChainWhiteBuffer(String phone) {
|
||||
String registerString=getBlockChainWhiteUserJsonString(phone);
|
||||
System.out.println("json: "+registerString);
|
||||
int jsonLen = registerString.getBytes().length;
|
||||
System.out.println("json len: "+jsonLen);
|
||||
byte[] registerByte=new byte[jsonLen+4];
|
||||
// System.arraycopy(intToBytesLittle(jsonLen),0,
|
||||
// registerByte,0,4);
|
||||
System.arraycopy(intToBytesLittle(jsonLen),0,
|
||||
registerByte,0,4);
|
||||
try {
|
||||
System.arraycopy(registerString.getBytes("utf-8"),
|
||||
0,registerByte,4,jsonLen);
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return registerByte;
|
||||
}
|
||||
|
||||
/**
|
||||
* 以小端模式将int转成byte[]
|
||||
*
|
||||
* @param value
|
||||
* @return
|
||||
*/
|
||||
public static byte[] intToBytesLittle(int value) {
|
||||
byte[] src = new byte[4];
|
||||
src[3] = (byte) ((value >> 24) & 0xFF);
|
||||
src[2] = (byte) ((value >> 16) & 0xFF);
|
||||
src[1] = (byte) ((value >> 8) & 0xFF);
|
||||
src[0] = (byte) (value & 0xFF);
|
||||
return src;
|
||||
}
|
||||
|
||||
/**
|
||||
* 以大端模式将int转成byte[]
|
||||
*
|
||||
* @param value
|
||||
* @return
|
||||
*/
|
||||
public static byte[] intToBytesBig(int value) {
|
||||
byte[] src = new byte[4];
|
||||
src[0] = (byte) ((value >> 24) & 0xFF);
|
||||
src[1] = (byte) ((value >> 16) & 0xFF);
|
||||
src[2] = (byte) ((value >> 8) & 0xFF);
|
||||
src[3] = (byte) (value & 0xFF);
|
||||
return src;
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换byte数组为int(小端)
|
||||
* @return
|
||||
* @note 数组长度至少为4,按小端方式转换,即传入的bytes是小端的,按这个规律组织成int
|
||||
*/
|
||||
public int Bytes2Int_LE(byte[] bytes){
|
||||
if(bytes.length < 4)
|
||||
return -1;
|
||||
int iRst = (bytes[0] & 0xFF);
|
||||
iRst |= (bytes[1] & 0xFF) << 8;
|
||||
iRst |= (bytes[2] & 0xFF) << 16;
|
||||
iRst |= (bytes[3] & 0xFF)<< 24;
|
||||
|
||||
return iRst;
|
||||
}
|
||||
|
||||
// 从前端界面获得登录数据并转换成json格式
|
||||
private String getBlockChainWhiteUserJsonString(String phone) {
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
String typeString = "whiteUser";
|
||||
String commandString = "addWhiteUser";
|
||||
String RealNameString = "王锋";
|
||||
Integer GenderInteger=0;
|
||||
String IDCardString="";
|
||||
try {
|
||||
jsonObject.put("Type", typeString);
|
||||
jsonObject.put("Command", commandString);
|
||||
jsonObject.put("RealName",RealNameString);
|
||||
jsonObject.put("Phone",phone);
|
||||
jsonObject.put("Gender",GenderInteger);
|
||||
jsonObject.put("IDCard",IDCardString);
|
||||
} catch (Exception e) {
|
||||
System.out.println("exception: " + e.getMessage());
|
||||
}
|
||||
return jsonObject.toString();
|
||||
}
|
||||
|
||||
// 从前端界面获得登录数据并转换成json格式
|
||||
private String getBlockChainRegisterJsonString(String username,String phone, String pubkey) {
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
String typeString = "user-act";
|
||||
String commandString = "Registry";
|
||||
String pubkeyString = pubkey;
|
||||
String prefixString="/"+username;
|
||||
Integer level=0;
|
||||
String timestamp="";
|
||||
String IDCard="";
|
||||
String realname="";
|
||||
String aboutMe="";
|
||||
String face="";
|
||||
String print="";
|
||||
String iris="";
|
||||
String other="";
|
||||
String sig="";
|
||||
try {
|
||||
jsonObject.put("Type", typeString);
|
||||
jsonObject.put("Command", commandString);
|
||||
jsonObject.put("Pubkey", pubkeyString);
|
||||
jsonObject.put("Prefix",prefixString);
|
||||
jsonObject.put("Level",level);
|
||||
jsonObject.put("Timestamp",timestamp);
|
||||
jsonObject.put("Username",username);
|
||||
jsonObject.put("Realname",realname);
|
||||
jsonObject.put("Phone",phone);
|
||||
jsonObject.put("IDcard",IDCard);
|
||||
jsonObject.put("AboutMe",aboutMe);
|
||||
jsonObject.put("Face",face);
|
||||
jsonObject.put("Print",print);
|
||||
jsonObject.put("Iris",iris);
|
||||
jsonObject.put("Other",other);
|
||||
jsonObject.put("Sig",sig);
|
||||
} catch (Exception e) {
|
||||
System.out.println("exception: " + e.getMessage());
|
||||
}
|
||||
return jsonObject.toString();
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,8 @@ package cn.minoa.view.mine;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
/*
|
||||
* 数据格式说明:
|
||||
@@ -11,7 +13,12 @@ import java.util.LinkedList;
|
||||
* .前端一个listview表项是一个pane,其id是"路径+纯文件名+@文件类型"
|
||||
*/
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import cn.minoa.model.SingleFile;
|
||||
import cn.minoa.util.FileUtil;
|
||||
import cn.minoa.util.StringByteLengthUtil;
|
||||
import cn.minoa.view.login.LoginOverviewController;
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
@@ -38,6 +45,8 @@ public class MyCloudFileController {
|
||||
private String currentPath;
|
||||
// 当前路径下的文件列表[path+file+@type]
|
||||
private List<String> filePathnameList;
|
||||
// 当前文件列表对应的文件具体信息,key是filePathnameList中的表项
|
||||
private Map<String, SingleFile> detailedFileListMap;
|
||||
|
||||
@FXML
|
||||
private Text pathText;
|
||||
@@ -53,6 +62,7 @@ public class MyCloudFileController {
|
||||
// TODO Auto-generated constructor stub
|
||||
currentPath = "/";
|
||||
filePathnameList = new LinkedList<String>();
|
||||
detailedFileListMap=new HashMap<String, SingleFile>();
|
||||
}
|
||||
|
||||
@FXML
|
||||
@@ -183,7 +193,7 @@ public class MyCloudFileController {
|
||||
}else{
|
||||
serverPathname=currentPath+"/"+file.getName();
|
||||
}
|
||||
Integer fileServerLength=mainApp.getServerFileByteLength(serverPathname);
|
||||
Long fileServerLength=mainApp.getServerFileByteLength(serverPathname);
|
||||
System.out.println("fileServerLength: "+fileServerLength);
|
||||
if(fileServerLength<0){
|
||||
//文件未成功创建
|
||||
@@ -259,7 +269,32 @@ public class MyCloudFileController {
|
||||
}
|
||||
|
||||
public void makeDir(String foldername) {
|
||||
//封死空文件夹
|
||||
if(foldername.trim().equals("")){
|
||||
return ;
|
||||
}
|
||||
// 封掉命名为/的文件夹
|
||||
if(foldername.trim().equals("/")){
|
||||
// 弹窗参考:https://code.makery.ch/blog/javafx-dialogs-official/
|
||||
Alert alert = new Alert(AlertType.WARNING);
|
||||
alert.setTitle("新建失败");
|
||||
alert.setHeaderText("新建文件夹失败");
|
||||
alert.setContentText("文件夹名称不许为\"/\"哦~");
|
||||
alert.showAndWait();
|
||||
return ;
|
||||
}
|
||||
foldername = currentPath + "/" + foldername;
|
||||
//封死在用户跟目录下创建share或cache文件夹
|
||||
if(foldername.equals("/share")||foldername.equals("/cache")||
|
||||
foldername.equals("//share")||foldername.equals("//cache")){
|
||||
// 弹窗参考:https://code.makery.ch/blog/javafx-dialogs-official/
|
||||
Alert alert = new Alert(AlertType.ERROR);
|
||||
alert.setTitle("新建失败");
|
||||
alert.setHeaderText("新建文件夹失败");
|
||||
alert.setContentText("根目录下不允许创建命名为share或cache的文件夹。");
|
||||
alert.showAndWait();
|
||||
return ;
|
||||
}
|
||||
// 请求数据
|
||||
OrderInfo orderInfo = new OrderInfo();
|
||||
ResponseData responseData = new ResponseData();
|
||||
@@ -306,6 +341,16 @@ public class MyCloudFileController {
|
||||
// 删除选中项按钮=>只支持删除普通文件
|
||||
@FXML
|
||||
private void deleteSelectedItem() {
|
||||
//判断是否选择了文件
|
||||
if(fileList.getSelectionModel().getSelectedItem()==null){
|
||||
// 弹窗参考:https://code.makery.ch/blog/javafx-dialogs-official/
|
||||
Alert alert = new Alert(AlertType.WARNING);
|
||||
alert.setTitle("文件未选择");
|
||||
alert.setHeaderText("文件未选择");
|
||||
alert.setContentText("请先在文件列表中选择一个文件。");
|
||||
alert.showAndWait();
|
||||
return;
|
||||
}
|
||||
System.out.println("发送了删除请求到服务器...");
|
||||
// 获取选中的文件
|
||||
Pane pane = fileList.getSelectionModel().getSelectedItem();
|
||||
@@ -356,36 +401,20 @@ public class MyCloudFileController {
|
||||
|
||||
}
|
||||
|
||||
// 下载选中项按钮,下载文件到缺省本地目录[E盘根目录]
|
||||
// @FXML
|
||||
// private void downloadSelectedItem() {
|
||||
// Pane pane=fileList.getSelectionModel().getSelectedItem();
|
||||
// String pathfilename=getPathFileName(pane.getId());
|
||||
// System.out.println("开始下载... :"+pathfilename);
|
||||
// int flag=mainApp.downloadFileByPathfilename(pathfilename);
|
||||
// if(flag==0) {
|
||||
//// 弹窗参考:https://code.makery.ch/blog/javafx-dialogs-official/
|
||||
// Alert alert = new Alert(AlertType.INFORMATION);
|
||||
// alert.setTitle("下载成功");
|
||||
// alert.setHeaderText("下载文件成功");
|
||||
// alert.setContentText("您请求的文件数据已经被全部下载到本地,"
|
||||
// + "如有发现打开异常或数据内容并非所求,说明出现了服务器数据请求问题。"
|
||||
// + "您的文件默认保存位置为:"+mainApp.fileLocalPath);
|
||||
// alert.showAndWait();
|
||||
// }else {
|
||||
//// 弹窗参考:https://code.makery.ch/blog/javafx-dialogs-official/
|
||||
// Alert alert = new Alert(AlertType.ERROR);
|
||||
// alert.setTitle("下载失败");
|
||||
// alert.setHeaderText("下载文件失败");
|
||||
// alert.setContentText("本地文件数据写入失败,请检查是否有权限访问默认存储位置。"
|
||||
// + "您的文件默认保存位置为:"+mainApp.fileLocalPath);
|
||||
// alert.showAndWait();
|
||||
// }
|
||||
// }
|
||||
|
||||
// 下载选中项按钮
|
||||
@FXML
|
||||
private void downloadSelectedItem() {
|
||||
// 判断是否选择了文件
|
||||
if(fileList.getSelectionModel().getSelectedItem()==null){
|
||||
// 弹窗参考:https://code.makery.ch/blog/javafx-dialogs-official/
|
||||
Alert alert = new Alert(AlertType.WARNING);
|
||||
alert.setTitle("文件未选择");
|
||||
alert.setHeaderText("文件未选择");
|
||||
alert.setContentText("请先在文件列表中选择一个文件。");
|
||||
alert.showAndWait();
|
||||
return;
|
||||
}
|
||||
// 选择要下载到的文件夹
|
||||
String localDirString = mainApp.fileLocalPath;
|
||||
DirectoryChooser directoryChooser = new DirectoryChooser();
|
||||
@@ -420,7 +449,7 @@ public class MyCloudFileController {
|
||||
}
|
||||
// 下载文件之后,通过获取服务器的文件大小,与下载到本地的文件大小对比
|
||||
// 判断是否传输成功
|
||||
Integer fileServerLength=mainApp.getServerFileByteLength(pathfilename);
|
||||
Long fileServerLength=mainApp.getServerFileByteLength(pathfilename);
|
||||
System.out.println("fileServerLength: "+fileServerLength);
|
||||
String localfilename=localDirString+getPureFileNameFromLinux(pathfilename);
|
||||
File localfile=new File(localfilename);
|
||||
@@ -450,23 +479,6 @@ public class MyCloudFileController {
|
||||
alert.setContentText("文件数据未能全部写入本地。" + "您的文件保存位置为:" +localDirString);
|
||||
alert.showAndWait();
|
||||
}
|
||||
// int flag = mainApp.downloadFileByPathfilename(pathfilename,localDirString);
|
||||
// if (flag == 0) {
|
||||
//// 弹窗参考:https://code.makery.ch/blog/javafx-dialogs-official/
|
||||
// Alert alert = new Alert(AlertType.INFORMATION);
|
||||
// alert.setTitle("下载成功");
|
||||
// alert.setHeaderText("下载文件成功");
|
||||
// alert.setContentText("您请求的文件数据已经被全部下载到本地," + "如有发现打开异常或数据内容并非所求,说明出现了服务器数据请求问题。" + "您的文件保存位置为:"
|
||||
// + localDirString);
|
||||
// alert.showAndWait();
|
||||
// } else {
|
||||
//// 弹窗参考:https://code.makery.ch/blog/javafx-dialogs-official/
|
||||
// Alert alert = new Alert(AlertType.ERROR);
|
||||
// alert.setTitle("下载失败");
|
||||
// alert.setHeaderText("下载文件失败");
|
||||
// alert.setContentText("本地文件数据写入失败,请检查是否有权限访问文件存储位置。" + "您的文件保存位置为:" +localDirString);
|
||||
// alert.showAndWait();
|
||||
// }
|
||||
}
|
||||
|
||||
// 根据包含路径的文件名获取纯文件名[linux下]
|
||||
@@ -524,9 +536,9 @@ public class MyCloudFileController {
|
||||
return jsonObject.toString();
|
||||
}
|
||||
|
||||
// 列出某目录下的所有文件
|
||||
// 列出某目录下的所有文件【非文件夹】
|
||||
private boolean lsFolder(String foldername) {
|
||||
System.out.println("foldername: " + foldername);
|
||||
System.out.println("罗列foldername下文件: " + foldername);
|
||||
// 请求数据
|
||||
OrderInfo orderInfo = new OrderInfo();
|
||||
ResponseData responseData = new ResponseData();
|
||||
@@ -546,12 +558,15 @@ public class MyCloudFileController {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (codeInteger == 201) {
|
||||
filePathnameList.clear();
|
||||
detailedFileListMap.clear();
|
||||
if (codeInteger == 200) {
|
||||
String dataString;
|
||||
try {
|
||||
dataString = jsonObject.getString("data");
|
||||
if ((dataString.equals("")) || (dataString.equals("null"))) {
|
||||
filePathnameList.clear();
|
||||
detailedFileListMap.clear();
|
||||
return true;
|
||||
}
|
||||
JSONArray dataJsonArray = new JSONArray(dataString);
|
||||
@@ -563,10 +578,23 @@ public class MyCloudFileController {
|
||||
fileCacheJsonObject = new JSONObject(fileCacheString);
|
||||
String filename = fileCacheJsonObject.getString("filename");
|
||||
String type = fileCacheJsonObject.getString("type");
|
||||
if (foldername.charAt(foldername.length() - 1) == '/') {
|
||||
filePathnameList.add(foldername + filename + "@" + type);
|
||||
} else {
|
||||
filePathnameList.add(foldername + '/' + filename + "@" + type);
|
||||
Long time=fileCacheJsonObject.getLong("time");
|
||||
Long size=fileCacheJsonObject.getLong("size");
|
||||
if (foldername.charAt(foldername.length() - 1) != '/'){
|
||||
foldername=foldername+"/";
|
||||
}
|
||||
if(type.equals("f")){
|
||||
// filePathnameList
|
||||
String fileId=foldername + filename + "@" + type;
|
||||
filePathnameList.add(fileId);
|
||||
// map
|
||||
SingleFile singleFile=new SingleFile(fileId);
|
||||
singleFile.setFilepath(foldername);
|
||||
singleFile.setFilename(filename);
|
||||
singleFile.setType(type);
|
||||
singleFile.setSize(size);
|
||||
singleFile.setTime(time);
|
||||
detailedFileListMap.put(fileId,singleFile);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
@@ -575,10 +603,108 @@ public class MyCloudFileController {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}else if(codeInteger==201){
|
||||
System.out.println("lsFolder: 201大数据传输接口");
|
||||
String dataString;
|
||||
try {
|
||||
dataString = jsonObject.getString("data");
|
||||
if (dataString.equals("")) {
|
||||
//数据为空
|
||||
} else {
|
||||
JSONObject dataJsonObject = new JSONObject(dataString);
|
||||
String dataIdString = dataJsonObject.getString("dataId");
|
||||
Integer dataSizeInteger = dataJsonObject.getInt("dataSize");
|
||||
Integer sliceNumInteger = dataJsonObject.getInt("sliceNum");
|
||||
Integer sliceSizeInteger = dataJsonObject.getInt("sliceSize");
|
||||
byte[] noticelistByte = new byte[dataSizeInteger];
|
||||
for (Integer sliceNo = 0; sliceNo < sliceNumInteger; sliceNo++) {
|
||||
// 发送数据请求
|
||||
Long seqLongT = mainApp.getNewDataReqId();
|
||||
orderInfo.setSeq(seqLongT);
|
||||
System.out.println("getDataSlice: " + getGetDataSlice(dataIdString, sliceNo));
|
||||
orderInfo.setJsonString(getGetDataSlice(dataIdString, sliceNo));
|
||||
mainApp.minoaDataAPI.executeOrder("/getDataSlice", orderInfo);
|
||||
// 获取用户列表信息
|
||||
ResponseData responseDataCache = mainApp.minoaDataAPI.dataCacheQueue.getResponseDataBySeq(seqLongT);
|
||||
byte[] byteCache = responseDataCache.getFileSlice();
|
||||
System.out.println("byteCache size:" + byteCache.length);
|
||||
System.out.println("byteCache:" + byteCache);
|
||||
if (sliceNo == (sliceNumInteger - 1)) {
|
||||
for (int x = (sliceNo * sliceSizeInteger); x < dataSizeInteger; x++) {
|
||||
noticelistByte[x] = byteCache[x - (sliceNo * sliceSizeInteger)];
|
||||
}
|
||||
} else {
|
||||
for (int x = (sliceNo * sliceSizeInteger); x < (sliceNo * sliceSizeInteger + 7000); x++) {
|
||||
noticelistByte[x] = byteCache[x - (sliceNo * sliceSizeInteger)];
|
||||
}
|
||||
}
|
||||
}
|
||||
try {
|
||||
String cacheString = new String(noticelistByte, "UTF-8");
|
||||
System.out.println(cacheString);
|
||||
JSONArray dataJsonArray = new JSONArray(cacheString);
|
||||
String fileCacheString;
|
||||
JSONObject fileCacheJsonObject;
|
||||
// 遍历每个文件信息
|
||||
for (int i = 0; i < dataJsonArray.length(); i++) {
|
||||
fileCacheString = dataJsonArray.getString(i);
|
||||
fileCacheJsonObject = new JSONObject(fileCacheString);
|
||||
String filename = fileCacheJsonObject.getString("filename");
|
||||
String type = fileCacheJsonObject.getString("type");
|
||||
Long time=fileCacheJsonObject.getLong("time");
|
||||
Long size=fileCacheJsonObject.getLong("size");
|
||||
if (foldername.charAt(foldername.length() - 1) != '/'){
|
||||
foldername=foldername+"/";
|
||||
}
|
||||
// if(type.equals("f")){
|
||||
// filePathnameList
|
||||
String fileId=foldername + filename + "@" + type;
|
||||
filePathnameList.add(fileId);
|
||||
// map
|
||||
SingleFile singleFile=new SingleFile(fileId);
|
||||
singleFile.setFilepath(foldername);
|
||||
singleFile.setFilename(filename);
|
||||
singleFile.setType(type);
|
||||
singleFile.setSize(size);
|
||||
singleFile.setTime(time);
|
||||
detailedFileListMap.put(fileId,singleFile);
|
||||
// }
|
||||
}
|
||||
return true;
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public String getGetDataSlice(String dataId, Integer sliceNo) {
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
String commandString = "/getDataSlice";
|
||||
String usernameString = mainApp.loginer.getUserName();
|
||||
String uuidString = mainApp.loginer.getUuid();
|
||||
Integer sliceNoInteger = sliceNo;
|
||||
String dataIdString = dataId;
|
||||
try {
|
||||
jsonObject.put("command", commandString);
|
||||
jsonObject.put("username", usernameString);
|
||||
jsonObject.put("uuid", uuidString);
|
||||
jsonObject.put("dataId", dataIdString);
|
||||
jsonObject.put("sliceNo", sliceNoInteger);
|
||||
} catch (Exception e) {
|
||||
// TODO: handle exception
|
||||
System.out.println("exception: " + e.getMessage());
|
||||
}
|
||||
return jsonObject.toString();
|
||||
}
|
||||
|
||||
// 获取上传文件的json格式
|
||||
private String getUploadFile(String filename, Integer offset) {
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
@@ -600,65 +726,6 @@ public class MyCloudFileController {
|
||||
return jsonObject.toString();
|
||||
}
|
||||
|
||||
// //上传文件操作=>此函数只支持上传指定文件到用户根目录
|
||||
// public void sendFileToServer(File file) {
|
||||
// // 获取要上传文件的文件长度,计算上传次数
|
||||
// long filelen = file.length();
|
||||
// int cycle = (int) filelen / mainApp.sliceSize;
|
||||
// System.out.println("file-len: " + filelen);
|
||||
// System.out.println("cycle: " + cycle);
|
||||
// // 发送上传命令给上传接口,接口自行取本地数据
|
||||
// int flagSuccess = 0; // 记录收到200回复的次数
|
||||
// for (int i = 0; i <= cycle; i++) {
|
||||
// OrderInfo orderInfo = new OrderInfo();
|
||||
// ResponseData responseData = new ResponseData();
|
||||
// Long seqLong = mainApp.getNewDataReqId();
|
||||
// orderInfo.setSeq(seqLong);
|
||||
// // 此时传入的文件路径是windows下的绝对路径
|
||||
// orderInfo.setJsonString(getUploadFile(file.getAbsolutePath(), i * mainApp.sliceSize));
|
||||
//
|
||||
// mainApp.minoaDataAPI.executeOrder("/uploadFile", orderInfo);
|
||||
// responseData = mainApp.minoaDataAPI.dataCacheQueue.getResponseDataBySeq(seqLong);
|
||||
//// System.out.println("上传文件的数据回执(200表示成功):"+responseData.getResponseJsonDataString());
|
||||
// JSONObject jsonObject = responseData.praseRequestData();
|
||||
// responseData.printSelf();
|
||||
// // 解析数据
|
||||
// Integer codeInteger = null;
|
||||
// try {
|
||||
// codeInteger = jsonObject.getInt("code");
|
||||
// } catch (JSONException e) {
|
||||
// // TODO Auto-generated catch block
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
// if (codeInteger == 200) {
|
||||
// flagSuccess++;
|
||||
// }
|
||||
// }
|
||||
// // 每个分片都上传成功
|
||||
// if (flagSuccess == (cycle + 1)) {
|
||||
//// 弹窗参考:https://code.makery.ch/blog/javafx-dialogs-official/
|
||||
// Alert alert = new Alert(AlertType.INFORMATION);
|
||||
// alert.setTitle("上传成功");
|
||||
// alert.setHeaderText("上传文件成功");
|
||||
// alert.setContentText("您的文件已上传。");
|
||||
// alert.showAndWait();
|
||||
// // 根据当前路径,重新加载整个界面,来刷新listview
|
||||
// try {
|
||||
// mainApp.reloadCloudFileOverview(currentPath);
|
||||
// } catch (IOException e) {
|
||||
// // TODO Auto-generated catch block
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
// } else {
|
||||
//// 弹窗参考:https://code.makery.ch/blog/javafx-dialogs-official/
|
||||
// Alert alert = new Alert(AlertType.WARNING);
|
||||
// alert.setTitle("上传失败");
|
||||
// alert.setHeaderText("上传文件失败");
|
||||
// alert.setContentText("由于未知原因,您的文件上传失败,非常抱歉。");
|
||||
// alert.showAndWait();
|
||||
// }
|
||||
// }
|
||||
|
||||
// 从paneId中获取文件所在路径
|
||||
public String getPathFromPaneId(String paneId) {
|
||||
// 标记最后一个/的下标
|
||||
@@ -731,146 +798,279 @@ public class MyCloudFileController {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
class FileListItem {
|
||||
// 外部pane
|
||||
private Pane pane;
|
||||
private Integer paneWidth;
|
||||
private Integer paneHeight;
|
||||
// 头像
|
||||
private Button head;
|
||||
private Integer headLength;
|
||||
// 文本区域
|
||||
// public TextArea text;
|
||||
private Text text;
|
||||
// private Integer textWidth;
|
||||
// private Integer textHeight;
|
||||
class FileListItem {
|
||||
// 外部pane
|
||||
private Pane pane;
|
||||
private Integer paneWidth;
|
||||
private Integer paneHeight;
|
||||
// 头像
|
||||
private Button head;
|
||||
private Integer headLength;
|
||||
// 文本区域:文件名
|
||||
private Text text;
|
||||
// 文件大小
|
||||
private Text filesizeText;
|
||||
// 文件创建时间
|
||||
private Text filetimeText;
|
||||
|
||||
// 每个Pane代映射了一个文件[路径+文件名+@文件类型]
|
||||
String pathfilename;
|
||||
// 每个Pane代映射了一个文件[路径+文件名+@文件类型]
|
||||
String pathfilename;
|
||||
|
||||
// 组件位置属性
|
||||
private Integer headXInteger;
|
||||
private Integer headYInteger;
|
||||
private Integer textXInteger;
|
||||
private Integer textYInteger;
|
||||
// 组件位置属性
|
||||
private Integer headXInteger;
|
||||
private Integer headYInteger;
|
||||
private Integer textXInteger;
|
||||
private Integer textYInteger;
|
||||
private Integer fileszTextXInteger;
|
||||
private Integer fileszTextYInteger;
|
||||
private Integer filetimeTextXInteger;
|
||||
private Integer filetimeTextYInteger;
|
||||
|
||||
// 设置联系人头像
|
||||
private void setHeadPortrait(Button button, String filetype) {
|
||||
button.setStyle(
|
||||
String.format("-fx-background-image: url('file:resources/images/myFileIcon/%s.png')", filetype));
|
||||
}
|
||||
// 设置联系人头像
|
||||
private void setHeadPortrait(Button button, String filetype) {
|
||||
button.setStyle(
|
||||
String.format("-fx-background-image: url('file:resources/images/myFileIcon/%s.png')", filetype));
|
||||
}
|
||||
|
||||
// 构造函数
|
||||
public FileListItem(String pathfiletypename) {
|
||||
// 映射数据
|
||||
this.pathfilename = pathfiletypename;
|
||||
// 大小配置
|
||||
paneWidth = 200;
|
||||
paneHeight = 50;
|
||||
headLength = 35;
|
||||
// textWidth = 150;
|
||||
// textHeight = 25;
|
||||
// 位置配置
|
||||
headXInteger = 10;
|
||||
headYInteger = 10;
|
||||
textXInteger = 70;
|
||||
textYInteger = 28;
|
||||
// 构造函数
|
||||
public FileListItem(String pathfiletypename) {
|
||||
// 映射数据
|
||||
this.pathfilename = pathfiletypename;
|
||||
// 大小配置
|
||||
paneWidth = 200;
|
||||
paneHeight = 50;
|
||||
headLength = 35;
|
||||
// 位置配置
|
||||
headXInteger = 10;
|
||||
headYInteger = 10;
|
||||
textXInteger = 70;
|
||||
textYInteger = 28;
|
||||
fileszTextXInteger=textXInteger+150;
|
||||
fileszTextYInteger=textYInteger;
|
||||
filetimeTextXInteger=textXInteger+280;
|
||||
filetimeTextYInteger=textYInteger;
|
||||
|
||||
pane = new Pane();
|
||||
head = new Button();
|
||||
text = new Text();
|
||||
pane = new Pane();
|
||||
head = new Button();
|
||||
text = new Text();
|
||||
filesizeText=new Text();
|
||||
filetimeText=new Text();
|
||||
|
||||
// 最外面的pane的大小
|
||||
pane.setPrefSize(paneWidth, paneHeight);
|
||||
// 最外面的pane的大小
|
||||
pane.setPrefSize(paneWidth, paneHeight);
|
||||
|
||||
// 设置头像和pane的CSS的样式标识
|
||||
head.getStyleClass().add("head");
|
||||
pane.getStyleClass().add("pane");
|
||||
// 设置头像和pane的CSS的样式标识
|
||||
head.getStyleClass().add("head");
|
||||
pane.getStyleClass().add("pane");
|
||||
|
||||
// 设置消息头像和消息文本属性
|
||||
head.setPrefSize(headLength, headLength);
|
||||
// text.setPrefSize(textWidth, textHeight);
|
||||
// text.setWrapText(true);
|
||||
// text.setEditable(false);
|
||||
}
|
||||
// 设置消息头像和消息文本属性
|
||||
head.setPrefSize(headLength, headLength);
|
||||
}
|
||||
|
||||
public FileListItem(String pathfilename, String filetype) {
|
||||
// 映射数据
|
||||
this.pathfilename = pathfilename + "@" + filetype;
|
||||
// 大小配置
|
||||
paneWidth = 200;
|
||||
paneHeight = 50;
|
||||
headLength = 35;
|
||||
// textWidth = 150;
|
||||
// textHeight = 25;
|
||||
// 位置配置
|
||||
headXInteger = 10;
|
||||
headYInteger = 10;
|
||||
textXInteger = 70;
|
||||
textYInteger = 28;
|
||||
|
||||
pane = new Pane();
|
||||
head = new Button();
|
||||
text = new Text();
|
||||
|
||||
// 最外面的pane的大小
|
||||
pane.setPrefSize(paneWidth, paneHeight);
|
||||
|
||||
// 设置头像和pane的CSS的样式标识
|
||||
head.getStyleClass().add("head");
|
||||
pane.getStyleClass().add("pane");
|
||||
|
||||
// 设置消息头像和消息文本属性
|
||||
head.setPrefSize(headLength, headLength);
|
||||
// text.setPrefSize(textWidth, textHeight);
|
||||
// text.setWrapText(true);
|
||||
// text.setEditable(false);
|
||||
}
|
||||
|
||||
// 根据person获取pane
|
||||
public Pane getPaneItem() {
|
||||
String name = this.pathfilename;
|
||||
// 头像位置
|
||||
head.setLayoutY(headYInteger);
|
||||
head.setLayoutX(headXInteger);
|
||||
// text位置
|
||||
text.setLayoutX(textXInteger);
|
||||
text.setLayoutY(textYInteger);
|
||||
// 头像和气泡文本内容
|
||||
text.setText(getPureFilenameFromPaneId(name));
|
||||
// text.setText(name);
|
||||
setHeadPortrait(head, getFileTypeFromPaneId(name));
|
||||
pane.getChildren().add(head);
|
||||
pane.getChildren().add(text);
|
||||
// 设置pane的id
|
||||
pane.setId(name);
|
||||
return pane;
|
||||
}
|
||||
|
||||
// 根据包含路径的文件名获取纯文件名
|
||||
private String getPureFilenameFromPaneId(String paneId) {
|
||||
// 标记最后一个/的下标
|
||||
int indexLeft = -1;
|
||||
// 标记最后一个@的下标
|
||||
int indexRight = -1;
|
||||
for (int i = 0; i < paneId.length(); i++) {
|
||||
if (paneId.charAt(i) == '@') {
|
||||
indexRight = i;
|
||||
} else if (paneId.charAt(i) == '/') {
|
||||
indexLeft = i;
|
||||
// 根据person获取pane
|
||||
public Pane getPaneItem() {
|
||||
String name = this.pathfilename;
|
||||
// 头像位置
|
||||
head.setLayoutY(headYInteger);
|
||||
head.setLayoutX(headXInteger);
|
||||
// text位置
|
||||
text.setLayoutX(textXInteger);
|
||||
text.setLayoutY(textYInteger);
|
||||
filesizeText.setLayoutX(fileszTextXInteger);
|
||||
filesizeText.setLayoutY(fileszTextYInteger);
|
||||
filetimeText.setLayoutX(filetimeTextXInteger);
|
||||
filetimeText.setLayoutY(filetimeTextYInteger);
|
||||
// 头像和气泡文本内容
|
||||
String thisfilename=getPureFilenameFromPaneId(name);
|
||||
if(StringByteLengthUtil.getByteLength(thisfilename)>20){
|
||||
thisfilename=thisfilename.substring(0,10)+" ...";
|
||||
}
|
||||
text.setText(thisfilename);
|
||||
setHeadPortrait(head, getFileTypeFromPaneId(name));
|
||||
// 文件大小
|
||||
Long size=detailedFileListMap.get(name).getSize();
|
||||
filesizeText.setText(FileUtil.sizeToShowSize(size));
|
||||
// 文件创建时间
|
||||
Long time=detailedFileListMap.get(name).getTime();
|
||||
filetimeText.setText(FileUtil.timeToDateString(time));
|
||||
// 文件大小和文件创建时间
|
||||
pane.getChildren().add(head);
|
||||
pane.getChildren().add(text);
|
||||
pane.getChildren().add(filesizeText);
|
||||
pane.getChildren().add(filetimeText);
|
||||
// 设置pane的id
|
||||
pane.setId(name);
|
||||
return pane;
|
||||
}
|
||||
if ((indexLeft == -1) || (indexRight == -1)) {
|
||||
System.out.println("prase paneId error: " + paneId);
|
||||
return "";
|
||||
}
|
||||
return paneId.substring(indexLeft + 1, indexRight);
|
||||
}
|
||||
|
||||
// 从paneId中获取文件类型
|
||||
private String getFileTypeFromPaneId(String paneId) {
|
||||
return paneId.substring(paneId.length() - 1, paneId.length());
|
||||
// 根据包含路径的文件名获取纯文件名
|
||||
private String getPureFilenameFromPaneId(String paneId) {
|
||||
// 标记最后一个/的下标
|
||||
int indexLeft = -1;
|
||||
// 标记最后一个@的下标
|
||||
int indexRight = -1;
|
||||
for (int i = 0; i < paneId.length(); i++) {
|
||||
if (paneId.charAt(i) == '@') {
|
||||
indexRight = i;
|
||||
} else if (paneId.charAt(i) == '/') {
|
||||
indexLeft = i;
|
||||
}
|
||||
}
|
||||
if ((indexLeft == -1) || (indexRight == -1)) {
|
||||
System.out.println("prase paneId error: " + paneId);
|
||||
return "";
|
||||
}
|
||||
return paneId.substring(indexLeft + 1, indexRight);
|
||||
}
|
||||
|
||||
// 从paneId中获取文件类型
|
||||
private String getFileTypeFromPaneId(String paneId) {
|
||||
return paneId.substring(paneId.length() - 1, paneId.length());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//class FileListItem {
|
||||
// // 外部pane
|
||||
// private Pane pane;
|
||||
// private Integer paneWidth;
|
||||
// private Integer paneHeight;
|
||||
// // 头像
|
||||
// private Button head;
|
||||
// private Integer headLength;
|
||||
// // 文本区域
|
||||
//// public TextArea text;
|
||||
// private Text text;
|
||||
//// private Integer textWidth;
|
||||
//// private Integer textHeight;
|
||||
//
|
||||
// // 每个Pane代映射了一个文件[路径+文件名+@文件类型]
|
||||
// String pathfilename;
|
||||
//
|
||||
// // 组件位置属性
|
||||
// private Integer headXInteger;
|
||||
// private Integer headYInteger;
|
||||
// private Integer textXInteger;
|
||||
// private Integer textYInteger;
|
||||
//
|
||||
// // 设置联系人头像
|
||||
// private void setHeadPortrait(Button button, String filetype) {
|
||||
// button.setStyle(
|
||||
// String.format("-fx-background-image: url('file:resources/images/myFileIcon/%s.png')", filetype));
|
||||
// }
|
||||
//
|
||||
// // 构造函数
|
||||
// public FileListItem(String pathfiletypename) {
|
||||
// // 映射数据
|
||||
// this.pathfilename = pathfiletypename;
|
||||
// // 大小配置
|
||||
// paneWidth = 200;
|
||||
// paneHeight = 50;
|
||||
// headLength = 35;
|
||||
//// textWidth = 150;
|
||||
//// textHeight = 25;
|
||||
// // 位置配置
|
||||
// headXInteger = 10;
|
||||
// headYInteger = 10;
|
||||
// textXInteger = 70;
|
||||
// textYInteger = 28;
|
||||
//
|
||||
// pane = new Pane();
|
||||
// head = new Button();
|
||||
// text = new Text();
|
||||
//
|
||||
// // 最外面的pane的大小
|
||||
// pane.setPrefSize(paneWidth, paneHeight);
|
||||
//
|
||||
// // 设置头像和pane的CSS的样式标识
|
||||
// head.getStyleClass().add("head");
|
||||
// pane.getStyleClass().add("pane");
|
||||
//
|
||||
// // 设置消息头像和消息文本属性
|
||||
// head.setPrefSize(headLength, headLength);
|
||||
//// text.setPrefSize(textWidth, textHeight);
|
||||
//// text.setWrapText(true);
|
||||
//// text.setEditable(false);
|
||||
// }
|
||||
//
|
||||
// public FileListItem(String pathfilename, String filetype) {
|
||||
// // 映射数据
|
||||
// this.pathfilename = pathfilename + "@" + filetype;
|
||||
// // 大小配置
|
||||
// paneWidth = 200;
|
||||
// paneHeight = 50;
|
||||
// headLength = 35;
|
||||
//// textWidth = 150;
|
||||
//// textHeight = 25;
|
||||
// // 位置配置
|
||||
// headXInteger = 10;
|
||||
// headYInteger = 10;
|
||||
// textXInteger = 70;
|
||||
// textYInteger = 28;
|
||||
//
|
||||
// pane = new Pane();
|
||||
// head = new Button();
|
||||
// text = new Text();
|
||||
//
|
||||
// // 最外面的pane的大小
|
||||
// pane.setPrefSize(paneWidth, paneHeight);
|
||||
//
|
||||
// // 设置头像和pane的CSS的样式标识
|
||||
// head.getStyleClass().add("head");
|
||||
// pane.getStyleClass().add("pane");
|
||||
//
|
||||
// // 设置消息头像和消息文本属性
|
||||
// head.setPrefSize(headLength, headLength);
|
||||
//// text.setPrefSize(textWidth, textHeight);
|
||||
//// text.setWrapText(true);
|
||||
//// text.setEditable(false);
|
||||
// }
|
||||
//
|
||||
// // 根据person获取pane
|
||||
// public Pane getPaneItem() {
|
||||
// String name = this.pathfilename;
|
||||
// // 头像位置
|
||||
// head.setLayoutY(headYInteger);
|
||||
// head.setLayoutX(headXInteger);
|
||||
// // text位置
|
||||
// text.setLayoutX(textXInteger);
|
||||
// text.setLayoutY(textYInteger);
|
||||
// // 头像和气泡文本内容
|
||||
// text.setText(getPureFilenameFromPaneId(name));
|
||||
//// text.setText(name);
|
||||
// setHeadPortrait(head, getFileTypeFromPaneId(name));
|
||||
// pane.getChildren().add(head);
|
||||
// pane.getChildren().add(text);
|
||||
// // 设置pane的id
|
||||
// pane.setId(name);
|
||||
// return pane;
|
||||
// }
|
||||
//
|
||||
// // 根据包含路径的文件名获取纯文件名
|
||||
// private String getPureFilenameFromPaneId(String paneId) {
|
||||
// // 标记最后一个/的下标
|
||||
// int indexLeft = -1;
|
||||
// // 标记最后一个@的下标
|
||||
// int indexRight = -1;
|
||||
// for (int i = 0; i < paneId.length(); i++) {
|
||||
// if (paneId.charAt(i) == '@') {
|
||||
// indexRight = i;
|
||||
// } else if (paneId.charAt(i) == '/') {
|
||||
// indexLeft = i;
|
||||
// }
|
||||
// }
|
||||
// if ((indexLeft == -1) || (indexRight == -1)) {
|
||||
// System.out.println("prase paneId error: " + paneId);
|
||||
// return "";
|
||||
// }
|
||||
// return paneId.substring(indexLeft + 1, indexRight);
|
||||
// }
|
||||
//
|
||||
// // 从paneId中获取文件类型
|
||||
// private String getFileTypeFromPaneId(String paneId) {
|
||||
// return paneId.substring(paneId.length() - 1, paneId.length());
|
||||
// }
|
||||
//}
|
||||
|
||||
@@ -3,6 +3,7 @@ package cn.minoa.view.mine;
|
||||
import java.io.File;
|
||||
|
||||
import cn.minoa.MainApp;
|
||||
import cn.minoa.dataRequestInterface.DownLoadClientBasedFacePool;
|
||||
import cn.minoa.model.Email;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.scene.control.Alert;
|
||||
@@ -124,8 +125,20 @@ public class SingleEmailDetailsController {
|
||||
}
|
||||
|
||||
System.out.println("开始下载... :"+pathfilename);
|
||||
int flag=mainApp.downloadFileByPathfilename(pathfilename,localDirString);
|
||||
if(flag==0) {
|
||||
// int flag=mainApp.downloadFileByPathfilename(pathfilename,localDirString);
|
||||
Long filelen= mainApp.getServerFileByteLength(pathfilename);
|
||||
Integer sliceNum = (int)(filelen / mainApp.sliceSize);
|
||||
if (filelen % mainApp.sliceSize != 0) {
|
||||
sliceNum++;
|
||||
}
|
||||
Long startTime = System.currentTimeMillis();
|
||||
DownLoadClientBasedFacePool downLoadClient = new DownLoadClientBasedFacePool(pathfilename,
|
||||
localDirString,sliceNum,mainApp.threadNumberForFileTransfer);
|
||||
// 下载文件
|
||||
boolean res = downLoadClient.downloadData();
|
||||
Long endTime = System.currentTimeMillis();
|
||||
System.out.println("耗时:" + (endTime - startTime) + "ms");
|
||||
if(res) {
|
||||
// 弹窗参考:https://code.makery.ch/blog/javafx-dialogs-official/
|
||||
Alert alert = new Alert(AlertType.INFORMATION);
|
||||
alert.setTitle("下载成功");
|
||||
|
||||
@@ -274,8 +274,8 @@ public class WrittenEmailController {
|
||||
String pathfilename=emailFilesList.get(i);
|
||||
//上传该文件到服务器共享文件夹目录下
|
||||
File file=new File(pathfilename);
|
||||
Integer res=mainApp.uploadFileToServerSharedFolder(file);
|
||||
if(res<0){
|
||||
boolean res=mainApp.uploadFileToServerSharedFolder(file);
|
||||
if(!res){
|
||||
flag=false;
|
||||
}
|
||||
//将该文件信息[服务器文件路径地址]写入邮件信息中
|
||||
|
||||