最新研究微信红包接口的问题真是困扰了我好久,因为微信的api 实在是太坑爹了 ,如果没有大量的测试是行不通的,我是拼凑的所有人的集合才弄明白,接下来跟大家分享一下java 结合jsp ,两个服务器如何实现 微信扫码二维码 然后公众号发放红包的例子。
1.准备工作先不说了(比如验证回调函数服务器域名啊、程序必须部署在80端口等等,开通微信支付等功能,这个微信api 说的很清晰),需要两个程序 ,一个作为微信接口的回掉函数程序用来获取 code(简称服务器A),另一个作为调取发送红包的程序(简称服务器B)。(java 端jar包就不写了直接写方法)
2.首先在A服务器上部署back.html页面 ,然后用生成二维码工具将此页面路径生成二维码,页面自动授权跳转到回第二个页面 getback.html
<!doctype html> <html> <head> <meta http-equiv="content-type" content="txt/html; charset=utf-8"/> <script type="text/javascript" src="jquery-1.8.3.js"></script> <script type="text/javascript"> $(document).ready(function () { window.location.href ="https://open.weixin.qq.com/connect/oauth2/authorize?appid=微信公众号的appid&redirect_uri=回调函数页面路劲(我的是getback.html)&response_type=code&scope=snsapi_userinfo&state=STATE&connect_redirect=1#wechat_redirect" }); </script> <style> </style> </head> <body> </body> </html>
接下来是 getback.html 代码
1 <!doctype html> 2 <html> 3 <head> 4 <meta http-equiv="content-type" content="txt/html; charset=utf-8"/> 5 6 <script type="text/javascript" src="jquery-1.8.3.js"></script> 7 <script type="text/javascript"> 8 $(document).ready(function () { 9 10 var code = getQueryString(\'code\'); 11 12 13 if (code != null) { 14 15 window.location.href="B服务器路径的controller方法上?code="+code; 16 17 } 18 }); 19 20 21 function getQueryString(name) { 22 var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i"); 23 var r = window.location.search.substr(1).match(reg); 24 if (r != null) return unescape(r[2]); 25 return null; 26 27 } 28 </script> 29 <style> 30 31 </style> 32 </head> 33 <body> 34 35 </body> 36 </html>
这个页面难点在于获取code,终于要说的微信最坑的地方了 就是获取的code 是在回调路径中隐藏的,api根本就没有写,我是通过截取的方法获取路径发送给B服务器的。
3.controller 我就不写了,我就写通过取回来的code如何获取openid的方法吧 java端个
public String getOpenId(String code) { String openid = ""; String uri="https://api.weixin.qq.com/sns/oauth2/access_token"; String requestEntity = "appid=" + 你的appid + "&secret=" + 你的秘钥 + "&code=" + code + "&grant_type=" + 你的grant_type; HttpUriRequest httpUriRequest = RequestBuilder.post() .setUri(uri) .setHeader("Content-Type", "application/x-www-form-urlencoded") .addParameter("_type", "json") .setEntity(new StringEntity(requestEntity, Charset.forName("utf-8"))) .build(); HttpResponse httpResponse = LocalHttpClient.execute(httpUriRequest); try { String result = EntityUtils.toString(httpResponse.getEntity()); JSONObject jsonObject = JSONObject.fromObject(result); openid = jsonObject.getString("openid"); System.out.println(openid); } catch (IOException e) { e.printStackTrace(); } return openid; };
获取到openid就离成功不远了。
4.通过openid发送红包(不要看我的返回值redenvelope具体需求具体分析)
public String sendRedEnvelopes(String openId,String id) throws Exception { String redenvelope=""; //具体参数查看具体实体类,实体类中的的参数参考微信的红包发放接口,这里你直接用map,进行设置参数也可以。。。 //转换成发送给为微信的参数的xml SendRedPackBack sendRedPackBack=new SendRedPackBack(); sendRedPackBack.setNonce_str(MoneyUtils.buildRandom()); sendRedPackBack.setMch_billno(MoneyUtils.getOrderNo()); sendRedPackBack.setMch_id(参数实体里有我就不举例子了); sendRedPackBack.setWxappid(); sendRedPackBack.setSend_name(); sendRedPackBack.setRe_openid(openId); sendRedPackBack.setTotal_amount(); sendRedPackBack.setTotal_num(); sendRedPackBack.setWishing(); sendRedPackBack.setClient_ip(); sendRedPackBack.setAct_name(); //将实体类转换为url形式 String urlParamsByMap = Tool.getUrlParamsByMap(Tool.toMap(sendRedPackBack)); //拼接我们再前期准备好的API密钥,前期准备第5条 urlParamsByMap += "&key="+证书秘钥; //进行签名,需要说明的是,如果内容包含中文的话,要使用utf-8进行md5签名,不然会签名错误 String sign = Tool.parseStrToMd5L32(urlParamsByMap).toUpperCase(); sendRedPackBack.setSign(sign); //微信要求按照参数名ASCII字典序排序,这里巧用treeMap进行字典排序 TreeMap treeMap = new TreeMap(Tool.toMap(sendRedPackBack)); //然后转换成xml格式 String soapRequestData = Tool.getSoapRequestData(treeMap); //发起请求前准备 RequestBody body = RequestBody.create(MediaType.parse("text/xml;charset=UTF-8"), soapRequestData); Request request = new Request.Builder() .url("https://api.mch.weixin.qq.com/mmpaymkttransfers/sendredpack") .post(body) .build(); //为http请求设置证书 SSLSocketFactory socketFactory = getSSL().getSocketFactory(); X509TrustManager x509TrustManager = Platform.get().trustManager(socketFactory); OkHttpClient okHttpClient = new OkHttpClient.Builder().sslSocketFactory(socketFactory, x509TrustManager).build(); //得到输出内容 Response response = okHttpClient.newCall(request).execute(); String content = response.body().string(); System.out.println(content); //解析返回数据 RedDevelop redDevelop= xmlBean(content,id); if(redDevelop.getReturnCode().equals("SUCCESS")){ if(redDevelop.getResultCode().equals("SUCCESS")){ redenvelope= String.valueOf(redDevelop.getTotalAmount()/100); //保存红包已经被领取 newUseRegisterService.setRedPack(id); }else { redenvelope="fail";//接口调取成功但是获取openid失败 } }else { redenvelope="fail";//接口调取失败 } return redenvelope; } public SSLContext getSSL() throws KeyStoreException, IOException, CertificateException, NoSuchAlgorithmException, UnrecoverableKeyException, KeyManagementException { KeyStore keyStore = KeyStore.getInstance("PKCS12"); String mchId=你的微信商户id; //证书位置自己定义 FileInputStream instream = new FileInputStream(new File(证书路径)); try { keyStore.load(instream, mchId.toCharArray()); } finally { instream.close(); } SSLContext sslcontext = SSLContexts.custom() .loadKeyMaterial(keyStore, mchId.toCharArray()) .build(); return sslcontext; } //这部分是将调取成功后的xml返回值转成实体继续保存,实体就不提供了 public RedDevelop xmlBean(String content,String id){ RedDevelop redDevelop=new RedDevelop(); Document dom= null; try { dom = DocumentHelper.parseText(content); } catch (DocumentException e) { e.printStackTrace(); } Element root=dom.getRootElement(); String returnCode=root.element("return_code").getText(); String returnMsg=root.element("return_msg").getText(); String resultCode=root.element("result_code").getText(); String errCode=root.element("err_code").getText(); String errCodeDes=root.element("err_code_des").getText(); String mchBillno=root.element("mch_billno").getText(); String mchId=root.element("mch_id").getText(); String wxappid=root.element("wxappid").getText(); String reOpenid=root.element("re_openid").getText(); String totalAmount=root.element("total_amount").getText(); redDevelop.setReturnCode(returnCode); redDevelop.setReturnMsg(returnMsg); redDevelop.setResultCode(resultCode); redDevelop.setErrCode(errCode); redDevelop.setErrCodeDes(errCodeDes); redDevelop.setMchBillno(mchBillno); redDevelop.setMchId(mchId); redDevelop.setWxappid(wxappid); redDevelop.setReOpenid(reOpenid); redDevelop.setTotalAmount(Integer.valueOf(totalAmount)); redDevelop.setRegisterId(id); redDevelopService.save(redDevelop); return redDevelop; }
实体类:
package com.sgepm.modules.marketing.entity; import com.sgepm.common.persistence.DataEntity; /** * Created by zxw on 2018-7-27 */ public class SendRedPackBack { private String nonce_str; //随机字符串 private String sign; //签名 private String mch_billno;//商户订单号 private String mch_id; //商户号 private String mchId; //商户号 private String wxappid; //公众账号appid private String send_name; //商户名称 private String re_openid; //用户openid private Integer total_amount; //付款金额 单位分 private Integer total_num; //付款人数 private String wishing; //红包祝福语 private String client_ip; //调用接口的机器Ip地址 private String act_name; //活动名称 private String remark; //备注 private String scene_id; //场景id private String risk_info; //活动信息 private String consume_mch_id; //资金授权商户号 public SendRedPackBack() { } public SendRedPackBack(String nonce_str, String mch_billno, String mch_id, String wxappid, String send_name, String re_openid, Integer total_amount, Integer total_num, String wishing, String client_ip, String act_name) { this.nonce_str = nonce_str; this.mch_billno = mch_billno; this.mch_id = mch_id; this.wxappid = wxappid; this.send_name = send_name; this.re_openid = re_openid; this.total_amount = total_amount; this.total_num = total_num; this.wishing = wishing; this.client_ip = client_ip; this.act_name = act_name; } public String getNonce_str() { return nonce_str; } public void setNonce_str(String nonce_str) { this.nonce_str = nonce_str; } public String getSign() { return sign; } public void setSign(String sign) { this.sign = sign; } public String getMch_billno() { return mch_billno; } public void setMch_billno(String mch_billno) { this.mch_billno = mch_billno; } public String getMch_id() { return mch_id; } public void setMch_id(String mch_id) { this.mch_id = mch_id; } public String getWxappid() { return wxappid; } public void setWxappid(String wxappid) { this.wxappid = wxappid; } public String getSend_name() { return send_name; } public void setSend_name(String send_name) { this.send_name = send_name; } public String getRe_openid() { return re_openid; } public void setRe_openid(String re_openid) { this.re_openid = re_openid; } public Integer getTotal_amount() { return total_amount; } public void setTotal_amount(Integer total_amount) { this.total_amount = total_amount; } public Integer getTotal_num() { return total_num; } public void setTotal_num(Integer total_num) { this.total_num = total_num; } public String getWishing() { return wishing; } public void setWishing(String wishing) { this.wishing = wishing; } public String getClient_ip() { return client_ip; } public void setClient_ip(String client_ip) { this.client_ip = client_ip; } public String getAct_name() { return act_name; } public void setAct_name(String act_name) { this.act_name = act_name; } public String getRemark() { return remark; } public void setRemark(String remark) { this.remark = remark; } public String getScene_id() { return scene_id; } public void setScene_id(String scene_id) { this.scene_id = scene_id; } public String getRisk_info() { return risk_info; } public void setRisk_info(String risk_info) { this.risk_info = risk_info; } public String getConsume_mch_id() { return consume_mch_id; } public void setConsume_mch_id(String consume_mch_id) { this.consume_mch_id = consume_mch_id; } public String getMchId() { return mchId; } public void setMchId(String mchId) { this.mchId = mchId; } }
工具类:
package com.sgepm.common.utils.weixin; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.Reader; import java.nio.charset.Charset; import java.security.KeyStore; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Iterator; import java.util.Map; import java.util.Random; import java.util.Set; import java.util.SortedMap; import java.util.TreeMap; import javax.net.ssl.SSLContext; import javax.servlet.http.HttpServletRequest; import org.apache.commons.lang3.StringUtils; import org.apache.http.HttpEntity; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpPost; import org.apache.http.conn.ssl.SSLConnectionSocketFactory; import org.apache.http.conn.ssl.SSLContexts; import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.protocol.HTTP; import org.apache.http.util.Args; import org.apache.http.util.CharArrayBuffer; import org.apache.http.util.EntityUtils; public class MoneyUtils { private static String appid = "";// 应用ID private static String appsecret = "";// 应用密钥 private static String partner = "";// 微信支付商户号 private static String partnerkey = "";// 财付通初始密�? private static String charset = ""; /** * 随机16为数值 * * @return */ public static String buildRandom() { String currTime = TenpayUtil.getCurrTime(); String strTime = currTime.substring(8, currTime.length()); int num = 1; double random = Math.random(); if (random < 0.1) { random = random + 0.1; } for (int i = 0; i < 4; i++) { num = num * 10; } return (int) ((random * num)) + strTime; } /** * 获取ip * * @param request * @return */ public static String getIpAddr(HttpServletRequest request) { String ip = request.getHeader("x-forwarded-for"); if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("PRoxy-Client-IP"); } if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("WL-Proxy-Client-IP"); } if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getRemoteAddr(); } if (null == ip) { ip = ""; } if (StringUtils.isNotEmpty(ip)) { String[] ipArr = ip.split(","); if (ipArr.length > 1) { ip = ipArr[0]; } } return ip; } /** * 创建md5摘要,规则是:按参数名称a-z排序,遇到空值的参数不参加签名。 sign */ public static String createSign(Map<String, Object> map) { SortedMap<String, String> packageParams = new TreeMap<String, String>(); for (Map.Entry<String, Object> m : map.entrySet()) { packageParams.put(m.getKey(), m.getValue().toString()); } StringBuffer sb = new StringBuffer(); Set<?> es = packageParams.entrySet(); Iterator<?> it = es.iterator(); while (it.hasNext()) { Map.Entry entry = (Map.Entry) it.next(); String k = (String) entry.getKey(); String v = (String) entry.getValue(); if (!StringUtils.isEmpty(v) && !"sign".equals(k) && !"key".equals(k)) { sb.append(k + "=" + v + "&"); } } sb.append("key=" + partnerkey); String sign = MD5Util.MD5Encode(sb.toString(), charset).toUpperCase(); return sign; } public static String getOrderNo() { String order = partner + new SimpleDateFormat("yyyyMMdd").format(new Date()); Random r = new Random(); for (int i = 0; i < 10; i++) { order += r.nextInt(9); } return order; } /* * public static void main(String[] args) { * System.out.println(getOrderNo()); } */ final static String KEYSTORE_FILE = "D:/works/cert/apiclient_cert.p12"; // final static String KEYSTORE_PASSWORD = "CDATA[签名错误"; public static String doSendMoney(String url, String data) throws Exception { KeyStore keyStore = KeyStore.getInstance("PKCS12"); FileInputStream instream = new FileInputStream(new File(KEYSTORE_FILE));//P12文件目录 // InputStream instream = MoneyUtils.class.getResourceAsStream("/apiclient_cert.p12"); try { keyStore.load(instream, "pamtpamtpamtpamtpamtpamtpamtpamt".toCharArray());//这里写密码..默认是你的MCHID } finally { instream.close(); } // Trust own CA and all self-signed certs SSLContext sslcontext = SSLContexts.custom() .loadKeyMaterial(keyStore, "pamtpamtpamtpamtpamtpamtpamtpamt".toCharArray())//这里也是写密码的 .build(); // Allow TLSv1 protocol only SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext, new String[] { "TLSv1" }, null, SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER); CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).build(); try { HttpPost httpost = new HttpPost(url); // 设置响应头信息 httpost.addHeader("Connection", "keep-alive"); httpost.addHeader("Accept", "*/*"); httpost.addHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8"); httpost.addHeader("Host", "api.mch.weixin.qq.com"); httpost.addHeader("X-Requested-With", "XMLHttpRequest"); httpost.addHeader("Cache-Control", "max-age=0"); httpost.addHeader("User-Agent", "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0) "); httpost.setEntity(new StringEntity(data, "UTF-8")); CloseableHttpResponse response = httpclient.execute(httpost); try { HttpEntity entity = response.getEntity(); String jsonStr = toStringInfo(response.getEntity(),"UTF-8"); //微信返回的报文时GBK,直接使用httpcore解析乱码 // String jsonStr = EntityUtils.toString(response.getEntity(),"UTF-8"); EntityUtils.consume(entity); return jsonStr; } finally { response.close(); } } finally { httpclient.close(); } } private static String toStringInfo(HttpEntity entity, String defaultCharset) throws Exception, IOException{ final InputStream instream = entity.getContent(); if (instream == null) { return null; } try { Args.check(entity.getContentLength() <= Integer.MAX_VALUE, "HTTP entity too large to be buffered in memory"); int i = (int)entity.getContentLength(); if (i < 0) { i = 4096; } Charset charset = null; if (charset == null) { charset = Charset.forName(defaultCharset); } if (charset == null) { charset = HTTP.DEF_CONTENT_CHARSET; } final Reader reader = new InputStreamReader(instream, charset); final CharArrayBuffer buffer = new CharArrayBuffer(i); final char[] tmp = new char[1024]; int l; while((l = reader.read(tmp)) != -1) { buffer.append(tmp, 0, l); } return buffer.toString(); } finally { instream.close(); } } public static String createXML(Map<String, Object> map){ String xml = "<xml>"; Set<String> set = map.keySet(); Iterator<String> i = set.iterator(); while(i.hasNext()){ String str = i.next(); xml+="<"+str+">"+"<![CDATA["+map.get(str)+"]]>"+"</"+str+">"; } xml+="</xml>"; return xml; } }
package com.sgepm.common.utils.weixin; import org.apache.commons.lang3.RandomUtils; import org.apache.commons.lang3.StringUtils; import org.json.JSONException; import java.beans.BeanInfo; import java.beans.IntrospectionException; import java.beans.Introspector; import java.beans.PropertyDescriptor; import java.io.UnsupportedEncodingException; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.HashMap; import java.util.Map; import java.util.TreeMap; import java.util.UUID; /** * Created by on 2016/9/6. */ public class Tool { /** * 获取订单号 * @return */ public static String getOrderNum(){ return String.valueOf(System.currentTimeMillis())+getRandom4(); } /** * 获取一个4位随机数 * @return */ public static int getRandom4(){ int x = RandomUtils.nextInt(1000,9999); return x; } /** * 获取UUID * @return */ public static String returnUUID() { return parseStrToMd5L32(UUID.randomUUID().toString()); } /** * 获取md5 * @param str * @return */ public static String parseStrToMd5L32(String str) { return parseStrToMd5L32(str,"utf-8"); } public static String parseStrToMd5L32(String str, String charset) { String reStr = null; try { MessageDigest md5 = MessageDigest.getInstance("MD5"); byte[] bytes = md5.digest(str.getBytes(charset)); StringBuffer stringBuffer = new StringBuffer(); for (byte b : bytes) { int bt = b & 0xff; if (bt < 16) { stringBuffer.append(0); } stringBuffer.append(Integer.toHexString(bt)); } reStr = stringBuffer.toString(); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } return reStr; } /** * 将map转换成url * @param map * @return */ public static String getUrlParamsByMap(Map<String, String> map) { if (map == null) { return ""; } StringBuffer sb = new StringBuffer(); map = new TreeMap<String, String>(map); for (Map.Entry<String, String> entry : map.entrySet()) { if(entry.getValue() == null){ continue; } sb.append(entry.getKey() + "=" + entry.getValue()); sb.append("&"); } String s = sb.toString(); if (s.endsWith("&")) { s = StringUtils.substringBeforeLast(s, "&"); } return s; } /** * Sha1加密方法 */ public static String getSha1(String decript) { try { MessageDigest digest = MessageDigest .getInstance("SHA-1"); digest.update(decript.getBytes()); byte messageDigest[] = digest.digest(); // Create Hex String StringBuffer hexString = new StringBuffer(); // 字节数组转换为 十六进制 数 for (int i = 0; i < messageDigest.length; i++) { String shaHex = Integer.toHexString(messageDigest[i] & 0xFF); if (shaHex.length() < 2) { hexString.append(0); } hexString.append(shaHex); } return hexString.toString(); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } return ""; } public static Map toMap(Object bean) { Class<? extends Object> clazz = bean.getClass(); Map<Object, Object> returnMap = new HashMap<Object, Object>(); BeanInfo beanInfo = null; try { beanInfo = Introspector.getBeanInfo(clazz); PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors(); for (int i = 0; i < propertyDescriptors.length; i++) { PropertyDescriptor descriptor = propertyDescriptors[i]; String propertyName = descriptor.getName(); if (!propertyName.equals("class")) { Method readMethod = descriptor.getReadMethod(); Object result = null; result = readMethod.invoke(bean, new Object[0]); if (null != propertyName) { propertyName = propertyName.toString(); } if (null != result) { result = result.toString(); returnMap.put(propertyName, result); } } } } catch (IntrospectionException e) { System.out.println("分析类属性失败"); } catch (IllegalAccessException e) { System.out.println("实例化 JavaBean 失败"); } catch (IllegalArgumentException e) { System.out.println("映射错误"); } catch (InvocationTargetException e) { System.out.println("调用属性的 setter 方法失败"); } return returnMap; } /** * 凑成xml格式字符串 * * @return */ public static String getSoapRequestData(Map<String, String> map) throws JSONException { StringBuffer sb = new StringBuffer(); sb.append("<xml>"); for (Map.Entry<String, String> entry : map.entrySet()) { sb.append("<" + entry.getKey() + ">" + entry.getValue() + "</" + entry.getKey() + ">"); } sb.append("</xml>"); return sb.toString(); } }
接口返回类:
package com.sgepm.modules.marketing.entity; import org.hibernate.validator.constraints.Length; import com.sgepm.modules.sys.entity.Office; import com.sgepm.common.persistence.DataEntity; /** * 红包管理Entity * @author zxw * @version 2018-08-02 */ public class RedDevelop extends DataEntity<RedDevelop> { private static final long serialVersionUID = 1L; private String returnCode; // 返回状态码 private String returnMsg; // 返回信息 private String resultCode; // 业务结果 private String errCode; // 错误代码 private String errCodeDes; // 错误代码描述 private String mchBillno; // 商户订单号 private String mchId; // 商户号 private String wxappid; // 公众账号appid private String reOpenid; // 用户openid private Integer totalAmount; // 付款金额 private String sendListid; // 微信单号 private String registerId; //注册人id private Office office; // 归属机构 public RedDevelop() { super(); } public RedDevelop(String id){ super(id); } @Length(min=0, max=16, message="返回状态码长度必须介于 0 和 16 之间") public String getReturnCode() { return returnCode; } public void setReturnCode(String returnCode) { this.returnCode = returnCode; } @Length(min=0, max=128, message="返回信息长度必须介于 0 和 128 之间") public String getReturnMsg() { return returnMsg; } public void setReturnMsg(String returnMsg) { this.returnMsg = returnMsg; } @Length(min=0, max=16, message="业务结果长度必须介于 0 和 16 之间") public String getResultCode() { return resultCode; } public void setResultCode(String resultCode) { this.resultCode = resultCode; } @Length(min=0, max=32, message="错误代码长度必须介于 0 和 32 之间") public String getErrCode() { return errCode; } public void setErrCode(String errCode) { this.errCode = errCode; } @Length(min=0, max=128, message="错误代码描述长度必须介于 0 和 128 之间") public String getErrCodeDes() { return errCodeDes; } public void setErrCodeDes(String errCodeDes) { this.errCodeDes = errCodeDes; } @Length(min=0, max=28, message="商户订单号长度必须介于 0 和 28 之间") public String getMchBillno() { return mchBillno; } public void setMchBillno(String mchBillno) { this.mchBillno = mchBillno; } @Length(min=0, max=32, message="商户号长度必须介于 0 和 32 之间") public String getMchId() { return mchId; } public void setMchId(String mchId) { this.mchId = mchId; } @Length(min=0, max=32, message="公众账号appid长度必须介于 0 和 32 之间") public String getWxappid() { return wxappid; } public void setWxappid(String wxappid) { this.wxappid = wxappid; } @Length(min=0, max=32, message="用户openid长度必须介于 0 和 32 之间") public String getReOpenid() { return reOpenid; } public void setReOpenid(String reOpenid) { this.reOpenid = reOpenid; } public Integer getTotalAmount() { return totalAmount; } public void setTotalAmount(Integer totalAmount) { this.totalAmount = totalAmount; } @Length(min=0, max=32, message="微信单号长度必须介于 0 和 32 之间") public String getSendListid() { return sendListid; } public void setSendListid(String sendListid) { this.sendListid = sendListid; } public Office getOffice() { return office; } public void setOffice(Office office) { this.office = office; } public String getRegisterId() { return registerId; } public void setRegisterId(String registerId) { this.registerId = registerId; } }
6.这就是全部过程如果有遗漏大家多多体谅,毕竟这些是我用好长时间整理出来的 希望对你们有帮助 晒几张图片