//////////////////////////// 注意: 此博客是个人工作笔记 非独立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() ; " + 19 "---wunian7yulian testing...-----The var is: null , And The value is: " + "--flag1--" + " ---------"); 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() ; " + 40 "---wunian testing...-----The var is: 已经分享的:没有分享的 , And The value is: " + hasSharedList.size() +"//"+ notSharedList.size() + " ---------"); 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 "========== "+"maId:"+maId +" flyerId:"+flyerId +" userIds:" + userIds); 148 List<Map<String, Object>> list = this.getDao().query(sql, params, null);// 149 System.out.println("查询列表长度为: "+ list.size() +"==="+list+ " ---------"); 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":"255123456@qq.com", 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":"2556890@qq.com", 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