最新研究微信红包接口的问题真是困扰了我好久,因为微信的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,进行设置参数也可以。。。//转换成发送给为微信的参数的xmlSendRedPackBack 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; //公众账号appidprivate String send_name; //商户名称private String re_openid; //用户openidprivate 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; //场景idprivate 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 = "";// 应用IDprivate 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 certsSSLContext sslcontext = SSLContexts.custom().loadKeyMaterial(keyStore, "pamtpamtpamtpamtpamtpamtpamtpamt".toCharArray())//这里也是写密码的 .build();// Allow TLSv1 protocol onlySSLConnectionSocketFactory 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 StringStringBuffer 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; // 公众账号appidprivate String reOpenid; // 用户openidprivate Integer totalAmount; // 付款金额private String sendListid; // 微信单号private String registerId; //注册人idprivate 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.这就是全部过程如果有遗漏大家多多体谅,毕竟这些是我用好长时间整理出来的 希望对你们有帮助 晒几张图片