######漏發郵件問題【###終歸是程式碼問題(測試出來的-不是直接可見的邏輯問題!!!try catch finally問題)。先耐心測試自身找原因,廣泛應用的都是成熟技術!
阿新 • • 發佈:2018-12-10
===ssm整合JavaMail:漏發郵件問題【###終歸是程式碼問題(測試出來的-不是直接可見的邏輯問題!!!try catch finally問題)。】
=== ###知識點:【finally保證異常仍然需要執行的程式碼一定會執行!】
===最後程式碼:(只需要看insertUser方法)
/** * 新增使用者 * 手機號、郵箱、備註可空 * 是否刪除、建立時間、修改時間為空,mapper層插入預設值 * 姓名、角色id、登入名、密碼不為空 * 登入名唯一, 登入名存在返回0 * 插入成功返回自增主鍵 * 其他錯誤返回-1 */ @Override public int insertUser(UserDO user, String rePassword, Integer agencyId, Integer advertiserId, HttpServletRequest request) { int userMessageIsAvailable = this.checkUserMessage(user, rePassword); if (userMessageIsAvailable != 1) { return userMessageIsAvailable; } String salt = Long.toString(System.currentTimeMillis()); ByteSource byteSource = ByteSource.Util.bytes(salt); user.setSalt(salt); Object md5Password = new SimpleHash("MD5", user.getPassword(), byteSource, 5); String password = user.getPassword();//設定加密密碼前,取出明文密碼。發郵件 user.setPassword(String.valueOf(md5Password)); int result = userMapper.insertSelective(user);//基本資訊。 if( result>0 ) { new Thread(){ @Override public void run() { //========================》freeMarker建立郵件內容:開始 Configuration configuration = freeMarkerConfigurer.getConfiguration(); //載入模板物件 Template template = null; String fileName = null;//拿出來,finally內部可見。 //建立一個數據集 Map data = new HashMap<>(); MockMultipartFile multipartFile = null; try { template = configuration.getTemplate("mail.ftl"); //data需要的資料分析:圖片絕對路徑。 //String realPath = request.getServletContext().getRealPath(""); String realPath = request.getServletContext().getRealPath("/"); if (!realPath.endsWith(java.io.File.separator)) { //linux下拿到的realPath不帶"\";Windows下帶 realPath = realPath + java.io.File.separator; } System.out.println("===》realPath:"+realPath);//E:\ClickCube\classes\artifacts\ClickCube_front_Web_exploded\ //防止圖片位置變化,每次發郵件,上傳一次mailLogo.png InputStream inputStream = new FileInputStream(realPath+"resource/mailLogo/mailLogo.png");// //不行換個MultipartFile的實現類試試======》 multipartFile = new MockMultipartFile("mailLogo.png", inputStream); fileName = multipartFile.getName(); // add // configuration.clearEncodingMap(); // configuration.clearSharedVariables(); // configuration.clearTemplateCache(); } catch (Exception e) { e.printStackTrace(); }finally { //》》》前面 出現任何異常,只要使用者插入成功,都要發郵件。 //### 【有時漏發郵件 就是沒有寫到finally裡導致的】》沒有執行發郵件方法。。。 String fileId = null; String content = null; String toMail = null; try{ //===》沒連線VPN 會報錯 部分=== 開始 fileId = FastDFSUtil.uploadFile(multipartFile.getBytes(), fileName);//===》沒連線VPN 開始報錯。。。 //獲取伺服器寫在配置檔案中的頭地址 String filePathUrl = ReadPropertiesUtil.readFilePath(); //設定在伺服器上的絕對地址 String logoUrl = filePathUrl + "/" + fileId; System.out.println("=====》logoUrl:" + logoUrl); data.put("logoUrl", logoUrl);//ok data.put("loginName", user.getLoginName()); data.put("password", password);//加密前取出的明文密碼。 content = FreeMarkerTemplateUtils.processTemplateIntoString(template, data); //========================》freeMarker建立郵件內容:結束 toMail = user.getEmail(); //===》沒連線VPN 會報錯 部分=== 結束 }catch (Exception e){ e.printStackTrace(); }finally { //====》沒連線VPN 報錯。保證發郵件也要執行。。。 if(result>0){ //MailUtils.sendMail("註冊郵件", content, toMail);//有些郵箱不能解析HTML。是不是content是String的原因? sendTemplateMail( content,toMail );//設定為html郵件。【使用Spring整合的Mail方式,不用原生JavaMail】 } } } }//run執行緒體 }.start(); }//a==1 插入記錄成功。 return user.getId(); } //傳送模板郵件 public void sendTemplateMail(String htmlText,String toMail) { MimeMessage msg=mailSender.createMimeMessage(); try{ MimeMessageHelper helper=new MimeMessageHelper(msg,false,"utf8");//由於是html郵件,不是mulitpart型別 helper.setFrom("
[email protected]"); helper.setTo(toMail); helper.setSubject("註冊成功-郵件"); helper.setText(htmlText, true);//是html郵件:true }catch (Exception e){ e.printStackTrace(); }finally { mailSender.send(msg);//有異常仍然發郵件。 System.out.println("成功傳送模板郵件"); } }
====之前導致問題的程式碼:
①測試發現:漏發的郵件,沒有執行發郵件程式碼。。。
②問題原因:
【### 只有一個try catch。try中程式碼過多,
#### 前面程式碼出現異常,不能保證:“出現異常,後面仍然需要執行的程式碼(發郵件)” 仍然繼續執行!!!】
/** * 新增使用者 * 手機號、郵箱、備註可空 * 是否刪除、建立時間、修改時間為空,mapper層插入預設值 * 姓名、角色id、登入名、密碼不為空 * 登入名唯一, 登入名存在返回0 * 插入成功返回自增主鍵 * 其他錯誤返回-1 */ @Override public int insertUser(UserDO user, String rePassword, Integer agencyId, Integer advertiserId, HttpServletRequest request) { int userMessageIsAvailable = this.checkUserMessage(user, rePassword); if (userMessageIsAvailable != 1) { return userMessageIsAvailable; } String salt = Long.toString(System.currentTimeMillis()); ByteSource byteSource = ByteSource.Util.bytes(salt); user.setSalt(salt); Object md5Password = new SimpleHash("MD5", user.getPassword(), byteSource, 5); String password = user.getPassword();//設定加密密碼前,取出明文密碼。發郵件 user.setPassword(String.valueOf(md5Password)); int a = userMapper.insertSelective(user);//基本資訊。 if( new Integer(a) !=null ) { new Thread(){ @Override public void run() { //========================》freeMarker建立郵件內容:開始 Configuration configuration = freeMarkerConfigurer.getConfiguration(); //載入模板物件 Template template = null; //建立一個數據集 Map data = new HashMap<>(); try { template = configuration.getTemplate("mail.ftl"); //data需要的資料分析:圖片絕對路徑。 //String realPath = request.getServletContext().getRealPath(""); String realPath = request.getServletContext().getRealPath("/"); if (!realPath.endsWith(java.io.File.separator)) { //linux下拿到的realPath不帶"\";Windows下帶 realPath = realPath + java.io.File.separator; } System.out.println("===》realPath:"+realPath);//E:\ClickCube\classes\artifacts\ClickCube_front_Web_exploded\ //String logoUrl="http://"+localAddr+":"+localPort+contextPath+"/resource/mailLogo/mailLogo.png";//必須加http // logoUrl的IP不對。換個裝置就訪問不到Logot圖片了。IP總是伺服器本機的127.0.0.1 //解決思路: // ①圖片寫到瀏覽器。 // ②拿到正確的伺服器IP【同一臺伺服器。網路變化:伺服器IP變化(所以只能傳送logo附件。本地顯示附件太麻煩)】 // ③logo圖片放到 fastDFS(穩定的檔案伺服器)上,再訪問遠端的圖片。 //防止圖片位置變化,每次發郵件,上傳一次mailLogo.png InputStream inputStream = new FileInputStream(realPath+"resource/mailLogo/mailLogo.png");// //不行換個MultipartFile的實現類試試======》 MockMultipartFile multipartFile = new MockMultipartFile("mailLogo.png", inputStream); // String fileName = multipartFile.getName(); //businessLicenseFileId等4個XXXFileId是要存到資料庫中的絕對ID,或者相對路徑,也是在伺服器中的相對地址 String fileId = FastDFSUtil.uploadFile(multipartFile.getBytes(), fileName); //獲取伺服器寫在配置檔案中的頭地址 String filePathUrl = ReadPropertiesUtil.readFilePath(); //設定在伺服器上的絕對地址 String logoUrl = filePathUrl + "/" + fileId; System.out.println("=====》logoUrl:" + logoUrl); data.put("logoUrl", logoUrl);//ok data.put("loginName", user.getLoginName()); data.put("password", password);//加密前取出的明文密碼。 /* //指定檔案輸出的路徑及檔名 File htmlFile = new File("D:\\freemarker_registerMail\\mail.html"); Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(htmlFile),"UTF-8")); //輸出檔案 template.process(data, out);//ok //關閉流 out.close();*/ String content = FreeMarkerTemplateUtils.processTemplateIntoString(template, data); //========================》freeMarker建立郵件內容:結束 String toMail = user.getEmail(); //MailUtils.sendMail("註冊郵件", content, toMail);//有些郵箱不能解析HTML。是不是content是String的原因? sendTemplateMail( content,toMail );//設定為html郵件。【使用Spring整合的Mail方式,不用原生JavaMail】 } catch (Exception e) { e.printStackTrace(); } }//run執行緒體 }.start(); }//a==1 插入記錄成功。 return user.getId(); }