//////////////////////////// 注意: 此博客是個人工作筆記 非獨立demo//////////////////////////////////
........................................................................................................................................................................................................................
業務介紹:
最近搞的新系統有一個傳單發放的功能,因為要趕著新系統先上線使用,所以老大說先使用老系統的代碼,就是先寫個接口調用支撐一下 下面是新系統調用老系統接口的方法
URL json(gson) html(jsoup)文件 及 IO流的使用
下面首先是http遠程調用的方法 先稱之為工具類
1 public String postTelentService(String urlStr,String urlParameter) throws IOException{ 2 //java.net.URL 主要用於基於Internet的網絡通信編程 3 URL url = new URL(urlStr);//URL的構造方法 4 //參數是值 請求的URL連接的地址(就是url) 字符串類型的 5 HttpURLConnection urlcon = (HttpURLConnection)url.openConnection();//打開這個url連接 此方法聲明拋出IO異常 返回值是URLConnection類型的 連接對象 6 //我們強制轉型為他的一個實現類:HttpURLConnection 7 urlcon.setDoOutput(true);//設置是否向connection輸出 8 //因為我們是個post類型的請求 參數要放在http正文當中,所以我們要設置成true 9 urlcon.setDoInput(true);// read from the connection.Defult is true 10 urlcon.setRequestMethod("POST");//設置http請求的方法 默認是GET方式 11 12 urlcon.setUseCaches(false);//POST請求不能使用緩存 13 urlcon.setInstanceFollowRedirects(true);//前者設置所有的http連接是否自動處理重定向 14 15 16 urlcon.setRequestProperty("Content-Type","application/x-www-form-urlencoded");//配置本次連接的Content-type,配置為application/x-www-form-urlencoded的意思是 正文是urlencoded編碼過的form參數 下面我們可以看到我們對正文內容使用URLEncoder.encode 進行編碼 17 /*google大神解釋: 18 * 這個是告訴服務器 你的客戶端的配置/需求 19 比如說你要取某個文件的多少字節到多少字節就通過這個東西告訴服務器 20 你的客戶端支持壓縮,也可以告訴服務器 服務器會壓縮傳輸 21 你的客戶端支持什麼編碼 也可以告訴服務器 服務器會盡量按照你的編碼傳遞數據 22 還有比如你的客戶端是什麼類型,IE,FIrefox之類,有的服務器會按照你的客戶端類型給你傳送文本 23 你啥都不告訴 服務器就按缺省配置傳遞內容給你的客戶端 24 */ 25 /** 還有注意點: 26 * 1 連接,從openConnection()至此的相關配置設定 必須在connect()之前完成! 27 * 2 connection.getOutputStream會隱含的進行connect()方法 28 */ 29 urlcon.connect();//配置完後 (規定好格式的傳輸對象? 打開對象的連接?) 30 31 DataOutputStream out = new DataOutputStream(urlcon.getOutputStream());//獲取 當前連接對象的輸出流 然後包裝成數據流 32 33 String content = urlParameter;//post方法的http請求正文起始跟 url中?後的參數字符串一致 34 out.writeBytes(content);//byte=8bit 以bate的形式講內容寫到向外的流內 35 out.flush();//強行刷入內存 36 out.close();//關閉輸出流 37 38 InputStream is = urlcon.getInputStream();//為了獲取結果的 輸入流 原始流 39 BufferedReader buffer = new BufferedReader(new InputStreamReader(is));//包裝成字符輸出流 再轉換成字節輸出流 40 StringBuffer bs = new StringBuffer(); 41 String l = null; 42 while((l=buffer.readLine())!=null){ //讀取一行 如果不為空則 in √ 43 bs.append(l).append("/n");//換行 44 } 45 String str1 = bs.toString();// 將Stringbuffer轉換成字符串 46 str1 = new String(str1.getBytes("GBK"),"UTF-8");//gbk轉成utf-8 47 String str2 = str1.subString(0,str1.length()-2);//獲取字符串 截取後面最後一位 48 return str2; 49 }
好了 方法封裝完畢 io流有些日子沒寫過 生疏了不少 下面是調用方法的時候的代碼 簡單的寫寫
1 String assUserIds = RequestUtil.getStringParam(request, "assUserIds"); 2 String urlStr="http://"+ Config.getMkpUrl()+"/marketa/remotePassFlyers.do"; // 調用其他系統的方法 基於http調用 路徑配置 3 // urlStr+="?userId="+userId+"&maId="+maId+"&flyerId="+flyerId+"&userIds="+userIds+"&assUserIds="+assUserIds; 4 String urlParameter="userId="+userId+"&maId="+maId+"&flyerId="+flyerId+"&userIds="+userIds+"&assUserIds="+assUserIds; 5 // userId=8665&maId=1015&flyerId=38273&userIds=8665,8687,8688 6 String result = null; 7 inviteAllUsers(request); 8 try { 9 result = this.postTelentService(urlStr,urlParameter);//路徑和參數傳遞 請求 10 } catch (IOException e) { 11 e.printStackTrace(); 12 }
//---------------------------------------------------------------------------------------------------------------------------------------------------------
好了新系統的 調用方法撰寫完畢
//=============================================================================================//
新系統用的springMVC spring MyBatis
老系統相信通過那個url路徑就能看出以前用的是struts
又因為老系統已經上線了幾年了 老員工告訴我盡量不要動他們寫好的代碼 直接調用或者自己重寫一個 到時候更新.class文件就行了
//============================================================================================//
分析業務邏輯 及 需求分析
涉及到兩個表 第一個表 d_flyer是傳單對應表 裡面存放的有 傳單的id 復制的誰的模板 更新時間 所屬人和活動 等等
d_flyer_detail 裡面存放了 對應的個人內容==
老系統傳單模塊分析: 首先由 主管 創建一個活動 然後為此活動創建一個相應的推廣的傳單
傳單: 一個靜態的html文件 裡面有需要展示的內容 :
1 名片 ./
-------------------------------------
2 反饋表 用於采集有意向的用戶的信息
當 主管 創建完成後 傳單的名片(如果此電子傳單有名片)內部是主管的相關的信息 然後 主管 邀請 組織內部人員參加此活動 並為人員下發此傳單 因為主管點擊邀請後 被邀請人需要登錄賬號 進入軟件後接受邀請 然後主管才能給其發送傳單 而且這樣太繁瑣
因為下發傳單也涉及到了傳單的復制(即 主管傳單的靜態html文件要復制一份給當前的用戶) 他復制的地址一直是在老系統中 所以說只能讓老系統提供給新系統一個調用接口 來進行調用
新系統對應需求是: 勾選相應的人員 給他們發送傳單 跳過了邀請接受的繁瑣
即:批量發送功能
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
由url的http請求內容(即參數)我們看出 調用老系統的參數有:
"userId=" userId //當前賬號的id
"&maId=" maId //當前活動的id
"&flyerId=" flyerId //當前活動綁定傳單的id
"&userIds=" userIds //被邀請人的id s 多個
"&assUserIds=" assUserIds //其他被邀請人的id s
//
//下面是老系統寫的接口:
//剛才已經說了 老系統是拿struts spring 和JdbcTemplate寫的
//本人並不知道jdbcTemplate的原理 但是感覺應該就是一個數據庫框架 沒有時間研究它了 同事也說已經過時很久了 不是主流了 只能先放著
//其他的不說了 struts是action了 接口如下:
1 public class Action{ 2 /** 3 * 這個方法是給另一個系統調用的 4 * 傳遞過來的參數分析: 業務分析: 5 * 1 userId 當前登錄的用戶的id 有一個單獨的人(主管)專門做傳單 傳單完成後進行下發 6 * 所以說他就是在做傳單的模板 7 * 2 maId 指的是當前活動的id 下發傳單實際上是對現有(某個活動某個用戶)模板傳單進行復制 8 * 在表d_flyer中 9 * 進行了賦值 穿但是的user_id字段賦以接受傳單人的id 10 * 3 flyerId 指的是傳單id 它現在寫的應該是錯誤的(但是有個邏輯就是 一個活動只有一個原本的傳單模板) 11 * 4 userIds 指的是下發到的目標用戶 本來是個數組 後來傳過來的時候是用了 toString()方法 12 * 5 assUserIds 已經廢棄 13 * 遠程下發傳單 14 * @return 15 */ 16 public String remotePassFlyers(){ 17 //遠程調用的參數示例為: userId=8665&maId=1015&flyerId=38273&userIds=8665,8687,8688&assUserIds= 18 System.out.println("This is in:Action.remotePassFlyers() ; \n " + 19 "---wunian7yulian testing...-----The var is: null , And The value is: " + "--flag1--" + " \t ---------"); 20 Integer userId = Integer.parseInt(this.getRequest().getParameter("userId")); 21 Integer maId = Integer.parseInt(this.getRequest().getParameter("maId")); 22 Integer flyerId = Integer.parseInt(this.getRequest().getParameter("flyerId")); 23 24 String userIds = this.getRequest().getParameter("userIds"); 25 String assUserIds = this.getRequest().getParameter("assUserIds"); 26 27 if(isBlank(maId) || isBlank(flyerId)){ //如果沒有活動參數或者傳單參數 28 return "ERROR INPUT PARAM"; 29 } 30 //................................................主要方法....................... 31 this.getMarketaService().passFlyerToUsers(userId, maId, flyerId, userIds, assUserIds);//spring注入的service層實例對象 32 return SUCCESS; 33 // return maId+";"+flyerId+";"+userIds+";"+assUserIds; 34 } 35 36 private boolean isBlank(Integer i){ 37 boolean flag = true; 38 if(null!=i && 0!=i){ 39 flag = false; 40 } 41 return flag; 42 } 43 } 44 //=======================================================================================================
下面是service層的代碼 有詳細清楚的的注釋:
1 //==============================================================service層===================================================================== 2 public class MarketaService extends BaseService{ 3 /** 4 * =====================================遠程action層調用此方法發送傳單================================================================== 5 */ 6 ///遠程調用的參數為: userId=8665&maId=1015&flyerId=38273&userIds=8665,8687,8688&assUserIds= 7 /** 服務層對接控制層 調用數據層 8 * 對接 action中的 遠程下發傳單 方法 remotePassFlyers () 9 * 下發活動傳單 10 * @param userId 當前用戶的id 11 * @param maId 當前活動的id 12 * @param flyerId 傳單的id 13 * @param userIds 目標用戶的id 14 * @param assUserIds --null 15 * @return ProcResult --> 專門用於存放(封裝)返回值的工具bean類 16 */ 17 public ProcResult passFlyerToUsers(Integer userId, Integer maId, Integer flyerId, String userIds, String assUserIds){ 18 /**輔助方法清單 方法一*/ 19 List<Map<String, Object>> users = getInvitedUserInfos(maId, flyerId, userIds, assUserIds);//獲取用戶的信息對應傳單id 沒有傳單id的為null 就是指沒有收到過傳單 20 //裡面都有 --- 用戶id 和創建用戶組織的id 和 傳單id 21 if(null != users && !users.isEmpty()){//非空才進去 (只要userIds有值就行) 22 //聲明兩個list集合 分別用於存放: 23 List<Integer> hasSharedList = new ArrayList<Integer>();//已經被分享了的成員 24 List<Integer> notSharedList = new ArrayList<Integer>();//還沒有被分享的成員 id的集合 25 26 for(int i=0; i<users.size(); i++){ 27 Map<String, Object> user = users.get(i); //每個用戶遍歷出來 取出來的個體對象都是一個map 28 //map的entity是[列名:值]的方式 29 // String : Object 30 //例{"user_id":8875,"id":9999} 31 Integer inviteUserId = Integer.parseInt(user.get("user_id").toString()) ;//用戶的id 32 boolean isShared = user.get("id")!=null;// 傳單id 傳單id不為空則說明已經有了 就是已經復制了模板 33 if(isShared){ //已經分享了的 用戶id ~s 34 hasSharedList.add(inviteUserId); 35 } else { //還沒有傳單的 用戶的id ~s 36 notSharedList.add(inviteUserId);//沒有分享的用戶的id 37 } 38 } 39 System.out.println("This is in:com.chanjet.mkp.marketa.MarketaService.passFlyerToUsers() ; \n " + 40 "---wunian testing...-----The var is: 已經分享的:沒有分享的 , And The value is: " + hasSharedList.size() +"//"+ notSharedList.size() + " \t ---------"); 41 //上面是對 已派發過的和未派發過的進行了 !!!分類!!! 整理到了兩個list裡面 42 /* ***************************************************************華麗麗的分割線***************************************************/ 43 /* ***************************************************************華麗麗的分割線***************************************************/ 44 /* ***************************************************************華麗麗的分割線***************************************************/ 45 46 //對所有已經派發過的批量修改 47 if(!hasSharedList.isEmpty()){//已經派發的 hasSharedList 數組裡面保存的是 已經有的傳單的user_id ~s 48 /**輔助方法清單:方法二*/ 49 List<Map<String, Object>> sharedFlyers = getSharedFlyerDetaiInfo(maId, flyerId);// 所有在活動下父傳單為模板傳單的 子傳單的詳細信息 詢已經共享的傳單的user_id 50 Integer[] sharedFlyerArray = new Integer[sharedFlyers.size()];//查看一共有多少個已經派送了的傳單 以多少作為長度 聲明一個Integer類型的數組 51 for(int i=0; i<sharedFlyers.size(); i++){ //循環遍歷出相關的子傳單的詳細信息來 52 Map<String, Object> flyer = sharedFlyers.get(i); 53 Integer sFlyerId = (Integer) flyer.get("flyer_id");//傳單的id 54 sharedFlyerArray[i] = sFlyerId;//這樣把現有的傳單的id 放在一個數組裡面 叫做sharedFlyerArray 55 } 56 /**輔助方法清單:方法三*/ 57 String sharedUserIds = castArrayToString(hasSharedList.toArray());//把已經分享的用戶(list集合)弄出來 轉換成數組 變成字符串 被分享的用戶的id ~s 58 String sharedFlyerIds = castArrayToString(sharedFlyerArray); // 把現有的傳單的id的數組轉換成一個字符串 59 // 對應的傳單的id ~s 60 61 /**輔助方法清單:方法四*/ 62 String updateFlyerSql = getPassFlyerSql(1).replace("{user_ids}", sharedUserIds); //肯定是sql的in用 63 //更新了 已經被分享的用戶的id的所有需要更新的相關信息的sql語句 64 // 65 String updateDlyerDetailSql = getPassFlyerSql(3).replace("{flyer_ids}", sharedFlyerIds);// same 66 //更新 已經被分享用戶的傳單的 詳細表(子表)的相關詳細信息的sql語句 67 68 Object[] flyerParam = new Object[]{flyerId, maId, flyerId}; 69 Object[] flyerDetailParam = new Object[]{flyerId}; 70 this.getDao().update(updateFlyerSql, flyerParam);//更新 d_flyer表 71 this.getDao().update(updateDlyerDetailSql, flyerDetailParam); // 更新了他的子表 72 } 73 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 74 //對所有未發送過的批量添加 沒有什麼傳單的 75 if(!notSharedList.isEmpty()){ // 沒有發送過的 就是d_flyer 所屬人 缺少穿過來的那些 的 76 /**輔助方法清單:方法三*/ 77 String notSharedUserIds = castArrayToString(notSharedList.toArray()); 78 /**輔助方法清單:方法四*/ 79 String addFlyerSql = getPassFlyerSql(5);// 多行插入 d_flyer 語句(復制傳單語句) 80 addFlyerSql = addFlyerSql.replace("{parent_id}",flyerId+"").replace("{user_ids}", notSharedUserIds); 81 //填充數據 批量復制傳單語句 最後一個parent_id字段要寫上模板(父傳單的id值 )的id值 82 Object[] addFlyerParams = new Object[]{flyerId,userId}; 83 this.getDao().update(addFlyerSql, addFlyerParams); 84 /**輔助方法清單:方法四*/ 85 List<Map<String, Object>> newAddFlyerList = getSharedFlyerInfoByUserIds(maId, flyerId, castArrayToString(notSharedList.toArray()));//查詢出剛剛分發出的傳單的 86 Object[] newAddFlyerIds = new Object[newAddFlyerList.size()]; //新增加的傳單個數 聲明一個數組 87 for(int i=0; i<newAddFlyerList.size(); i++){ // 88 Map<String, Object> newF = newAddFlyerList.get(i); 89 newAddFlyerIds[i] = newF.get("flyer_id"); //新傳單的id存放到數組裡面 獲得傳單id 並放到數組中 90 } 91 /**輔助方法清單:方法三*/ 92 String newAddFIds = castArrayToString(newAddFlyerIds); //數組轉換成字符串 去掉了空格 93 /**輔助方法清單:方法四*/ 94 String addFlyerDetailSql = getPassFlyerSql(4).replace("{flyer_ids}", newAddFIds);// 插入對應的子表的數據 95 Object[] addFlyerDetailParams = new Object[]{flyerId}; 96 this.getDao().update(addFlyerDetailSql, addFlyerDetailParams);//因為關聯到了子表 97 } 98 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~相對應的數據庫的所有表的查詢 更新操作結束!!!~~~~~~~~~~~ 99 //獲取 所有屬於此活動的 父傳單id為flyerId的 所有復制版本員工傳單 100 // 返回數據字段有: 101 // 用戶的id 傳單id 用戶對應組織id 傳單詳細信息表的內容 發布後的內容 102 // 郵箱 電話 qq 微信 名稱 職位 103 /**輔助方法清單:方法二*/ 104 List<Map<String, Object>> allSharedFlyers = getSharedFlyerDetaiInfo(maId, flyerId);//插入完成後再次重新獲取所有相關的傳單 105 //重新上傳html文件 106 try { 107 /**輔助方法清單:方法六*/ 108 refreshNameCard(allSharedFlyers); //更新傳單名片信息(數據庫中的content字段的更新) 109 //重新生成靜態html頁面 110 Integer orgId=0; 111 /**輔助方法清單:方法十一 */ 112 uploadShareFlyerHtmlFile(maId, flyerId, userId, orgId, allSharedFlyers); 113 } catch (Exception e) { 114 e.printStackTrace(); 115 } 116 } 117 return ProcResult.success(); 118 } 119 120 /** 121 * =====================================輔助方法清單:方法一================================================================== 122 * 返回值為 此活動 模板傳單是相應傳單模板的 未刪除 的且user_id 在參數裡面的所有滿足條件的 用戶id 傳單id 123 * 即 在此活動被邀請 且有傳單的所有人 124 * 傳入的userIds作為了左表!!!!! (9876有無對應的fid都會有一條對應 生成 9876 null) 125 */ 126 private List<Map<String, Object>> getInvitedUserInfos(Integer maId, Integer flyerId, String userIds, String assUserIds){ 127 String sql = "select " + 128 " u.user_id as user_id,f.id as id " + //用戶id 和創建用戶組織的id 和 傳單id 129 " from m_user u " + 130 " left join d_flyer f " + 131 " on u.user_id = f.user_id " + 132 " and f.ma_id=? " + // 所屬活動限定 133 " and f.parent_id=? " + //這填充的是 傳單模板(父傳單)的id值 這樣就又是一個小型的無線分類 知道了模板的來源 134 " and f.deleted = 0" + // 刪除 ? 否限定 135 " where (u.user_id in ({userIds}) ) and del = 0 ";// 用戶限定 穿過來的用戶 136 /** 137 * select u.user_id as user_id,f.id as id 138 * from m_user u 139 * left join d_flyer f on u.user_id = f.user_id And f.ma_id =? and parent_id=? and f.deleted =0 140 * where (u.user_id in ({userIds}) ) and del =0; 141 由此看出是preparedstatement in 為什麼用替換? 我試了一下用? 出錯了 142 */ 143 sql = sql.replace("{userIds}",userIds);//參數填充 144 Object[] params = new Object[]{maId, flyerId}; //准備參數 145 System.out.println(sql + "=========>"); 146 System.out.println( 147 "==========\n"+"maId:"+maId +"\n flyerId:"+flyerId +"\n userIds:" + userIds); 148 List<Map<String, Object>> list = this.getDao().query(sql, params, null);// 149 System.out.println("查詢列表長度為: "+ list.size() +"==="+list+ " \t ---------"); 150 return list; 151 } 152 //================================================================================================== 153 154 /** 155 * =====================================輔助方法清單:方法二================================================================== 156 */ 157 private List<Map<String, Object>> getSharedFlyerDetaiInfo(Integer maId, Integer parentFlyerId){ 158 List<Map<String, Object>> list = null; 159 String sql = "SELECT t.user_id, t.id AS flyer_id, t.orgid, d.content, d.updated_content," + 160 " m.email, m.mobile, m.phone, m.qq, m.weixin, m.user_name as realname ,mou.position AS job " + 161 " FROM d_flyer t" + 162 " left join d_flyer_detail d on t.id=d.flyer_id" + 163 " left join m_user m on t.user_id = m.user_id"+ 164 " left join m_org_user mou on mou.user_id = m.user_id and mou.dept_id !=0" + 165 " WHERE t.parent_id = ? AND t.ma_id = ? AND t.deleted = 0"; 166 /* 167 SELECT ? FROM d_flyer t 168 left join d_flyer_detail d on t.id=d.flyer_id 169 left join m_user m on t.user_id = m.user_id 170 left join m_org_user mou on mou.user_id = m.user_id and mou.dept_id !=0 171 WHERE t.parent_id = ? AND t.ma_id = ? AND t.deleted = 0 172 */ 173 list = this.getDao().query(sql, new Object[]{parentFlyerId, maId}, null); 174 return list; 175 } 176 /** 177 * =====================================輔助方法清單:方法三================================================================== 178 */ 179 /** 180 * 把數組拼接成以","隔開的字符串 181 * @param array 182 * @return 183 */ 184 private String castArrayToString(Object[] array){ 185 String str = ""; 186 if(null==array){ 187 return str; 188 } 189 switch (array.length){ 190 case 1: 191 str = array[0].toString(); 192 break; 193 default: 194 for(int i=0; i<array.length; i++){ 195 if(i==array.length-1){ 196 str += array[array.length-1].toString(); 197 break; 198 } 199 str += array[i].toString() + ","; 200 } 201 } 202 return str; 203 } 204 205 /** 206 * =====================================輔助方法清單:方法四================================================================== 207 */ 208 private String getPassFlyerSql(Integer type){ 209 String sql = ""; 210 switch (type) { 211 case 1: // updateFlyer 212 sql = "UPDATE d_flyer t1, d_flyer t2 SET t1.title = t2.title," + 213 " t1.status = t2.status," + 214 " t1.create_time = NOW()," + 215 " t1.notice = t2.notice," + 216 " t1.template = t2.template," + 217 " t1.update_time = NOW()," + 218 " t1.description = t2.description," + 219 " t1.beau_sel = t2.beau_sel, " + 220 " t1.refer_count = t2.refer_count," + 221 " t1.refer_id = t2.refer_id," + 222 " t1.isdraw = t2.isdraw," + 223 " t1.iscopy = t2.iscopy," + 224 " t1.is_marketa_enjoy = 0," + 225 " t1.showTitle = t2.showTitle," + 226 " t1.searchKeyword = t2.searchKeyword," + 227 " t1.music = t2.music," + 228 " t1.classify_id = t2.classify_id," + 229 " t1.template_status = t2.template_status," + 230 " t1.option_id = t2.option_id," + 231 " t1.approvedBy = t2.approvedBy," + 232 " t1.deleteReason = t2.deleteReason" + 233 " WHERE t1.user_id IN ({user_ids}) AND t1.parent_id= ? AND t1.ma_id= ? AND t2.id=?"; 234 break; 235 case 2:// insertFlyer 236 sql = "INSERT INTO d_flyer(title,status,create_time,notice,template,user_id,update_time,description,deleted,orgid,hit,notice_days,visitor_count,feedback_count,ishot,version,is_edit,is_add,beau_sel,ma_id,isorg,refer_count,refer_id,isdraw,iscopy,is_marketa_enjoy,showTitle,searchKeyword,music,classify_id,template_status,option_id,approvedBy,deleteReason,parent_id)" + 237 " SELECT t1.title,t1.status,NOW(),t1.notice,t1.template,t2.invite_user_id,NOW(),t1.description,0,t2.adscription_org,0,t1.notice_days,0,0,t1.ishot,2.00,t1.is_edit,t1.is_add,t1.beau_sel,t1.ma_id,t1.isorg,t1.refer_count,t1.refer_id,t1.isdraw,t1.iscopy,0,t1.showTitle,t1.searchKeyword,t1.music,t1.classify_id,t1.template_status,t1.option_id,t1.approvedBy,t1.deleteReason,{parent_id}" + 238 " FROM d_flyer t1," + 239 " (SELECT m.invite_user_id,m.adscription_org FROM m_market_invite_user m WHERE m.invite_user_id IN ({user_ids}) AND m.ma_id=?" + 240 " {add_admin_user}) t2 " + 241 " WHERE t1.id=? AND t1.ma_id=? AND t1.deleted=0 AND t1.user_id=?"; 242 break; 243 case 3:// updateFlyerDetail 244 sql = "UPDATE d_flyer_detail t1,d_flyer_detail t2" + 245 " SET t1.content = t2.content," + 246 " t1.updated_content = t2.updated_content," + 247 " t1.dsc=t2.dsc" + 248 " WHERE t1.flyer_id IN({flyer_ids}) AND t2.flyer_id = ?"; 249 break; 250 case 4:// insertFlyerDetail 251 sql = "INSERT INTO d_flyer_detail(flyer_id, content, updated_content, dsc) " + 252 " SELECT t2.id, t1.content, t1.updated_content, t1.dsc " + 253 " FROM d_flyer_detail t1,(SELECT id ,user_id FROM d_flyer WHERE id IN({flyer_ids})) t2" + 254 " WHERE t1.flyer_id=?"; 255 break; 256 case 5: 257 sql =" INSERT INTO d_flyer(title,status,create_time,notice,template,user_id,update_time,description,deleted,orgid,hit,notice_days,visitor_count,feedback_count,ishot,version,is_edit,is_add,beau_sel,ma_id,isorg,refer_count,refer_id,isdraw,iscopy,is_marketa_enjoy,showTitle,searchKeyword,music,classify_id,template_status,option_id,approvedBy,deleteReason,parent_id) " + 258 " (SELECT t1.title,t1.status,NOW(),t1.notice,t1.template,t2.user_id,NOW(),t1.description,0,t2.org_id,0,t1.notice_days,0,0,t1.ishot,2.00,t1.is_edit,t1.is_add,t1.beau_sel,t1.ma_id,0,t1.refer_count,t1.refer_id,t1.isdraw,t1.iscopy,0,t1.showTitle,t1.searchKeyword,t1.music,t1.classify_id,t1.template_status,t1.option_id,t1.approvedBy,t1.deleteReason, " + 259 " {parent_id} " + 260 " FROM d_flyer t1, " + 261 " (select DISTINCT user_id, org_id from m_org_user where user_id in({user_ids}) and del=0 and dept_id !=0 ) t2 " + 262 " WHERE t1.id=? AND t1.deleted=0 AND t1.user_id=?)"; 263 default: 264 265 } 266 267 return sql; 268 } 269 270 /** 271 * =====================================輔助方法清單:方法五================================================================== 272 */ 273 private List<Map<String, Object>> getSharedFlyerInfoByUserIds(Integer maId, Integer parentId, String userIds){ 274 List<Map<String, Object>> flyers = null; 275 String sql = "SELECT t.id AS flyer_id,t.user_id, t.orgid FROM d_flyer t WHERE t.user_id IN ({user_ids}) AND t.ma_id=? AND t.parent_id=?"; 276 sql = sql.replace("{user_ids}", userIds); 277 Object[] params = new Object[]{maId, parentId}; 278 flyers = this.getDao().query(sql, params, null); 279 return flyers; 280 } 281 /** 282 * =====================================輔助方法清單:方法六================================================================== 283 */ 284 private void refreshNameCard(List<Map<String, Object>> flyerDetails){ 285 if(null==flyerDetails || flyerDetails.isEmpty()){ //如果沒有任何相關的表 286 return; 287 } 288 for(int i=0; i<flyerDetails.size(); i++){//獲取 289 Map<String, Object> flyer = flyerDetails.get(i); 290 Integer userId = Integer.parseInt(flyer.get("user_id").toString());//獲取傳單所屬用戶 291 Integer flyerId = Integer.parseInt(flyer.get("flyer_id").toString());// 相關的傳單id 292 String content = flyer.get("content").toString();// 傳單設置的內容 293 //String updateContent = flyer.get("updated_content").toString();//傳單發布後設置的內容 為空!!!!!!! 294 /**輔助方法清單:方法七*/ 295 Map<String, Object> m = JsonUtil.jsonToMap(content);/**content 格式化後長度過長 會在最下面展示*/ 296 //m 是json解析的總根 ~ 297 List<Map<String,String>> widgets = (List<Map<String, String>>) m.get("widgets"); 298 for(int j=0; j<widgets.size(); j++){ 299 Map<String, String> widget = widgets.get(j); 300 String wdUname = widget.get("wd_u_name"); 301 if("bio".equals(wdUname)){// 找到名片 復制了簡單的我們需要的json數據 302 /**輔助方法清單:方法九*/ 303 Map<String, String> newCard = replaceCardInfo(widget, userId, flyerId, flyer);//生成用戶 新的名片 304 widgets.set(j, newCard);//應該就一個 - -! 設置回去 305 } 306 } 307 m.put("widgets", widgets);//用新的替換了之前的 308 /**輔助方法清單:方法八*/ 309 String newContent = JsonUtil.objToJson(m);//重新轉換成json字符串 310 //訪問數據庫,開始修改detail表的數據 311 /**輔助方法清單:方法十*/ 312 updateDetailContent(flyerId, newContent);// 更改詳細信息表裡面的content數據 313 314 } 315 /**輔助方法六調用結束 返回passFlyerToUsers() 方法的調用處(倒數7行左右)*/ 316 } 317 /** 318 * =====================================輔助方法清單:方法九================================================================== 319 */ 320 private Map<String, String> replaceCardInfo(Map<String, String> widget, Integer userId, Integer flyerId, Map<String, Object> userInfo){ 321 /*"wd_u_name":"bio","company":"貴州限責任公司","job":"職位","realname":"李小姐", 322 "qq":"1234578","tell":"085-1234567","sina":"http://webo.com/baogs/ome?vr=5","email":"[email protected]", 323 "web":"http://www.e.com/","address":"貴陽號",*/ 324 Map<String, String> card = new HashMap<String, String>(); 325 Set<String> keySet = widget.keySet();// company job realname ==的key集合 326 System.out.println("----------Start replace mobile card info[userId="+userId+",flyerId="+flyerId+"]---------------"); 327 for(String key : keySet){ 328 Object userObj = null; 329 if("realname".equals(key)){ 330 userObj = userInfo.get("realname"); 331 } else if("qq".equals(key)){ 332 userObj = userInfo.get("qq"); 333 } else if("tell".equals(key)){ 334 userObj = userInfo.get("mobile"); 335 } else if("email".equals(key)){ 336 userObj = userInfo.get("email"); 337 } else if("phone".equals(key)){ 338 userObj = userInfo.get("phone"); 339 } else if("weixin".equals(key)){ 340 userObj = userInfo.get("weixin"); 341 } else if("job".equals(key)){ 342 userObj = userInfo.get("job") 343 } 344 System.out.println(key+" = "+String.valueOf(userObj)); 345 String value = ""; 346 if(null==userObj){ 347 value = String.valueOf(widget.get(key)); //沒有的話 用原來的 348 } else { 349 value = String.valueOf(userObj); //有的話 設置進去 350 } 351 card.put(key, value); //放到map裡面 352 } 353 System.out.println("----------End replace mobile card info---------------"); 354 return card; //返回回去 355 } 356 357 /** 358 * =====================================輔助方法清單:方法十================================================================== 359 */ 360 private void updateDetailContent(Integer flyerId, String content){ 361 String sql = "update d_flyer_detail set content = ? where flyer_id = ?"; 362 Object[] params = new Object[]{content, flyerId}; 363 this.getDao().update(sql,params); 364 } 365 366 /** 367 * =====================================輔助方法清單:方法十一================================================================== 368 */ 369 private void uploadShareFlyerHtmlFile(Integer maId, Integer flyerId, Integer userId, Integer orgId, List<Map<String, Object>> members) throws Exception{ 370 //本地html保存路徑 371 //獲取ServletAction上下文對象,getServletContext()獲取Servlet上下文對象(項目地址),getRealPath("file")獲取file的!絕對路徑! 加上/加上flyer 372 String localHtmlRoot = ServletActionContext.getServletContext().getRealPath("file")+ File.separatorChar +"flyer"; 373 //本地共享傳單路徑 374 String shareHtmlPath = localHtmlRoot + File.separator + "html" + File.separator + userId+ File.separator; 375 //共享傳單文件名稱 376 String shareFileName = flyerId + ".html"; //被共享的傳單的地址拼接完成 377 378 //上傳路徑 379 final String realPath = ServletActionContext.getServletContext().getRealPath("");//獲取項目的絕對路徑 380 File shareFile = new File(shareHtmlPath + shareFileName); //被共享傳單的File對象 381 if(!shareFile.exists()){ // 如果不存在 則拋出異常 382 throw new RuntimeException("共享失敗,共享傳單不存在!"); 383 } 384 for(int i=0; i<members.size(); i++){ //為每一個用戶復制被共享的一份傳單 放到自己的/user_id/flyer_id下面 385 String uploadFilePath = ""; 386 String tmpFileName = ""; 387 Map<String, Object> mem = members.get(i); 388 Integer inviteUserId = (Integer) mem.get("user_id"); 389 Integer inviteUserOrg = (Integer) mem.get("orgid"); 390 Integer inviteUserFlyerId = (Integer) mem.get("flyer_id"); 391 tmpFileName = inviteUserFlyerId + ".html"; 392 String tmpFilePath = localHtmlRoot + File.separator + "html" +File.separator + inviteUserId+ File.separator; 393 String tmpFileFullName = tmpFilePath + tmpFileName; 394 //文件名 和文件路徑判斷 先有路徑才能創建文件 395 File tmpFile = new File(tmpFileFullName); 396 File tmpDirs = new File(tmpFilePath); 397 if(!tmpDirs.exists()){//文件路徑不存在的情況下 創建文件路徑 398 tmpDirs.mkdirs(); 399 } 400 if(tmpFile.exists()){ //如果先前文件已經存在(未刪除)則進行刪除 401 tmpFile.delete(); 402 } 403 //復制共享傳單 404 /**輔助方法清單:方法十二*/ 405 FileUtil.copyFile(shareFile, tmpFile);//建立流 復制傳單 406 if(!tmpFile.exists()){ //再次判斷是否復制了傳單 407 throw new RuntimeException("共享失敗,復制傳單"+tmpFileName+"失敗!"); 408 } 409 // 更改了成員傳單的 名片 等詳細信息 410 /**輔助方法清單:方法十三*/ 411 reloadCardHtml(tmpFile, mem); 412 //上傳成員傳單html文件 413 uploadFilePath = localHtmlRoot.replace(realPath, "") + File.separator + "html" + File.separator + inviteUserOrg + File.separator + tmpFileName; 414 try { 415 FileService.UpYunWriteFile(uploadFilePath, tmpFile, false); 416 } catch (Exception e) { 417 e.printStackTrace(); 418 } 419 }//for循環右括號 420 } 421 /** 422 * =====================================輔助方法清單:方法十三================================================================== 423 */ 424 /** 使用了 Jsoup解析了 html文檔樹*/ 425 private void reloadCardHtml(File html, Map<String, Object> userInfo){ 426 // FileWriter fw = null; 427 OutputStreamWriter writer = null; 428 boolean flag = false; 429 try { 430 Integer inviteUserId = (Integer) userInfo.get("user_id"); 431 Integer inviteUserOrg = (Integer) userInfo.get("orgid"); 432 Integer inviteUserFlyerId = (Integer) userInfo.get("flyer_id"); 433 System.out.println("==========Start replace html bio[userId="+inviteUserId+",flyerId="+inviteUserFlyerId+"]========================"); 434 //http://www.jb51.net/article/43485.htm Jsoup的使用 435 //<span class="realname" data-key="realname">“構享家”團隊</span> 436 Document doc = Jsoup.parse(html, "UTF-8"); 437 438 Elements companies = doc.getElementsByAttributeValue("data-key", "company"); 439 Elements jobs = doc.getElementsByAttributeValue("data-key","job"); 440 Elements realname = doc.getElementsByAttributeValue("data-key","realname"); 441 Elements qq = doc.getElementsByAttributeValue("data-key","qq"); 442 Elements wechats = doc.getElementsByAttributeValue("data-key","weixin"); 443 Elements mobile = doc.getElementsByAttributeValue("data-key","tell"); 444 Elements phone = doc.getElementsByAttributeValue("data-key","mobile"); 445 Elements weibos = doc.getElementsByAttributeValue("data-key","sina"); 446 Elements emails = doc.getElementsByAttributeValue("data-key","email"); 447 Elements webs = doc.getElementsByAttributeValue("data-key","web"); 448 Elements address = doc.getElementsByAttributeValue("data-key","address"); 449 450 String userCompany = String.valueOf(userInfo.get("company")==null?"":userInfo.get("company")); 451 String userJob = String.valueOf(userInfo.get("job") == null ? "" : userInfo.get("job")); 452 String userQQ = String.valueOf(userInfo.get("qq")==null?"":userInfo.get("qq")); 453 String userMobile = String.valueOf(userInfo.get("mobile")==null?"":userInfo.get("mobile")); 454 String userPhone = String.valueOf(userInfo.get("phone")==null?"":userInfo.get("phone")); 455 String userRealname = String.valueOf(userInfo.get("realname")==null?"":userInfo.get("realname")); 456 String userEmail = String.valueOf(userInfo.get("email")==null?"":userInfo.get("email")); 457 String userWeixin = String.valueOf(userInfo.get("weixin")==null?"":userInfo.get("weixin")); 458 if(null!=realname && realname.size()>0){ 459 Element e = realname.get(0); 460 e.text(userRealname);//給元素內容設置數據 461 System.out.println("realname="+userRealname); 462 flag = true; 463 } 464 465 if(null!=phone && phone.size()>0){ 466 Element e = phone.get(0); 467 e.text(userPhone); 468 System.out.println("phone="+userPhone); 469 flag = true; 470 } 471 472 if(null!=mobile && mobile.size()>0){ 473 Element e = mobile.get(0); 474 e.text(userMobile); 475 System.out.println("mobile="+userMobile); 476 flag = true; 477 } 478 479 if(null!=qq && qq.size()>0){ 480 Element e = qq.get(0); 481 e.text(userQQ); 482 System.out.println("qq="+userQQ); 483 flag = true; 484 } 485 486 if(null!=emails && emails.size()>0){ 487 Element e = emails.get(0); 488 e.text(userEmail); 489 System.out.println("email="+userEmail); 490 flag = true; 491 } 492 493 if(null!=wechats && wechats.size()>0){ 494 Element e = wechats.get(0); 495 e.text(userWeixin); 496 System.out.println("weixin="+userWeixin); 497 flag = true; 498 } 499 System.out.println("==========End replace html bio[userId="+inviteUserId+",flyerId="+inviteUserFlyerId+"]========================"); 500 if(flag){ //如果有更改 in √ 501 String htmlContent = doc.html();//doc對象的內容已經變了? 現在實際上是jsoup一次性解析了html文件 502 // 生成 Document對象 一直在內存中 我們只是操作了對象 503 // String aaa = doc.data(); 測試代碼 504 // String bbb = doc.html(); 505 // String ccc = doc.val(); 506 // fw = new FileWriter(html); 507 // fw.write(htmlContent); 508 writer = new OutputStreamWriter(new FileOutputStream(html), "UTF-8"); //開啟了到更新文件的 輸出流 509 writer.write(htmlContent); //把文檔輸出到裡面去 內存到硬盤的寫入 510 writer.close(); 511 } 512 } catch (Exception e) { 513 e.printStackTrace(); 514 } 515 } 516 }
兩個工具類(不完全):
1 //--------------------------JsonUtil類---------使用了google提供的 gson類 解析json-a------------------------------------------------------ 2 import com.google.gson.Gson; 3 import com.google.gson.GsonBuilder; 4 import com.google.gson.reflect.TypeToken; 5 6 public class JsonUtil{ 7 private static Gson gson; 8 /** JSON字符串轉化為HashMap對象*/ 9 /** 10 * =====================================輔助方法清單:方法七================================================================== 11 */ 12 public static Map<String, Object> jsonToMap(String string) { 13 Map<String, Object> obj = null; 14 try { //s使用 google的gson包 15 obj = JsonUtil.getGson().fromJson(string, new TypeToken<Map<String, Object>>(){}.getType()); 16 }catch (Exception e) { 17 e.printStackTrace(); 18 } 19 return obj; 20 } 21 /** 22 * =====================================輔助方法清單:方法八================================================================== 23 */ 24 public static String objToJson(Object data) { 25 try { 26 return JsonUtil.getGson().toJson(data); 27 } catch (Exception e) { 28 e.printStackTrace(); 29 } 30 return ""; 31 } 32 } 33 34 //--------------------------FileUtil類---------使用了google提供的 gson類 解析json-a------------------------------------------------------ 35 public class FileUtil { 36 /** 37 * =====================================輔助方法清單:方法十二================================================================== 38 */ 39 public static boolean copyFile(File sourceFile, File targetFile) { 40 try { 41 BufferedInputStream inBuff = null; 42 BufferedOutputStream outBuff = null; 43 try { 44 // 新建文件輸入流並對它進行緩沖 45 inBuff = new BufferedInputStream(new FileInputStream(sourceFile)); 46 47 // 新建文件輸出流並對它進行緩沖 48 outBuff = new BufferedOutputStream(new FileOutputStream(targetFile)); 49 // 緩沖數組 50 byte[] b = new byte[1024 * 100]; 51 int len; 52 while ((len = inBuff.read(b)) != -1) { 53 outBuff.write(b, 0, len); 54 } 55 // 刷新此緩沖的輸出流 56 outBuff.flush(); 57 } finally { 58 // 關閉流 59 if (inBuff != null) 60 inBuff.close(); 61 if (outBuff != null) 62 outBuff.close(); 63 } 64 } catch (Throwable e) { 65 e.printStackTrace(); 66 return false; 67 } 68 return true; 69 } 70 71 }
/**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ content內容展~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1 /* 2 {"widgets": 3 [ 4 {"wd_u_name":"title", 5 "value":"找工作去勞聯,電信送手機", 6 "href":"http://baidu.com", 7 "color":"#000000", 8 "colors":[ 9 "#000000", 10 "#ff7418", 11 "#f14444", 12 "#a25c18", 13 "#b62450"], 14 "fontSize":"25px", 15 "fontFamily":"Microsoft YaHei,Microsoft YaHei", 16 "marginTop":"10px", 17 "textAlign":"center"}, 18 19 {"wd_u_name":"map", 20 "value":"北京市海澱區上地信息路28號科實大廈", 21 "marginTop":"5px"}, 22 {"wd_u_name":"media", 23 "value":"http://player.youku.com/player.php/sid/XNjY0NDI4MjE2/v.swf", 24 "color":"#000000", 25 "marginTop":"5px"}, 26 27 {"wd_u_name":"feedback", //反饋表 28 "btnLabel":"搶購", 29 "items": 30 [ 31 {"name":"name", 32 "allowBlank":"false", 33 "label":"姓 名 "}, 34 {"name":"weibo", 35 "label":"微博", 36 "maxlength":64, 37 "input":"string", 38 "width":"100", 39 "allowBlank":"true"}, 40 {"name":"phone", 41 "label":"電話", 42 "maxlength":32, 43 "sortable":true, 44 "type":"string", 45 "width":"100", 46 "allowBlank":"false"}, 47 {"name":"mobile", 48 "label":"手 機", 49 "allowBlank":"false"}, 50 {"name":"appellation", 51 "label":"稱呼", 52 "maxlength":32, 53 "input":"string", 54 "width":"100", 55 "allowBlank":"true"}, 56 {"name":"email", 57 "label":"郵 箱 ", 58 "allowBlank":"true"}, 59 {"name":"position", 60 "label":"經紀人", 61 "maxlength":32, 62 "input":"string", 63 "width":"100", 64 "allowBlank":"false"}, 65 {"name":"note", 66 "label":"備注", 67 "maxlength":200, 68 "type":"string", 69 "input":"textarea", 70 "width":"150"}, 71 {"name":"company", 72 "label":"公司", 73 "maxlength":64, 74 "sortable":true, 75 "input":"string", 76 "width":"150"}, 77 {"name":"qq", 78 "label":"QQ", 79 "allowBlank":"true"}, 80 {"name":"address", 81 "label":"地址", 82 "maxlength":128, 83 "type":"string", 84 "width":"100", 85 "allowBlank":"true"} 86 ], 87 "fontSize":"13px", 88 "marginTop":"10px"}, 89 90 -------------//名片表-----------------------主要是他更新 因為傳單的名片應該是發到A的賬號中去的時候就變成A的相關的信息 當然也可以編輯 91 {"wd_u_name":"bio", 92 "company":"貴州限責任公司", 93 "job":"職位", 94 "realname":"李小姐", 95 "qq":"", 96 "tell":"08516550", 97 "sina":"http://webo.com/baogs/ome?vr=5", 98 "email":"[email protected]", 99 "web":"http://www.e.com/", 100 "address":"貴陽號", 101 "marginTop":"0px", 102 "imgsrc":"/file/flyer/tdcode/png201431118063553.png", 103 "status":2, 104 "fontSize":"18px", 105 "color":"rgb(0, 106 0, 107 0)", 108 "colors":["#000000", 109 "#7f8c2f", 110 "#85622a", 111 "#b66c2a", 112 "#a92e2e"]} 113 ], 114 "meta":{"color":"#fedac2", 115 "bgImg":"/flyer/images/flyerimg/flyer_bg_6.jpg", 116 "shadingImg":"/flyer/images/bgimg/06.png"}} 117 */
OK 結束 再次聲明 此博客為個人筆記 並不是獨立demo