package cn.minoa.view.login; import java.io.File; import java.io.UnsupportedEncodingException; import java.nio.charset.StandardCharsets; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; 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.model.Person; import cn.minoa.model.SingleMessage; import cn.minoa.model.SingleNotice; import javafx.collections.FXCollections; import javafx.collections.ObservableList; import javafx.fxml.FXML; import javafx.scene.control.Alert; import javafx.scene.control.Alert.AlertType; import javafx.scene.control.PasswordField; import javafx.scene.control.TextField; public class LoginOverviewController { private MainApp mainApp; private OrderInfo orderInfo; public LoginOverviewController() { orderInfo = new OrderInfo(); } @FXML private TextField userNameFiled; @FXML private PasswordField passwordFiled; @FXML private ImageView loginHeadPhoto; @FXML private ImageView miniLogo; @FXML private ImageView settingImage; @FXML private void initialize() { // 在fxml被载入时候被自动调用 miniLogo.setImage(new Image("file:resources/images/logo_mini.png")); settingImage.setImage(new Image("file:resources/images/setting_gear.png")); loginHeadPhoto.setImage(new Image("file:resources/images/ic_launcher-web.png")); } /* * @param mainApp */ public void setMainApp(MainApp mainApp) { this.mainApp = mainApp; } @FXML private void handleSetting() { // 弹出注册界面 mainApp.showSettingOverview(); } @FXML private void handleRegister() { // 弹出注册界面 mainApp.showRegisterOverview(); } @FXML private void handleRegisterByFlip() { // 从登录页翻转到注册界面 mainApp.showRegisterOverviewByFlip(); } @FXML private void handleFindPassword() { // 找回密码 // 。。。 } @FXML 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("用户名或密码错误"); alert.setHeaderText("请核对用户名或密码"); alert.setContentText("请核对用户名或密码。\n" + "如果你故意导入了首字段与用户名相同的密钥证书,但" + "该证书是非法生成的,也将弹出该弹窗!!!"); alert.showAndWait(); } } // 将账号密码保存在本地 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; // 发送数据请求 Long seqLong = mainApp.getNewDataReqId(); orderInfo.setSeq(seqLong); orderInfo.setJsonString(loginJsonString); mainApp.minoaDataAPI.executeOrder("/login", orderInfo); // 根据结果判断是否登录成功 ResponseData responseData = mainApp.minoaDataAPI.dataCacheQueue.getResponseDataBySeq(seqLong); // responseData.printSelf(); JSONObject jsonObject = responseData.praseRequestData(); Integer codeInteger = null; try { codeInteger = jsonObject.getInt("code"); } catch (JSONException e) { // TODO Auto-generated catch block e.printStackTrace(); } if (codeInteger == 200) { System.out.println("login 200"); flag = true; // 初始化Loginer的信息 updateLoginer(jsonObject); System.out.println("ini loginer (include the head photo) success"); // 初始化其它系统信息 iniLoginerData(); // 打印输出 mainApp.loginer.printSelf(); } return flag; } // 初始化登录者的一些系统信息 private void iniLoginerData() { // 初始化联系人列表信息及其头像 updateContactList(); System.out.println("ini contact list (include the head photos) success"); // 初始化与所有联系人的消息记录列表 updateMessageLog(); System.out.println("ini message log success"); // 初始化通知列表 updateNoticeList(); System.out.println("ini notice success"); // 开启[消息列表/通知/审批]的线程循环监听 System.out.println("Creating Thread to Bind News..."); mainApp.creatThreadToRefreshMessageLog(); System.out.println("Created Thread to Bind News."); } // 请求服务器某文件的大小:返回-1表示没有该文件或登录失效 public Long getServerFileLength(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("getServerFileLength-fileInfo-JSON: " + jsonObject.toString()); responseData.printSelf(); 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); Long fileSize= dataJsonObject.getLong("fileSize"); return fileSize; } catch (JSONException e) { // TODO Auto-generated catch block e.printStackTrace(); } } return (long)-1; } public void delTempChild(File file){ if (file.isDirectory()) { String[] children = file.list();//获取文件夹下所有子文件夹 // 递归删除目录中的子目录下 for (int i = 0; i < children.length; i++) { delTempChild(new File(file, children[i])); } } // 目录空了,进行文件删除 file.delete(); } // 删除本地的ndn/pid和ndn/tpm两个文件夹 private void moveNdnKeyFile(){ String dirpath1="./ndn/pid"; String dirpath2="./ndn/tpm"; File f1 = new File(dirpath1); File f2 = new File(dirpath2); delTempChild(f1); delTempChild(f2); } // 导入密钥 @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; } } 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 ; } // 做一个清空本地密钥的动作 // moveNdnKeyFile(); // System.out.println("本地密钥文件已清空"); // 将所选文件导入密钥 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(); } } // 根据包含路径的文件名获取纯文件名[linux下] public String getPureFileName(String pathfilename) { // 标记最后一个/的下标 int indexLeft = -1; for (int i = 0; i < pathfilename.length(); i++) { if (pathfilename.charAt(i) == '/') { indexLeft = i; } } if (indexLeft == -1) { System.out.println("pure name[linux]: " + pathfilename); return pathfilename; } else { System.out.println("pure name[linux]: " + pathfilename.substring(indexLeft + 1, pathfilename.length())); return pathfilename.substring(indexLeft + 1, pathfilename.length()); } } // 获取要下载的文件信息 public String getFileInfoJson(String filename) { JSONObject jsonObject = new JSONObject(); String commandString = "/fileInfo"; String usernameString = mainApp.loginer.getUserName(); String uuidString = mainApp.loginer.getUuid(); String filenameString = filename; try { jsonObject.put("command", commandString); jsonObject.put("username", usernameString); jsonObject.put("uuid", uuidString); jsonObject.put("filename", filenameString); } catch (Exception e) { // TODO: handle exception System.out.println("exception: " + e.getMessage()); } return jsonObject.toString(); } public String getLoginJsonString(String userNameString,String passWordString) { JSONObject jsonObject = new JSONObject(); 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("password", passWordString); } catch (Exception e) { System.out.println("exception: " + e.getMessage()); } return jsonObject.toString(); } // 从前端界面获得登录数据并转换成json格式 private String getLoginJsonString() { JSONObject jsonObject = new JSONObject(); String commandString = "/login"; String userNameString = userNameFiled.getText().trim(); String passWordString = passwordFiled.getText().trim(); // 对密码进行哈希加密 passWordString= EncryptionUtil.getMD5String(passWordString); mainApp.loginer.setUserName(userNameString); mainApp.loginer.setPassWord(passWordString); try { jsonObject.put("command", commandString); jsonObject.put("username", userNameString); jsonObject.put("password", passWordString); } catch (Exception e) { System.out.println("exception: " + e.getMessage()); } return jsonObject.toString(); } // 根据请求到的json数据更新loginer的信息 private void updateLoginer(JSONObject loginerJsonObject) { String dataString; try { dataString = loginerJsonObject.getString("data"); System.out.println("dataString: "+dataString); JSONObject dataJsonObject = new JSONObject(dataString); String uuid = dataJsonObject.getString("uuid"); String realname=dataJsonObject.getString("realName"); String prefix=dataJsonObject.getString("prefix"); String phone=dataJsonObject.getString("phone"); // System.out.println("realname: "+realname); // System.out.println("prefix: "+prefix); mainApp.loginer.setUuid(uuid); mainApp.loginer.setRealName(realname); mainApp.loginer.setPrefix(prefix); mainApp.loginer.setPhone(phone); // 初始化登录者头像 String avatarString = dataJsonObject.getString("avatar"); if (!isHaveHeadPhoto(mainApp.loginer.getUserName() + ".png")) { System.out.println("downloading " + mainApp.loginer.getUserName() + "'s head photo file..."); downloadRenamedFileToSpecifiedDir(avatarString, mainApp.userHeadPhotoBinPath, mainApp.loginer.getUserName() + ".png"); } } catch (JSONException e) { // TODO Auto-generated catch block e.printStackTrace(); } } // 拿到获取用户列表的json格式字符串 private String getGetUsersJson() { JSONObject jsonObject = new JSONObject(); String commandString = "/getUsers"; 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(); } // 初始化联系人列表信息 private void updateContactList() { // 发送数据请求 Long seqLong = mainApp.getNewDataReqId(); orderInfo.setSeq(seqLong); orderInfo.setJsonString(getGetUsersJson()); mainApp.minoaDataAPI.executeOrder("/getUsers", orderInfo); // 获取用户列表信息 ResponseData responseData = mainApp.minoaDataAPI.dataCacheQueue.getResponseDataBySeq(seqLong); JSONObject jsonObject = responseData.praseRequestData(); System.out.println("getUsers-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"); JSONArray dataJsonArray = new JSONArray(dataString); String userCacheString; JSONObject userCacheJsonObject; String userNameCacheString; // System.out.println("data: "+dataString); // 遍历每个用户联系人,将其加入mainApp的联系人列表中 for (int i = 0; i < dataJsonArray.length(); i++) { userCacheString = dataJsonArray.getString(i); userCacheJsonObject = new JSONObject(userCacheString); userNameCacheString = userCacheJsonObject.getString("username"); // System.out.println("user-"+i+": "+userNameCacheString); mainApp.contactListData.add(new Person(userNameCacheString)); // 初始化联系人头像到本地=》目前接口没返回头像路径 String avatarString = userCacheJsonObject.getString("avatar"); if (!isHaveHeadPhoto(userNameCacheString + ".png")) { System.out.println("downloading " + userNameCacheString + "'s head photo file..."); downloadRenamedFileToSpecifiedDir(avatarString, mainApp.userHeadPhotoBinPath, userNameCacheString + ".png"); } } } catch (JSONException e) { // TODO Auto-generated catch block e.printStackTrace(); } }else if(codeInteger==201){ String dataString = null; try { dataString = jsonObject.getString("data"); 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)]; } } } String cacheString = new String(noticelistByte, StandardCharsets.UTF_8); System.out.println(cacheString); JSONArray dataJsonArray = new JSONArray(cacheString); String userCacheString; JSONObject userCacheJsonObject; String userNameCacheString; // System.out.println("data: "+dataString); // 遍历每个用户联系人,将其加入mainApp的联系人列表中 for (int i = 0; i < dataJsonArray.length(); i++) { userCacheString = dataJsonArray.getString(i); userCacheJsonObject = new JSONObject(userCacheString); userNameCacheString = userCacheJsonObject.getString("username"); // System.out.println("user-"+i+": "+userNameCacheString); mainApp.contactListData.add(new Person(userNameCacheString)); // 初始化联系人头像到本地=》目前接口没返回头像路径 String avatarString = userCacheJsonObject.getString("avatar"); if (!isHaveHeadPhoto(userNameCacheString + ".png")) { System.out.println("downloading " + userNameCacheString + "'s head photo file..."); downloadRenamedFileToSpecifiedDir(avatarString, mainApp.userHeadPhotoBinPath, userNameCacheString + ".png"); } } } catch (JSONException e) { e.printStackTrace(); } } } //判断是否已经有本地头像 boolean isHaveHeadPhoto(String headPhotoString) { File file = new File(mainApp.userHeadPhotoBinPath + headPhotoString); if (file.exists()) { System.out.println(headPhotoString + " has existed."); return true; } else { return false; } } // 请求通知消息 private String getGetInformJson() { JSONObject jsonObject = new JSONObject(); String commandString = "/getInform"; String usernameString = mainApp.loginer.getUserName(); String uuidString = mainApp.loginer.getUuid(); Integer pageNoInteger = 0; Integer pageSizeInteger = 100; 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(); } // 请求每个通知的数据分片的JSON 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(); } //重新加载所有通知列表信息 public void reloadNoticeList(){ mainApp.noticeList.clear(); updateNoticeList(); } // 初始化通知列表信息 private void updateNoticeList() { // 发送数据请求 Long seqLong = mainApp.getNewDataReqId(); orderInfo.setSeq(seqLong); orderInfo.setJsonString(getGetInformJson()); mainApp.minoaDataAPI.executeOrder("/getInform", orderInfo); // 获取用户列表信息 ResponseData responseData = mainApp.minoaDataAPI.dataCacheQueue.getResponseDataBySeq(seqLong); System.out.println("通知答复:"); responseData.printSelf(); JSONObject jsonObject = responseData.praseRequestData(); System.out.println("getInform-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"); if (dataString.equals("")) { //数据为空 } else { JSONArray dataJsonArray = new JSONArray(dataString); String singleNoticeCacheString; JSONObject singleNoticeCacheJsonObject; Integer noticeIdInteger; String usernameCacheString; String titleCacheString; String contentCacheString; String starttimeCacheString; String endtimeCacheString; String attachementCacheString; // 遍历每个用户联系人,将其加入mainApp的联系人列表中 for (int i = 0; i < dataJsonArray.length(); i++) { singleNoticeCacheString = dataJsonArray.getString(i); singleNoticeCacheJsonObject = new JSONObject(singleNoticeCacheString); //拿到通知ID noticeIdInteger = singleNoticeCacheJsonObject.getInt("id"); // 拿到新闻发布人 usernameCacheString = singleNoticeCacheJsonObject.getString("proposer"); // 拿到content // JSONObject detailJsonObject = singleNoticeCacheJsonObject.getJSONObject("detail"); String detailString = singleNoticeCacheJsonObject.getString("detail"); System.out.println("通知详细: " + detailString); JSONObject detailJsonObject = new JSONObject(detailString); contentCacheString = detailJsonObject.getString("content"); // 拿到title titleCacheString = detailJsonObject.getString("title"); // 拿到starttime、endtime starttimeCacheString = detailJsonObject.getString("startTime"); endtimeCacheString = detailJsonObject.getString("endTime"); // 拿到attachment attachementCacheString = detailJsonObject.getString("attachment"); // System.out.println("user-"+i+": "+usernameCacheString); // 新建一个notice SingleNotice singleNotice = new SingleNotice(); singleNotice.setNoticeId(noticeIdInteger); singleNotice.setContent(contentCacheString); singleNotice.setUsername(usernameCacheString); singleNotice.setTitle(titleCacheString); singleNotice.setStarttime(starttimeCacheString); singleNotice.setEndtime(endtimeCacheString); singleNotice.setAttachment(attachementCacheString); mainApp.noticeList.add(singleNotice); } } } catch (JSONException e) { // TODO Auto-generated catch block e.printStackTrace(); } } else if (codeInteger == 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 singleNoticeCacheString; JSONObject singleNoticeCacheJsonObject; String usernameCacheString; String titleCacheString; String contentCacheString; String starttimeCacheString; String endtimeCacheString; String attachementCacheString; // 遍历每个用户联系人,将其加入mainApp的联系人列表中 for (int i = 0; i < dataJsonArray.length(); i++) { singleNoticeCacheString = dataJsonArray.getString(i); singleNoticeCacheJsonObject = new JSONObject(singleNoticeCacheString); // 拿到新闻发布人 usernameCacheString = singleNoticeCacheJsonObject.getString("proposer"); // 拿到content String detailString = singleNoticeCacheJsonObject.getString("detail"); JSONObject detailJsonObject = new JSONObject(detailString); contentCacheString = detailJsonObject.getString("content"); // 拿到title titleCacheString = detailJsonObject.getString("title"); // 拿到starttime、endtime starttimeCacheString = detailJsonObject.getString("startTime"); endtimeCacheString = detailJsonObject.getString("endTime"); // 拿到attachment attachementCacheString = detailJsonObject.getString("attachment"); // System.out.println("user-"+i+": "+usernameCacheString); // 新建一个notice SingleNotice singleNotice = new SingleNotice(); singleNotice.setContent(contentCacheString); singleNotice.setUsername(usernameCacheString); singleNotice.setTitle(titleCacheString); singleNotice.setStarttime(starttimeCacheString); singleNotice.setEndtime(endtimeCacheString); singleNotice.setAttachment(attachementCacheString); mainApp.noticeList.add(singleNotice); } } catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } catch (JSONException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } // 初始化与所有联系人的往来消息列表 public void updateMessageLog() { System.out.println("ini message log start..."); // 清空旧的联系人消息清单 mainApp.messageLogMap.clear(); // 获取联系人清单 ObservableList contactList = mainApp.getContactListData(); // 遍历联系人,获取与他们的聊天消息记录 for (Person person : contactList) { // 新建当前用户的消息记录列表 ObservableList messageLogByPersonCacheList = FXCollections.observableArrayList(); mainApp.messageLogMap.put(person.getUserName(), messageLogByPersonCacheList); // 赋值该消息记录列表(当前时间之前的五条消息记录) // fullMessageLogByPerson(person); } // 为了容错"/getNews"轮询到自己发出的消息,这里在消息记录表中增加一个自己 ObservableList messageLogByMyselfList = FXCollections.observableArrayList(); mainApp.messageLogMap.put(mainApp.loginer.getUserName(), messageLogByMyselfList); // 赋值登录时未读消息记录列表(循环请求getNews,并将联系人头像标红) System.out.println("fullIniNotReadMessageListWhenLoginByGetNews-start"); for (int i = 0; i < 1; i++) { // 只请求一次getNews有时候拿不到新消息,这里多发送几次请求。 fullNotReadMessageListByGetNews(); } System.out.println("fullIniNotReadMessageListWhenLoginByGetNews-end"); } // 赋值该消息记录列表(循环请求getNews,并将联系人头像标红) private void fullNotReadMessageListByGetNews() { // 发送数据请求 Long seqLong = mainApp.getNewDataReqId(); OrderInfo orderInfo = new OrderInfo(); orderInfo.setSeq(seqLong); orderInfo.setJsonString(getGetNewsJson()); mainApp.minoaDataAPI.executeOrder("/getNews", orderInfo); // 获取回复消息 ResponseData responseData = mainApp.minoaDataAPI.dataCacheQueue.getResponseDataBySeq(seqLong); // System.out.println("ini-getNews-responseData: "+responseData.getResponseJsonDataString()); JSONObject jsonObject = responseData.praseRequestData(); 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"); if (!dataString.equals("")) { JSONArray dataJsonArray = new JSONArray(dataString); String newsCacheString; JSONObject newsCacheJsonObject; Integer typeCodeInteger; String contentString; // 遍历每个新消息或者通知或者审批,将其更新到前端内存数据中 for (int i = 0; i < dataJsonArray.length(); i++) { newsCacheString = dataJsonArray.getString(i); newsCacheJsonObject = new JSONObject(newsCacheString); typeCodeInteger = newsCacheJsonObject.getInt("typeCode"); contentString = newsCacheJsonObject.getString("content"); if (typeCodeInteger == 0) { // 处理新消息 handleNewSingleMessage(contentString); } else if (typeCodeInteger == 1) { // 处理新通知 } else if (typeCodeInteger == 2) { // 处理新审批 } } } } catch (JSONException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } // 获取是否有新消息产生的json字符串 private String getGetNewsJson() { JSONObject jsonObject = new JSONObject(); String commandString = "/getNews"; 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(); } // 处理一条接收到的新消息 private void handleNewSingleMessage(String singleMessageString) { try { // System.out.println("handleNewSingleMessage start"); JSONObject singleMessageJsonObject = new JSONObject(singleMessageString); String fromString; JSONObject fromJsonObject; String fromNameString; Integer idInteger; String msgString; Long timeLong; // 解析发送方姓名 fromString = singleMessageJsonObject.getString("from"); fromJsonObject = new JSONObject(fromString); fromNameString = fromJsonObject.getString("username"); // 解析id idInteger = singleMessageJsonObject.getInt("id"); // 解析内容 msgString = singleMessageJsonObject.getString("msg"); // 解析时间 timeLong = singleMessageJsonObject.getLong("time"); // 构建一条消息对象 SingleMessage singleMessage = new SingleMessage(); singleMessage.setFromName(fromNameString); singleMessage.setMsg(msgString); singleMessage.setTime(timeLong); singleMessage.setToName(mainApp.loginer.getUserName()); singleMessage.setMsgId(idInteger); // 加入登录未读消息列表中 mainApp.iniNotReadMessageListWhenLogin.addNotReadMessage(singleMessage); ; System.out.println("Login-iniNotReadMessageListWhenLogin addSingleMessage success: " + singleMessageString); } catch (JSONException e) { // TODO Auto-generated catch block e.printStackTrace(); } } // 填充登录者与传入的联系人的消息记录[填充当前时间节点之前的五条消息] private void fullMessageLogByPerson(Person person) { if (person != null) { // 发送请求,更新与该用户的消息记录 Long seqLong = mainApp.getNewDataReqId(); orderInfo.setSeq(seqLong); orderInfo.setJsonString(getGetRTMsgLogJson(person)); mainApp.minoaDataAPI.executeOrder("/getRTMsgLog", orderInfo); // 获取用户列表信息 ResponseData responseData = mainApp.minoaDataAPI.dataCacheQueue.getResponseDataBySeq(seqLong); // System.out.println(responseData.getResponseJsonDataString()); JSONObject jsonObject = responseData.praseLoginData(); // System.out.println("getRTMsgLog-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"); // System.out.println("getRTMsgLog-data: "+dataString); if (dataString.equals("null") || dataString.equals("")) { // 没有消息 } else { JSONArray dataJsonArray = new JSONArray(dataString); String singleMessageCacheString; // 遍历每个用户联系人,将其消息记录加入mainApp的消息列表中【倒序是为了让时间顺序】 for (int i = dataJsonArray.length() - 1; i >= 0; i--) { singleMessageCacheString = dataJsonArray.getString(i); // System.out.println("singleMessage-"+i+": "+singleMessageCacheString); praseAndAddSigleMessage(singleMessageCacheString, person); } } } catch (JSONException 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(); } System.out.println("ini message log with " + person.getUserName() + " success"); } } // 解析单条消息记录并将其加入与特定联系人的消息记录里 private void praseAndAddSigleMessage(String singleMessageString, Person person) { try { JSONObject singleMessageJsonObject = new JSONObject(singleMessageString); // formName String fromString = singleMessageJsonObject.getString("from"); JSONObject fromJsonObject = new JSONObject(fromString); String fromNameString = fromJsonObject.getString("username"); // toName String toString = singleMessageJsonObject.getString("to"); JSONObject toJsonObject = new JSONObject(toString); String toNameString = toJsonObject.getString("username"); // time Long timeLong = singleMessageJsonObject.getLong("time"); // msg String msgString = singleMessageJsonObject.getString("msg"); // id Integer idInteger = singleMessageJsonObject.getInt("id"); // 构造类 SingleMessage singleMessage = new SingleMessage(); singleMessage.setFromName(fromNameString); singleMessage.setToName(toNameString); singleMessage.setTime(timeLong); singleMessage.setMsg(msgString); singleMessage.setMsgId(idInteger); // 加入列表 mainApp.messageLogMap.get(person.getUserName()).add(singleMessage); // System.out.println(person.getUserName()+"的消息记录数目是:"+mainApp.messageLogMap.get(person.getUserName()).size()); } catch (JSONException e) { // TODO Auto-generated catch block e.printStackTrace(); } } // 获取精确到秒的时间戳 private static Long getSecondTimestampTwo(Date date) { if (null == date) { return (long) 0; } String timestamp = String.valueOf(date.getTime() / 1000); return Long.valueOf(timestamp); } // 创建一个代表2019年9月1号的时间戳【精确到秒】 public static Long get20190901() throws ParseException { SimpleDateFormat dataFormat = new SimpleDateFormat("yyyy-MM-dd"); Date testData = dataFormat.parse("2019-09-01"); return getSecondTimestampTwo(testData); } // 创建一个当前时间的时间戳【精确到秒】 public static Long getNowTimeStamp() { Date date = new Date(); return getSecondTimestampTwo(date); } // "获取当前时间节点之前与该选中人的5条互发消息"[数据库给的数据是按照时间倒序的] 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; timestampLong = getNowTimeStamp(); // 期望获取的信息条数 Integer limitInteger = 5; // 0表示时间节点之后,1表示之前 Integer directInteger = 1; 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(); } /* * @param filename 要下载的文件的“服务器路径+文件名称”,即写入请求的名称 * * @param localDir 要下载文件到的本地地址 * * @param localName 要下载的文件重命名之后的本地名称 * * @return 0表示已经成功接收所有回执数据并写入本地文件,否则出现error * * 目的是下载头像到指定路径,并重命名之。 */ 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++; } Long startTime = System.currentTimeMillis(); DownLoadClientBPRenewal downLoadClient = new DownLoadClientBPRenewal(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{ 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("要重命名的文件不存在"); } } }