post 微信开发_微信公众号开发,为什么微信服务器发送的是post请求 - CSDN
  • 今天整理一下微信开发中遇到的图片和附件的上传问题。 开发环境参考:微信开发(一)--分享接口 点击打开链接 由于是基于weixin-java-tools 封装的java sdk,所以在微信底层处理上我们可以直接调用WxMpService. ...

          今天整理一下微信开发中遇到的图片和附件的上传问题。

          开发环境参考:微信开发(一)--分享接口 点击打开链接

          由于是基于weixin-java-tools 封装的java sdk,所以在微信底层处理上我们可以直接调用WxMpService.

          .数据准备:

               进入页面前,根据条件查询相应的图片附件列表(已有数据时进行展示,没有数据可以忽略):

    	           //查询图片数据  
    		List<FileModel> imgList = fileModelService.loadFileModelsByBFTT(11);
    		   //查询附件数据
    		List<FileModel> attachmentFileList = fileModelService.loadFileModelsByBFTT(11);
    		

          二.页面准备:    

                jspye页面设置上传按钮,遍历读取图片列表   

        <!-- 图片上传 -->   
    				 <div class="form-group">
    				    <div class="input-group">
    				       <div class="input-group-addon "><span style="color:red;"> </span>图片上传:</div>
    				       <input type="hidden" name="fileIds" id="fileIds">
    				       <div class="input-group-addon">
    				       	
    				       				<a href="javascript:void(0)" οnclick="chooseImage('${basePath }','${id}');">
    						       			<span class="glyphicon glyphicon-plus"></span>
    						       		</a>
    				       
    				       </div>
    				    </div>
    				  </div>
    				  
    				  <!-- 缩略图 -->
    				  <ul class="body-img-ul">
    				  		<c:forEach items="${imgList}" var="v" varStatus="sta">
    				  			<li style="background-image:url('${simplePath }${v.revealpath }')" 
    				  				οnclick="previewImage('${simplePath }${v.revealpath }');">
    				  		
    					       		<i class="del_icon" οnclick="deleteImage('${v.id }',this,'${basePath }')"></i>
    		    	            </li>
    				  		</c:forEach>
    				  </ul>
    				   <!-- 附件上传 --> 
    				   <div class="form-group">
    				    <div class="input-group">
    				       <div class="input-group-addon "><span style="color:red;"> </span>附件上传:</div>
    				       <div class="input-group-addon">
    				       		<input type="hidden" name="attachmentIds" id="attachmentIds">
    				       		
    					       				<span class="glyphicon glyphicon-plus">
    					       					<input type="file" class="attachmentFile" name="attachmentFile" id="attachmentFile"
    						       				 οnchange="uploadAttachment('${basePath }','${id}');"/>
    					       				</span>
    				       </div>
    				    </div>
    				  </div>
    				  <!-- 附件 -->
    				  <ul class="body-file-ul">
    				  		<c:forEach items="${attachmentFileList }" var="v" varStatus="sta">
    		    	            <li>
    					  			<a href="${simplePath }${v.revealpath }">
    					  				<c:choose>
    			              		 		<c:when test="${fn:length(v.filename) < 20 }">
    			              		 			${v.filename }
    			              		 		</c:when>
    			              		 		<c:otherwise>
    			              		 			${fn:substring(v.filename,0,20) }....${v.extname }
    			              		 		</c:otherwise>
    			              		 	</c:choose>
    					  			</a>
    					
    					       				<i class="del_icon" οnclick="deleteImage('${v.id }',this,'${basePath }')"></i>
    		    	            </li>
    				  		</c:forEach>
    				  </ul>
    				<!-- 附件上传 -->  
    				    

         三.初始化jssdk:  

              controller

    @Controller
    @RequestMapping("jssdk")
    public class WeXinJsSdkController {
    	
    	@Autowired
    	private WxMpService wxMpService;
    	
    	@RequestMapping(value = "/config", method = RequestMethod.GET)
    	@ResponseBody
    	public WxJsapiSignature wxJsSdkConfig(HttpServletRequest request,String url) {
    		try {
    			WxJsapiSignature wxJsapiSignature = wxMpService.createJsapiSignature(url);
    			return wxJsapiSignature;
    		} catch (WxErrorException e) {
    			return null;
    		}
    	}
    	  
    }
      js请求获取config 参数 
    	/* 初始化jssdk */
    	$.get("${basePath}/jssdk/config.do",{url:window.location.href},function(data,status){
    		if(status == "success"){
    			wx.config({
    			    debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
    			    appId: data.appId, // 必填,公众号的唯一标识
    			    timestamp: data.timestamp, // 必填,生成签名的时间戳
    			    nonceStr: data.nonceStr, // 必填,生成签名的随机串
    			    signature: data.signature,// 必填,签名,见附录1
    			    jsApiList: ['chooseImage', 'uploadImage', 'downloadImage', 'previewImage'] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2
    			 
    			});
    			wx.ready(function(){
    				//layer.msg("jssdk初始化成功");
    			    // config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,config是一个客户端的异步操作,
    			    //所以如果需要在页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行。对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中。
    			});
    			wx.error(function(res){
    			    // config信息验证失败会执行error函数,如签名过期导致验证失败,具体错误信息可以打开config的debug模式查看,
    			    //也可以在返回的res参数中查看,对于SPA可以在这里更新签名。
    				layer.msg(res);
    			});
    		}
    		},"json");

      js 配置

        1. chooseImage    手机选择或拍摄图片 
        2. uploadImage    上传图片到微信服务器
        3. downloadImage  下载图片到本地

        previewImage   本地图片预览 


    	
    	//微信sdk上传图片------------------------
    var images = {
    	    localIds: [],
    	    serverIds: [],
    	  }; 
    function chooseImage(basePath,id){
    	wx.chooseImage({
    	    count: 6, // 默认9
    	    sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图,默认二者都有
    	    sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机,默认二者都有
    	    success: function (res) {
    	    	images.localIds = res.localIds; // 返回选定照片的本地ID列表,localId可以作为img标签的src属性显示图片
    	    	//显示缩略图
    	        for(var i=0;i<images.localIds.length;i++){
    	        	var liLength = $(".body-img-ul li").length;
    	        	if(liLength >= 6 ){
    	        		layer.msg("最多允许上传6张图片!");
    					return;
    		        }
    	        	var imgHtml = "<li style=\"background-image:url('"+images.localIds[i]+"')\"";
    	        		   imgHtml += "οnclick=\"previewImage('"+images.localIds[i]+"')\">";
    	        		   imgHtml += "<i class=\"del_icon\"></i>";
    	        		   imgHtml += "</li>";
    	  				
    	        	$(".body-img-ul").append(imgHtml);
    		    }
    		    //递归的上传图片
    	        syncUpload(images.localIds,id);
    	    }
    	});
    }
    //将微信服务器的图片下载到本地
    var syncUpload = function(localIds,id){
    	var localId = localIds.pop();
    	//上传图片到微信服务器
        wx.uploadImage({
            localId: localId, // 需要上传的图片的本地ID,由chooseImage接口获得
            isShowProgressTips: 1, // 默认为1,显示进度提示
            success: function (res) {
            	images.serverIds.push(res.serverId); // 返回图片的服务器端ID
                if(localIds.length > 0){
                	syncUpload(localIds,id);  
                }else if(images.localIds.length == 0){
                	var serverids = images.serverIds.join(',');
                	$.post(
                		basePath+"/fileupload/uploadImg.do",
                		{"serverIds":serverids,"id":id}
                		,function(data,status){
            			if(status == "success"){
            				images.serverIds = [];
            				//存储文件id到页面
            				setFileIds(data.join(','));
            				
            				var tempLen = $(".del_icon").length;
            				var dataLen = data.length;
            				var del_index;
            				var del_id;
            				for(var i = 1;i<dataLen+1;i++){
            					del_index = tempLen-i;
            					del_id = data[i-1];
            					addDeleteEvent(del_index,del_id,basePath);
            				}
            				layer.msg("上传成功!");
            			}
            	  },"json");
                }
            }
        });
     }
    //添加事件
    function addDeleteEvent(del_index,del_id,basePath){
    	$(".del_icon").eq(del_index).click(function(e){
    		deleteImage(del_id,this,basePath);
    		window.event.cancelBubble = true;
    	});
    }
    //添加上传的filemodeID
    function setFileIds(fildIds){
    	var temp = $("#fileIds").val();
    	if(temp == ""){
    		 $("#fileIds").val(fildIds)
    	}else{
    		$("#fileIds").val(temp+","+fildIds)
    	}
    }
    //预览图片
    function previewImage(url){
    	document.write("url----"+url);
    	 wx.previewImage({
             current: url, // 当前显示图片的http链接
             urls: [url] // 需要预览的图片http链接列表
    	 });
    }
    //异步删除图片
    function deleteImage(id,obj,basePath){
    	$.ajax({
    		  type: 'POST',
    		  url: basePath+"/fileupload/deleteFile.do",
    		  data:{"id":id},
    		  dataType: 'json',
    		  success: function(data){
    			 if(data.state == 200){
    				layer.msg("删除成功!");
    				 //移除对应数据
    				 $(obj).parent()[0].remove();
    			 }else{
    				 layer.msg("删除失败!");
    			 }
    		  }
    		});
    	 window.event.cancelBubble = true;
    }
    //微信sdk上传图片------------------------
    //上传附件
    function uploadAttachment(basePath,id) {
       //限制数量
    	var liLength = $(".body-file-ul li").length;
    	if(liLength >= 6 ){
    		layer.msg("最多允许上传6份附件!");
    		return;
        }
       //上传文件
       $.ajaxFileUpload({
           url: basePath+"/fileupload/uploadAttachment.do", //文件上传到哪个地址,告诉ajaxFileUpload
           data:{"bussinessId":bussinessId,"id":id},
           secureuri: false, //一般设置为false
           fileElementId: 'attachmentFile', //文件上传控件的Id  <input type="file" id="fileUpload" name="file" />
           dataType: 'json', //返回值类型 一般设置为json
           success: function (data, status){//服务器成功响应处理函数
        	   if(data.state == 200){
        		   var imgHtml = "<li>";
        		   imgHtml += "<a href=\""+basePath+data.data[2]+"\">"+data.data[1]+"</a>";
        		   imgHtml += "<i class=\"del_icon\" οnclick=\"deleteImage('"+data.data[0]+"',this,'"+basePath+"')\"></i>";
        		   imgHtml += "</li>";
        		   $(".body-file-ul").append(imgHtml)
        		   //存储文件id到页面
        		   setFileIds(data.data[0]);
        	   }
    		   layer.msg(data.msg);
           	}
           });
       };
    	
    
    .后台配置文件名称,设置本地存储路径,把相应数据存储到本地:  

    @Controller
    @RequestMapping("/fileupload")
    public class FileUploadController {
    	
    	public String prefix ="yongjun/upload/";
    	private Logger logger = LoggerFactory.getLogger(this.getClass());
    	@Autowired
    	private WxMpService wxMpService;
    	@Autowired
    	private UsersService usersService;
    	@Autowired
    	private FileModelService fileModelService;
    	@Value(value = "#{resourceProperties['uploadUrl']}")
    	private String uploadUrl;
    	
    	@RequestMapping(value = "/uploadImg", method = RequestMethod.POST)
    	@ResponseBody
    	public String[] uploadImg(String serverIds,BigDecimal id,HttpServletRequest request){
    		
    		String[] result;
    		//获取当前用户
    		CurrentUser currentUser = usersService.getCurrentUser(request);
    		try {
    			String[] serverId_arr = serverIds.split(",");
    			if(serverId_arr != null && currentUser != null){
    				//图片存储
    				List<FileModel> fileModelStorelist = new ArrayList<FileModel>();
    				for (int i=0;i<serverId_arr.length;i++) {
    					File file = wxMpService.getMaterialService().mediaDownload(serverId_arr[i]);
    					String filePath = FileUploadUtil.uploadImg(file, uploadUrl, currentUser);
    					//文件模型数据
    					FileModel fileModel = new FileModel();
    					fileModel.setCreatedTime(new Date());
    					byte disabled = 0;
    					fileModel.setDisabled(disabled);
    					fileModel.setFilename(file.getName());
    					fileModel.setRealname(file.getName());
    					fileModel.setExtname(filePath.substring(filePath.lastIndexOf(".")+1));
    					fileModel.setFilepath(filePath);
    					fileModel.setRevealpath(filePath.replace("C:\\crm2009\\upload", "/myImg").replace("\\", "/"));
    					fileModel.setFiletype("image");
    					
    					fileModelStorelist.add(fileModel);
    				}
    				result = fileModelService.storeFileModelList(fileModelStorelist);
    				return result;
    			}else{
    				logger.info("当前用户不存在!!");
    				return null;
    			}
    		} catch (Exception e) {
    			e.printStackTrace();
    			logger.info("下载文件失败!!"+e.getClass());
    			return null;
    		}
    		
    		
    	}
    	@RequestMapping(value = "/uploadAttachment", method = RequestMethod.POST)
    	@ResponseBody
    	public ResultData uploadAttachment(BigDecimal bussinessId,BigDecimal id,HttpServletRequest request,MultipartFile attachmentFile){
    		
    		//判断文件类型
    		String originalFilename = attachmentFile.getOriginalFilename();
    		String[] imagType={".jpg",".png",".bmp",".gif"};
    		List<String> imagTypeList = Arrays.asList(imagType);
    		if(imagTypeList.contains(originalFilename.substring(originalFilename.lastIndexOf(".")).toLowerCase())){
    			return ResultData.error("无法上传图片!");
    		}
    		String[] result = new String[3];
    		//获取当前用户
    		CurrentUser currentUser = usersService.getCurrentUser(request);
    		try {
    			if(currentUser != null){
    				//上传文件
    				String filePath = FileUploadUtil.uploadFile(attachmentFile, uploadUrl, currentUser);
    				//文件模型数据
    				FileModel fileModel = new FileModel();
    				fileModel.setCreatedTime(new Date());
    				byte disabled = 0;
    				fileModel.setBussinessid(bussinessId);
    				fileModel.setDisabled(disabled);
    				fileModel.setFilename(originalFilename);
    				fileModel.setRealname(filePath.substring(filePath.lastIndexOf("/")+1));
    				fileModel.setExtname(filePath.substring(filePath.lastIndexOf(".")+1));
    				fileModel.setFilepath(filePath);
    				fileModel.setRevealpath(filePath.replace("C:\\crm2009\\upload", "/myImg").replace("\\", "/"));
    				fileModel.setFiletype("attachment");
    				fileModelService.storeFileModel(fileModel);
    				
    				result[0] = fileModel.getId().toString();
    				result[1] = fileModel.getFilename();
    				result[2] = fileModel.getRevealpath();
    				return ResultData.ok(result, "上传成功!");
    			}else{
    				logger.info("当前用户不存在!!");
    				return null;
    			}
    		} catch (Exception e) {
    			e.printStackTrace();
    			logger.info("下载文件失败!!"+e.getClass());
    			return null;
    		}
    		
    		
    	}
    	
    	@RequestMapping(value = "/deleteFile", method = RequestMethod.POST)
    	@ResponseBody
    	public ResultData deleteFile(BigDecimal id){
    		fileModelService.deleteFileModel(id);
    		return ResultData.ok();
    	}
    	
    }
    .设置 文件转接工具类:

         

    public class FileUploadUtil {
    	/**
    	 * 上传文件
    	 * @param file 源文件
    	 * @param uploadUrl 上传地址
    	 * @param currentUser 当前用户
    	 * @param fileType 
    	 * @return
    	 */
    	public  static String uploadImg(File file,String uploadUrl,CurrentUser currentUser) {
    		//处理待写入的位置
    		if(currentUser != null){
    			uploadUrl += "\\image\\" +currentUser.getLoginName().toString();
    		}
    		File uploadPosition = new File(uploadUrl);
    		if(!uploadPosition.exists()){
    			//文件路径不存在,则创建
    			uploadPosition.mkdirs();
    		}
    		if (file.renameTo(new File(uploadPosition + "\\" + file.getName()))) {
                System.out.println("File is moved successful!");
            } else {
                System.out.println("File is failed to move!");
            }
    		return uploadPosition + "/" + file.getName();
    	}
    	public  static String uploadFile(MultipartFile file,String uploadUrl,CurrentUser currentUser) throws UnsupportedEncodingException {
    		//处理待写入的位置
    		if(currentUser != null){
    			uploadUrl += "\\attachment\\" +currentUser.getLoginName().toString();
    		}
    		File uploadPosition = new File(uploadUrl);
    		if(!uploadPosition.exists()){
    			//文件路径不存在,则创建
    			uploadPosition.mkdirs();
    		}
    		String originalFilename = file.getOriginalFilename();
    		String realName = UUID.randomUUID().toString() + originalFilename.substring(originalFilename.lastIndexOf("."));
    		try {
    			file.transferTo(new File(uploadPosition + "\\" +  realName));
    			System.out.println("File is moved successful!");
    		} catch (IllegalStateException | IOException e) {
    			e.printStackTrace();
    			System.out.println("File is failed to move!");
    		}
    		return uploadPosition + "/" + realName;
    	}
    } 
       学习在于不断地探索、思考和总结记录,欢迎喜欢的朋友们在下方留言,与君共同进步!







    展开全文
  • 凭借大量活跃用户,微信已成为商家重要营销平台之一。商家为庞大用户群提供定制化服务的迫切需求,吸引了大量开发者/开发商投入到...在CSDN站内,拥有大量与微信开发相关的资源,包括技术博客、问题讨论、工具资源

    http://bss.csdn.net/m/topic/learning_path_weixin

    凭借大量活跃用户,微信已成为商家重要营销平台之一。商家为庞大用户群提供定制化服务的迫切需求,吸引了大量开发者/开发商投入到微信公众平台开发中。学习和掌握微信公众平台开发技术,已成为开发者淘金的另一重要选择。

    在CSDN站内,拥有大量与微信开发相关的资源,包括技术博客、问题讨论、工具资源等。CSDN邀请多位微信开发专家对这些资源取其精华,按照微信开发的学习路线展示站内优质资源,从基础入门到高级开发,帮你全面掌握微信开发。

    这里,我们为您推出的是微信开发的基础入门及高级进阶部分。

    热门学习

     微信支付之H5页面WAP端接入

    本文将介绍如何在WAP端实现微信支付,包括页面和后台接口的实现过程。作者还分享了这一开发过程中所遭遇的坑及解决方案

    蚂蚁爱吃糖发布于2015-10-10

     微信支付开发系统开发流程及完整Demo展示

    微信支付有很多坑,官方文档也不太全面,且Demo比较“羞涩”难懂。如果所需注意的细节无法体会到,开发者将会很多弯路。本文将系统讲解微信支付开发流程及注意事项,并附上完整Demo。

    忘记是最好的记得发布于2015-09-26

     微信公共服务平台开发(.Net实现):获取Access Token

    成为开发者,微信平台会向你提供AppID和Secret,而这些在订阅号中是没有的,所以应该申请服务号,并获取Access Token才能做添加菜单,上传、下载图片等功能。本文通过代码演示告诉你如何获取Access Token。

    hemeng发布于2014-02-19

     微信公众平台开发文档 获取用户地理位置

    开通上报地理位置接口的公众号,用户在关注后进入公众号会话时,会弹框让用户确认是否允许公众号使用其地理位置。获取用户地理位置的方式有两种,一种是仅在进入会话时上报一次,一种是进入会话后每隔5秒上报一次。公众号可以在公众平台网站中设置。本文将详解该设置过程及代码实现。

    方倍工作室发布于2014-10-21

     微信公共服务平台开发(.Net实现):解决Access Token过期的问题

    Access Token是变化的,正常情况下,它的有效期为7200秒,重复获取将导致上次获取的Access Token失败。而我们可以把获得的Access Token存入一个物理文件或者Application中,请求过期后修改这些内容,需要时读出即可。详情请阅读本文。

    hemeng发布于2014-02-20

     微信公众平台开发 OAuth2.0网页授权认证

    OAuth是一个开放协议,允许用户让第三方应用以安全且标准的方式获取该用户在某一网站、移动或桌面应用上存储的私密的资源,而无需将用户名和密码提供给第三方应用。本文将分享微信公众平台OAuth2.0授权详细步骤。

    Iamduoluo发布于2014-10-22

     微信公众帐号开发教程:自定义菜单的创建及菜单事件响应

    申请了服务号,开发者就可以创建自定义菜单了。本文将详解自定义菜单的创建步骤、创建菜单的难点、解读自定义菜单接口文档、解读API文档之使用限制、响应菜单点击事件等内容。图文并茂,代码展示,是了解自定义菜单的创建及菜单事件响应很好的教程。

    柳峰的专栏发布于2013-08-09

     微信公众平台开发:生成带参数二维码

    为了满足用户渠道推广分析的需要,微信公众平台提供了生成带参数二维码的接口。使用该接口可以获得多个带不同场景值的二维码,用户扫描后,公众号可以接收到事件推送。本文介绍了在微信公众平台上如何使用高级接口开发生成带参数二维码的功能。

    qiuxuemei915发布于2014-11-20

     微信支付:调用微信客户端支付之服务端开发详解

    微信支付是由腾讯微信与财付通联合推出的移动支付产品,旨在为广大微信用户及商户提供优质安全的支付服务。该文章将详解微信支付的开发过程。

    qiuxuemei915发布于2014-11-20

     微信公众号开发环境要求和准备工作

    本文主要介绍利用ASP.NET开发微信公众号相关功能所需提前准备的事项,包括开发所需的服务器软件开发环境;订阅号、服务号及企业号必读帮助文档;在线调试工具等内容。

    fuyifang发布于2014-10-31

     接口接入,正式成为微信开发者

    正式进入微信开发,需要提前准备哪些工作?需要经过怎样的流程才能正式成为微信开发者,本文通过简单明了的语言,对该过程进行了说明。

    qivan发布于2014-02-10

     玩转微信公众平台之搭建新浪SAE服务器

    微信开发前必须首先搭建好服务器,用来存放自己开发的程序文件。本文将介绍如何搭建新浪SAE服务器,及上传自己的代码包。

    star特530发布于2014-05-16

     微信公众号开发之编辑模式使用

    在编辑模式下,可以通过简单的界面编辑,来设置自动回复。服务号还有底部的自定义菜单功能。该模式下无需编程。本博文将带你了解编辑模式,并通过图文展示如何设置自动回复和自定义菜单功能。

    万境绝尘发布于2014-03-06

     微信公众号开发系列之启用开发模式

    微信公众平台分为编辑模式与开发模式两种模式。开发模式主要针对具备开发能力的人使用。开启该模式后,能够使用微信公众平台开放的接口,通过编程方式实现自定义菜单的创建、用户消息的接收/处理/响应。本文将介绍如何启用开发模式。

    fuyifang发布于2014-10-31

     微信公众号开发之图文消息全攻略

    本文主要介绍微信公众帐号开发中图文消息的使用,以及图文消息的几种表现形式。该文将帮助大家清除掉所有对图文消息相关的问题、疑虑和障碍。

    柳峰发布于2013-07-25

     微信公众号开发教程——各种消息的接收与响应

    当用户向公众帐号发消息时,微信服务器会将消息通过POST方式提交给我们在接口配置信息中填写的URL,而我们需要在URL所指向的请求处理类的doPost方法中接收消息、处理消息和响应消息。本文将主要介绍如何接收微信服务器发送的消息并做出响应。

    好人永远平安发布于2013-09-24

     微信开发——自动回复和多客服开发

    自动回复功能,可大幅减少交互时间和客服工作量,在服务号推活动时尤其明显;而多客服则是自动回复的一个超集,如果自动回复处理不了,则要转接给客服。本文将详细分析两个功能的技术实现。

    疾风似月光发布于2015-04-30
    展开全文
  • 发送消息,是指用户公众号向用户发送相应形式的消息。根据微信开发文档,由以下四种形式:被动回复,群发接口,客服消息接口以及模板消息接口。...这一部分较为简单,正式进行微信开发的第一步就是,在公众号中基本

    发送消息,是指用户公众号向用户发送相应形式的消息。根据微信开发文档,由以下四种形式:被动回复,群发接口,客服消息接口以及模板消息接口。本文将基于Java语言以及个人微信测试号,说明被动回复、客服消息接口以及模板消息接口的使用实现,群发接口并未涉及。
    1. 被动回复
    被动回复只能应用于在接收到用户的互动数据之后,才能向用户发送消息。这一部分较为简单,正式进行微信开发的第一步就是,在公众号中基本配置->服务器配置中设置URL(服务器地址)时,这时该URL链接指定的地址就是对应着Java Web下的一个Servlet,配置好对应的Token及相关参数之后,则微信服务器将会将所有的用户与公众号的互动信息都转发到该Servlet,然后开发者根据接收到的用户互动数据,再进行处理。所谓的被动回复,就是在该Servlet中判断接收到你指定的消息时(例如某个字眼),则直接将想要回复的消息打包成官方指定的XML数据格式,写回到输出流中即可。在这里不过过多解释,如下示例代码:

    response.getWriter().write( MessageUtil.MessageToXML(new TextMessage.Builder(fromUserName,toUserName,new Date().getTime(),"最新资讯请查看下方微信菜单栏,谢谢您的关注").build()));

    2.客服消息接口
    客服消息接口,应用于公众号主动向特定用户(必须满足该用户在48小时内与公众号有交互)发送特定格式的消息,应用场景例如:用户在微页面上完成了抽奖,而这时候公众号主动向用户推送中奖信息。所回复的不同消息的格式,参见开发者文档,下面以回复文本消息作为示例,需要注意的是推送的消息data必须满足json格式,请求类型为post。返回的json数据中,若errorcode为0,则代表推送成功。

     //推送中奖消息
            String data = "{"+
                    "\"touser\":\""+openid+"\","+
                    "\"msgtype\":\"text\","+
                    "\"text\":"+
                    "{"+
                    "\"content\":\""+content+"\""+
                    "}"+
                    "}";
            System.out.println(data);
            String reMsg0 = UrlReqUtil.post("https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token="+access_token,data);
            JSONObject jsonObject = JSONObject.fromObject(reMsg0);
            if(0 != (Integer) jsonObject.get("errcode")) throw new RuntimeException("通知用户失败");

    3.模板消息接口
    模板消息接口的使用场景大体与客服消息接口一致,只是不需要证明对象用户“在线”,即48小时内与当前公众号有交互记录,因而应用范围更为广泛。在具有权限的服务号中使用该接口时,需要向系统申请对应模板,并得到模板号,作为调用凭据。在测试号环境下,则需要自定义模板。例如:
    这里写图片描述
    其中模板内容需要严格遵循指定的格式,即在需要调用才填入的变量值的定义方式为:{{xxxx.DATA}},其中“xxxx”为调用时对应的字段名。
    以下是调用代码:jsonData数据部分遵循json数据格式。
    其中touser:为用户在该公众号下的openid
    template_id:为模板id
    对于每个字段,包含两个值,一是value,即填入模板的具体值;二是color,即对应的字体颜色。
    请求方式为post,判断是否成功同样是依据errcode字段,为0则成功。

            //推送模板消息
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
            String jsonData = "{" +
                    "\"touser\":\""+openid+"\"," +
                    "\"template_id\":\"maD2W1yaTvkXmh1dRjXEsMHUc9dDP8Xh1eANP***ig\"," +
                    "\"topcolor\":\"#FF0000\"," +
                    "\"data\":{" +
                    "\"title\":{\"value\":\"恭喜您中奖啦\",\"color\":\"#173177\"}," +
                    "\"nickname\":{\"value\":\""+nickname+"\",\"color\":\"#173177\"}," +
                    "\"prizeLevel\":{\"value\":\""+rewardLevel+"\",\"color\":\"#173177\"}," +
                    "\"prizeContent\":{\"value\":\""+ ConfigParamUtil.PRIZE_CONTENT.split(",")[rewardLevel]+"\",\"color\":\"#173177\"}," +
                    "\"time\":{\"value\":\""+dateFormat.format(new Date())+"\",\"color\":\"#173177\"}," +
                    "\"bonus\":{\"value\":\"10积分\",\"color\":\"#173177\"}}}";
            String reMsg1 = UrlReqUtil.post("https://api.weixin.qq.com/cgi-bin/message/template/send?access_token="+access_token,jsonData);
            JSONObject jsonObject = JSONObject.fromObject(reMsg1);
            if(0 != (Integer) jsonObject.get("errcode")) throw new RuntimeException("通知用户失败");
    展开全文
  • 微信公众平台上自定义菜单的事件推送,文档上说会POST这些个数据 xml> ToUserName>ToUserName> FromUserName>FromUserName> CreateTime>123456789CreateTime> MsgType>MsgType> Event>Event> EventKey>EventKey> ...


    微信公众平台上自定义菜单的事件推送,文档上说会POST这些个数据

    <xml>
    <ToUserName><![CDATA[toUser]]></ToUserName>
    <FromUserName><![CDATA[FromUser]]></FromUserName>
    <CreateTime>123456789</CreateTime>
    <MsgType><![CDATA[event]]></MsgType>
    <Event><![CDATA[EVENT]]></Event>
    <EventKey><![CDATA[EVENTKEY]]></EventKey>
    </xml>
    

    但是我把log打出来看,POST里什么数据都没有

    其实微信把数据 全部放在request中,而不是通过POST的键值对对可以获取的。

    如python django中     print request.read() 得到的就是微信发回来的数据


    展开全文
  • 微信支付的开发,作为微信公众号开发的难点之一,另不少开发者颇为头痛。市面上微信支付开发成本动辄上万,也让刚创业的小公司无力负担。本次文章将详细介绍微信支付中微信原生红包的开发思路,并提供源代码。以供...

    微信支付的开发,作为微信公众号开发的难点之一,另不少开发者颇为头痛。市面上微信支付开发成本动辄上万,也让刚创业的小公司无力负担。本次文章将详细介绍微信支付中微信原生红包的开发思路,并提供源代码。以供各位同好交流。

    开发效果

    如图1所示,微信公众号9五后不害羞(love_thyc)发放红包效果。微信红包分为:普通红包、裂变红包。本次介绍普通红包。

    微信开发五之微信红包开发

    图 1

    开发前准备

    1.已认证的服务号

    2.开通微信支付功能。

    开启“微信支付——产品中心——现金红包”此项功能,如图2所示

    微信开发五之微信红包开发

    图 2

    3.微信支付开发文档:

    https://pay.weixin.qq.com/wiki/doc/api/tools/cash_coupon.php?chapter=13_4&index=3

    开始开发

    1.开发思路:笔者利用mindject整理了程序结构及调用关系。在微信后台“学点编程”(shijiawen6)回复“红包思路”获取红包开发思路图片。

    2.接口:POST方式,带XML参数。

    https://api.mch.weixin.qq.com/mmpaymkttransfers/sendredpack;

    3.参数拆分:因发送红包的参数非常多,如图3所示,逐一介绍。

    微信开发五之微信红包开发

    图 3

    1)nonce_str:随机字符串,用来生成签名。随机字符串签名可以通用,26个字母,10个数字,字符串最长为36。随机字符串程序如下,因为程序较为简单,所以写在redPacketPay.php主程序的类中,用$this->调用。

    微信开发五之微信红包开发

    图 4

    2)sign:签名。签名的获取较为复杂所以并没有在redPacketPay.php中拼装。

    (签名算法:https://pay.weixin.qq.com/wiki/doc/api/tools/cash_coupon.php?chapter=4_3)

    分析签名算法,它可以拆分为:

    a)在支付平台中设置密钥,密钥需保密。

    微信开发五之微信红包开发

    图 5

    b)检查其他参数是否已生产。

    微信开发五之微信红包开发

    图 6

    c)对参数按照 key=value 的格式,并按照参数名 ASCII 字典序排序,并拼接为字符串,如图7所示。其中ksort()函数作用为ASCII 字典序排序;formatQueryParaMap()函数作用为拼接为字符串,如图8所示。

    微信开发五之微信红包开发

    图 7

    微信开发五之微信红包开发

    图 8

    d)用MD5加密算法获得签名,如图9所示。

    微信开发五之微信红包开发

    图 9

    3)mch_billno:订单编号=商户号+YYMMDDHHIISS+RANDOM(1000,9999)把时间补全HHIISS有六位,再来一个随机四位数即可。

    4)mch_id:商户号,注册了支付平台就有的

    5)wxappid:appID

    6)send_name:发送方名称

    7)nick_name:如果做为第三方支付开发方,帮商户开发时候,此字段指开放方(非必须)

    8)re_openid:用户的openid,传参的时候直接用$object->FromUserName

    9)total_amount:付款金额,分为单位,最小为100分,即1元

    10)total_num:发红包总数,普通红包1,裂变红包可以为其他值

    11)wishing:红包祝福语

    12)client_ip:新浪云的ip是动态的,所以要动态获取,获取方式如图10所示。

    微信开发五之微信红包开发

    图 10

    13)act_name:活动信息

    14)remark:备注信息,

    以上参数均为必须,完成参数设置之后,需要将参数拼装为XML数据。

    4.组装XML数组,其方法如图11所示。

    微信开发五之微信红包开发

    图 11

    5.发起POST请求。涉及金钱,所以要使用证书,证书对于每个商户是唯一的,必须妥善保管,方法如图12所示。

    微信开发五之微信红包开发

    图 12

    全文总结

    当执行完POST请求后,即完成发红包动作。微信原生红包的开发其实并不复杂,只是涉及到较多的参数,需要运用较多的方法。建议利用笔者提供的“红包思路”先梳理一下开发的流程,再结合源代码进行开发。

    展开全文
  • 上一篇《微信开发学习总结(一)——微信开发环境搭建》我们已经完成了微信开发的准备工作,准备工作完成之后,就要开始步入正题了。 一、微信公众平台的基本原理  在开始做之前,先简单介绍了微信公众平台的基本...
  • 过年前后做了个微信公众号项目,已经过去一段时间了,抽空回忆总结下基本流程吧,不然很快估计自己就忘了。。 微信公众平台官网:https://mp.weixin.qq.com 文章目录一、注册公众号二、了解公众号管理页面三、必备...
  • 企业微信开发

    2018-05-10 15:19:32
    企业微信的认识企业微信概念:企业微信2016年4月18日,腾讯正式发布全平台企业办公工具“企业微信”。与微信一致的沟通体验,为企业员工提供最基础和最实用的办公服务,并加入贴合办公场景的特色功能、轻OA工具,提供...
  • 微信开发源码注释

    2016-06-11 18:11:55
    本文用于解释微信开发中的中PHP代码意义,用于学习先关基础知识。
  • 进行微信开发,后台程序需要与微信服务器进行交互,通过调用接口来完成服务,阅读微信开发文档,发现接口的调用都是通过http请求进行的,所以必须有个HttpUtil来支撑,这里总结下以javaAPI的方式和以Apach的...
  • 随着微信服务开发在越来越多的领域应用,应用的安全性逐渐被重视起来。本文主要阐述如何为微信的消息加密的原理与Java版本的实现。
  • 所有微信开发的相关内容,都需要参考官方文档。 [微信公众平台|开发文档] http://mp.weixin.qq.com/wiki/home/。 一、通过网页授权,可以获取用户微信的基本信息。 二、总共有5个步骤: 1 :用户同意授权,...
  • CleverCode前一段时间想去接触一下微信开发,申请了一个人订阅号,发现暂不能申请个人认证,而且没有微信接口的很多权限,也没有自定义菜单的权限(开发模式下)。在开发模式下,只能到手公众号里面的回复信息,然后...
  • 微信开发, 经常会用到相同功能操作, 比如向微信请求内容,判断是否是移动端访问… 我们把这些常用的操作, 封装成函数, 当我们需要使用时, 直接调用就可以了。 ...
  • 接触微信公众号接口开发,在进行自行以菜单添加进行POST请求时 出错 无任何返回结果。 用的是curl的请求。最后差错时因为curl的原因 对比代码如下:错误版 无法放问POST 返回错误结果代码为60 对应错误是:无法使用...
  • 在php微信开发文档中,我们使用php来做微信的开发; 首先: 在微信开发者文档中,开始开发->接入指南->目录中有三步骤写的很已经很明确了。 好了。进入正题; 下载demo,php示例; 把Demo放到线上的域名中。 ...
  • 最近的话,发现微信开发其实也有很多挺有意思的地方,比如最近很火的一款游戏“跳一跳”,也让我如此着迷。。但是,今天我所要讲的并不是对于小程序的开发,而是要说一下,关于微信开发的另外一个内容,那就是微信...
  • 关注、接收和发送消息 上一节讲述了配置接口,这次看一下关注、接收和发送消息。 我们先看效果图 在上一次的controller里面加上: @PostMapping(&quot;/wx&quot;... public void doPost(HttpServletRequest ...
  • 微信开发少不了要用到post跟get请求,封装一个函数方便后期使用 function curl_request($url, $data=null, $method='get', $https=true){ $ch = curl_init();//初始化 curl_setopt($ch, CURLOPT_URL, $url);//...
1 2 3 4 5 ... 20
收藏数 38,630
精华内容 15,452
关键字:

post 微信开发