java对接微信支付
对接微信扫码支付(模式2),前端使用velocity技术
(1)调用微信支付接口(view层) 此部分业务逻辑部分可以省略
@RequestMapping("/wxpay.htm")
public ModelAndView wxpay(HttpServletRequest request,HttpServletResponse response, String id, String type,
String payment_id)
{
ModelAndView mv = new JModelAndView("wxpay.html",
configService.getSysConfig(),
this.userConfigService.getUserConfig(), 1, request,
response);
/*处理业务逻辑开始,如获取当前订单单号,充值单号,积分兑换单号,获取当前价格
此处为自定义部分
*/
OrderForm of = null;
Predeposit obj = null;
GoldRecord gold = null;
IntegralGoodsOrder ig_order = null;
String redirect =null;
String msg ="返回订单列表";
if (type.equals("goods") || type.equals("group")) {
of = this.orderFormService.getObjById(CommUtil.null2Long(id));
}
if (type.equals("cash")) {
obj = this.predepositService.getObjById(CommUtil.null2Long(id));
}
if (type.equals("gold")) {
gold = this.goldRecordService.getObjById(CommUtil.null2Long(id));
}
if (type.equals("integral")) {
ig_order = this.integralGoodsOrderService.getObjById(CommUtil
.null2Long(id));
}
// 获取提交的商品价格
String order_price = "";
if (type.equals("goods") ) {
double order_total_price = 0d;
//order_price = CommUtil.null2String(of.getTotalPrice());
if (of != null ) {
if(of.getLiuCheng()==0){ ////普通实物订单 TotalPrice已经包含运费
order_total_price = CommUtil.null2Double(of
.getTotalPrice());
if (!CommUtil.null2String(of.getChild_order_detail())
.equals("")) {
List<Map> maps = this.orderFormTools
.queryGoodsInfo(of.getChild_order_detail());
for (Map map : maps) {
OrderForm child_order = this.orderFormService
.getObjById(CommUtil.null2Long(map
.get("order_id")));
if(child_order.getOrder_status()==10){ //这里判断如果是主订单的话,就会和次订单一块结算,但是如果次订单结算了,就不在添加使用。
order_total_price = order_total_price
+ CommUtil.null2Double(child_order
.getTotalPrice());
}
}
}
redirect = "/buyer/order.htm";
}else if(of.getLiuCheng()==1){ ///预售订单这里只支付定金
if(of.getOrder_status() == 10){
order_total_price = CommUtil.null2Double(of.getDingJin_price());
mv.addObject("level", "1");
}else if(of.getOrder_status() == 18){
order_total_price = CommUtil.add(CommUtil.null2Double(of.getWeiKuan_price()), of.getShip_price());
mv.addObject("level", "2");
}
redirect = "/buyer/yuShouOrder.htm";
}
} order_price = CommUtil.null2String(order_total_price) ;
}
//微信扫码后暂不支持自动跳转,根据订单不同,在支付二维码下提示返回不同的列表
if (type.equals("group")) {
//Map queryGroupInfo = this.orderFormTools.queryGroupInfo(of.getGroup_info());
redirect = "/buyer/group.htm";
order_price = CommUtil.null2String(of.getTotalPrice());
}
if (type.equals("cash")) {
redirect = "/buyer/predeposit_list.htm";
msg = "返回充值列表";
order_price = CommUtil.null2String(obj.getPd_amount());
}
if (type.equals("gold")) {
redirect = "/seller/gold_record_list.htm";
msg = "返回金币日志";
order_price = CommUtil.null2String(gold.getGold_money());
}
if (type.equals("integral")) {
redirect = "/buyer/integral_order_list.htm";
order_price = CommUtil.null2String(ig_order.getIgo_trans_fee());
}
mv.addObject("redirect", redirect);
mv.addObject("msg", msg);
// 获取提交的商品名称
String product_name = "";
if (type.equals("goods") || type.equals("group")) {
product_name = of.getOrder_id();
}
if (type.equals("cash")) {
product_name = obj.getPd_sn();
}
if (type.equals("gold")) {
product_name = gold.getGold_sn();
}
if (type.equals("integral")) {
product_name = ig_order.getIgo_order_sn();
}
//自定義的參數
String attach = "";
if (type.equals("goods") || type.equals("group")) {
attach = type + "," + of.getId().toString();
}
if (type.equals("cash")) {
attach = type + "," + obj.getId().toString();
}
if (type.equals("gold")) {
attach = type + "," + gold.getId().toString();
}
if (type.equals("integral")) {
attach = type + "," + ig_order.getId().toString();
}
String desc = "商品:" + product_name;
// 获取提交的订单号
String out_trade_no = "";
if (type.equals("goods") || type.equals("group")) {
out_trade_no = of.getOrder_id();
}
if (type.endsWith("cash")) {
out_trade_no = obj.getPd_sn();
}
if (type.endsWith("gold")) {
out_trade_no = gold.getGold_sn();
}
if (type.equals("integral")) {
out_trade_no = ig_order.getIgo_order_sn();
}
/* OrderForm order = this.orderFormService.getObjById(CommUtil
.null2Long(orderid));*/ //double order_total_price = 0d; mv.addObject("order_total_price", order_price);
/*
处理业务逻辑结束 ---------- **/
//获取预支付信息
Map<String,Object> token = null;
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+request.getContextPath();
String notify= basePath + "/wxBuyerNotify.htm?attach="+attach; //微信支付回调地址,付款成功后调用该地址
Money para = new Money(); //将订单编号和订单金额封装到实体中(Money)
para.setId(product_name);
// para.setCash(new BigDecimal(order_total_price));
para.setCash(new BigDecimal(0.01)); //测试使用,不获取实际订单金额
mv.addObject("type", type);
mv.addObject("id", id);
try
{
token = wxPayService.getPrepayKey(para,notify); //调用微信API,生成页面二维码信息
String barCode = (String)token.get("codeUrl");
mv.addObject("barCode", barCode);
}
catch(Exception e)
{
mv = new JModelAndView("error.html", configService.getSysConfig(),
this.userConfigService.getUserConfig(), 1, request,
response);
mv.addObject("op_title", "参数错误,付款失败");
mv.addObject("url", CommUtil.getURL(request) + "/index.htm");
} return mv;
}
(2)view层用到的 实体,接口和工具类
<1>实体类:Money
public class Money implements Serializable {
/**
* 主键编号
*/
private String id; /**
* 用户编号
*/
private String userId; /**
* 支付金额
*/
private BigDecimal cash; /**
* 手机号码
*/
private String phone; /**
* 支付方式:1支付宝,2微信,3银联,4余额
*/
private String type;
<2>微信支付接口:IWxPayService
public interface IWxPayService { /**
* 获取微信支付链接
* @param record
* @param path
* @param ds
* @return
* @throws Exception
*/
Map<String,Object> getPrepayKey(Money record,String path)throws Exception; /**
* 微信支付成功回调
* @param request
* @return
*/
int updateWxPay(HttpServletRequest request); /**
* 形成支付订单信息
* @param para
* @return
*/
PayOrder insertOrder(Money para); /**
* 用户余额支付
* @param order
* @param user
* @return
*/
int updateStorePay(PayOrder order, User user); /**
* 形成支付宝支付信息
* @param id
* @param string
* @param user_id
* @param basePath
* @return
*/
String createAlipay(Long id, String cash, long user_id, String basePath); /**
* 支付宝支付回调
* @param orderid
* @param fee
* @param storeId
* @return
*/
int updateAliPay(String orderid, String fee, String storeId); /**
* 形成银联支付信息
* @param para
* @return
*/
String packPay(Money para,PayOrder order); /**
* 银联支付回调
* @param request
* @return
*/
int unionNotfy(HttpServletRequest request);
}
<3>实现类:WxPayServiceImpl
@Service
@Transactional
public class WxPayServiceImpl implements IWxPayService
{
/**
* 获取packageValue
* @param response
* @param request
* @param orderCode String 用户编号
* @param ds boolean 是否打赏
* @return
*/
@Override
public Map<String,Object> getPrepayKey(Money record,String path)
throws Exception
{
Pay pay = new Pay(); //此处为微信支付返回的参数,封装为实体(Pay)
String orderCode = record.getId();
if(StringUtils.isBlank(orderCode))
{
return null;
}
orderCode = orderCode.trim(); BigDecimal money = record.getCash();
if(money == null)
{
return null;
}
packRecharge(orderCode,pay,money,path);
packSign(pay);//形成签名
return packToMap(pay,true);
}
private void packRecharge(String ucode,Pay pay,BigDecimal money,String notify)
{ float cash = money.floatValue();
int total = (int)(cash * 100);
String orderCode = ucode.trim();
String prekey = doInBackground(orderCode.trim(),total,pay,notify);
pay.setPrepayid(prekey);
}
/**
* 形成调起支付的签名
* @param pay Pay
*/
private void packSign(Pay pay)
{
//将数据封装到map中
if(pay == null)
{
return;
}
Map<String,Object> map = packToMap(pay,false);
if(map != null)
{
String sign = WXPayDataUtils.genPackageSign(map);
pay.setSign(sign);
}
}
/**
* 请求微信后台获取预支付单号
* @param ucode String
* @param total int
* @return
*/
private String doInBackground(String ucode,int total,Pay pay,String notify) { String entity = WXPayDataUtils.genProductArgs(ucode,total,pay,notify);
Map<String,String> map =WXPayDataUtils.sendPost(WXPayDataUtils.WX_VERIFY_URL, entity);
pay.setCodeUrl(map.get("code_url"));
String id = map.get("prepay_id");
return id;
} private Map<String,Object> packToMap(Pay pay,boolean flag)
{
if(pay == null)
{
return null;
}
Map<String,Object> param = new HashMap<String,Object>();
if(pay.getAppid() != null)
{
param.put("appid", pay.getAppid().trim());
}
if(pay.getPartnerid() != null)
{
param.put("partnerid", pay.getPartnerid().trim());
}
if(pay.getPrepayid() != null)
{
param.put("prepayid", pay.getPrepayid().trim());
}
if(pay.getPack() != null)
{
param.put("package", pay.getPack().trim());
}
if(pay.getNoncestr() != null)
{
param.put("noncestr", pay.getNoncestr().trim());
}
if(pay.getTimestamp() != null)
{
param.put("timestamp", pay.getTimestamp().trim());
}
if(pay.getSign() != null && flag)
{
param.put("sign", pay.getSign());
}
if(pay.getAppkey() != null && flag)
{
param.put("appkey", pay.getAppkey());
}
if(pay.getCodeUrl() !=null && flag)
{
param.put("codeUrl",pay.getCodeUrl());
}
return param;
}
}
<4>实体:Pay
public class Pay { private String appid;
private String appkey;
private String noncestr;
private String pack;
private String partnerid;
private String prepayid;
private String timestamp;
private String sign;
private String codeUrl;
.
.
.
}
<5>微信支付工具类:WXPayDataUtils
package com.sanmi.wx.util; import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;
import java.util.TreeSet; import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.params.ClientPNames;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder; import com.sanmi.wx.client.HttpClientConnectionManager;
import com.sdsanmi.core.domain.Pay; /**
* 微信支付数据
* @author Admin
*
*/
public class WXPayDataUtils {
private static final Log logger = LogFactory.getLog(WXPayDataUtils.class); public static final String APPID = "***********";//微信分配的公众账号ID
public static final String MCH_ID = "********";//微信支付分配的商户号
public static final String API_KEY="as4d4s41a4s4789a5w4********";//商户号对应的密钥
public static final String APP_SECRET = "c1634fe990550b96********";//应用对应的凭证
public static final String BODY = "东地美商城";//商品或支付单简要描述
public static final String NOTIFY_URL = "http://121.40.35.3/test";//接收微信支付异步通知回调地址
public static final String TRADE_TYPE = "NATIVE";//交易类型
public static final String WX_VERIFY_URL = "https://api.mch.weixin.qq.com/pay/unifiedorder";//微信统一下单请求url
public static final String WX_CLOSE_ORDER = "https://api.mch.weixin.qq.com/pay/closeorder";//关闭订单接口
public static final String WX_ORDER_QUERY = "https://api.mch.weixin.qq.com/pay/orderquery";//查询订单接口 public static DefaultHttpClient httpclient; static
{
httpclient = new DefaultHttpClient();
httpclient = (DefaultHttpClient)HttpClientConnectionManager.getSSLInstance(httpclient);
} /**
* 拼接要传递的参数
* @param order
* @return
*/
public static String genProductArgs(String order,int cash,Pay pay,String notify) { SortedMap<String, Object> map = new TreeMap<String, Object>();
String appid = APPID;//微信分配的公众账号ID
String mch_id= MCH_ID;//微信支付分配的商户号
String nonce_str = getRandomString(18);//随机字符串
String body = BODY; String out_trade_no = order;//商户订单号
String total_fee = String.valueOf(cash);//订单总金额,单位为分
String spbill_create_ip = "127.0.0.1";//APP和网页支付提交用户端ip,Native支付填调用微信支付API的机器IP,暂时为本机地址
String notify_url = notify;//接收微信支付异步通知回调地址,不支持参数
String trade_type = TRADE_TYPE;//交易类型 map.put("appid", appid);
map.put("mch_id", mch_id);
map.put("nonce_str", nonce_str);
map.put("body", body);
map.put("out_trade_no", out_trade_no);
map.put("total_fee", total_fee);
map.put("spbill_create_ip", spbill_create_ip);
map.put("notify_url", notify_url);
map.put("trade_type", trade_type); String sign = genPackageSign(map);
map.put("sign", sign);//签名
pay.setSign(sign);
pay.setAppid(appid);
pay.setAppkey(API_KEY);
pay.setPartnerid(mch_id);
pay.setPack("Sign=WXPay");
pay.setNoncestr(nonce_str);
pay.setTimestamp(String.valueOf(System.currentTimeMillis() / 1000));
String xmlstring = "<xml>" + "<appid>" + appid + "</appid>"
+ "<mch_id>" + mch_id + "</mch_id>"
+ "<nonce_str>" + nonce_str + "</nonce_str>"
+ "<sign>" + sign + "</sign>"
+ "<body><![CDATA[" + body + "]]></body>"
+ "<out_trade_no>" + out_trade_no + "</out_trade_no>"
+ "<total_fee>" + total_fee + "</total_fee>"
+ "<spbill_create_ip>" + spbill_create_ip + "</spbill_create_ip>"
+ "<notify_url>" + notify_url + "</notify_url>"
+ "<trade_type>" + trade_type + "</trade_type>"
+ "</xml>";
return xmlstring; } /**
* 生成签名
* @param params
* @return
*/
public static String genPackageSign(Map<String,Object> params) {
StringBuilder sb = new StringBuilder(); TreeSet<String> sort = new TreeSet<String>(params.keySet());
for (String key : sort) {
String value = (String) params.get(key);
sb.append(key);
sb.append("=");
sb.append(value);
sb.append("&");
}
sb.append("key=");
sb.append(API_KEY);//API密钥
String packageSign = MD5.MD5Encode((sb.toString()));
packageSign = packageSign.toUpperCase();
return packageSign;
}
/**
* 生成随机字符串
* @param length
* @return
*/
public static String getRandomString(int length) { //length表示生成字符串的长度
String base = "abcdefghijklmnopqrstuvwxyz0123456789";
Random random = new Random();
StringBuffer sb = new StringBuffer();
for (int i = 0; i < length; i++) {
int number = random.nextInt(base.length());
sb.append(base.charAt(number));
}
return sb.toString();
}
/**
* 实现Java访问url
* @param url param
* @return
* @throws JDOMException
* @throws IOException
*/
public static Map<String,String> sendPost(String url, String param) {
DefaultHttpClient client = new DefaultHttpClient();
client.getParams().setParameter(ClientPNames.ALLOW_CIRCULAR_REDIRECTS, true);
HttpPost httpost= HttpClientConnectionManager.getPostMethod(url);
Map<String,String> map = null;
try {
httpost.setEntity(new StringEntity(param, "UTF-8"));
HttpResponse response = httpclient.execute(httpost);
String jsonStr = EntityUtils.toString(response.getEntity(), "UTF-8");
// System.out.println("=====" + jsonStr);
if(jsonStr.indexOf("FAIL")!=-1){
return map;
}
map = doXMLParse(jsonStr);
//prepay_id = (String) map.get("prepay_id");
} catch (Exception e) {
logger.error("request weixin prepay_id error!", e);
e.printStackTrace();
}
return map;
}
/**
* 关闭订单支付
* @param url
* @param param
* @return
*/
public static boolean sendClosePost(String url,String param)
{
boolean flag = true;
DefaultHttpClient client = new DefaultHttpClient();
client.getParams().setParameter(ClientPNames.ALLOW_CIRCULAR_REDIRECTS, true);
HttpPost httpost= HttpClientConnectionManager.getPostMethod(url);
try
{
httpost.setEntity(new StringEntity(param,"UTF-8"));
HttpResponse response = httpclient.execute(httpost);
String jsonStr = EntityUtils.toString(response.getEntity(), "UTF-8");
if(jsonStr.indexOf("FAIL")!=-1){
return false;
} }
catch(Exception e)
{
flag = false;
}
return flag;
} /**
* 形成支付网址
* @param phone
* @return
*/
public static String createPayUrl(String order)
{
if(StringUtils.isBlank(order))
{
return null;
}
StringBuffer sb = new StringBuffer();
//weixin://wxpay/bizpayurl?sign=XXXXX&appid=XXXXX&mch_id=XXXXX&product_id=XXXXXX&time_stamp=XXXXXX&nonce_str=XXXXX
Map<String,Object> param = new HashMap<String,Object>();
param.put("appid",APPID);
param.put("mch_id", MCH_ID);
param.put("time_stamp", String.valueOf(Calendar.getInstance().getTimeInMillis()));
param.put("nonce_str", getNewId());
param.put("product_id", order);
String sign = genPackageSign(param);
param.put("sign",sign);
sb.append("weixin://wxpay/bizpayurl?");
sb.append(genUrlParam(param));
return sb.toString();
} /**
* 形成随机字符串
* @return
*/
private static String getNewId()
{
return java.util.UUID.randomUUID().toString().toLowerCase().replaceAll("-","");
} private static String genUrlParam(Map<String,Object> param)
{
StringBuffer sb = new StringBuffer();
TreeSet<String> sort = new TreeSet<String>(param.keySet());
for (String key : sort) {
String value = (String) param.get(key);
sb.append(key);
sb.append("=");
sb.append(value);
sb.append("&");
}
String params = sb.toString();
while(params.endsWith("&"))
{
params = params.substring(0,params.length() - 1);
}
return params;
}
/**
* 查询订单是否存在
* @param url
* @param param
* @return
*/
public static boolean sendQueryPost(String url,String param)
{
boolean flag = true;
DefaultHttpClient client = new DefaultHttpClient();
client.getParams().setParameter(ClientPNames.ALLOW_CIRCULAR_REDIRECTS, true);
HttpPost httpost= HttpClientConnectionManager.getPostMethod(url);
try
{
httpost.setEntity(new StringEntity(param,"UTF-8"));
HttpResponse response = httpclient.execute(httpost);
String jsonStr = EntityUtils.toString(response.getEntity(), "UTF-8");
System.out.println(jsonStr);
if(jsonStr.indexOf("FAIL")!=-1){
return false;
} }
catch(Exception e)
{
flag = false;
}
return flag;
}
/**
* 解析xml,返回第一级元素键值对。如果第一级元素有子节点,则此节点的值是子节点的xml数据。
* @param strxml
* @return
* @throws JDOMException
* @throws IOException
*/
public static Map<String, String> doXMLParse(String strxml) throws Exception {
if(null == strxml || "".equals(strxml)) {
return null;
} Map<String, String> m = new HashMap<String, String>();
InputStream in = String2Inputstream(strxml);
SAXBuilder builder = new SAXBuilder();
Document doc = builder.build(in);
Element root = doc.getRootElement();
List<?> list = root.getChildren();
Iterator<?> it = list.iterator();
while(it.hasNext()) {
Element e = (Element) it.next();
String k = e.getName();
String v = "";
List<?> children = e.getChildren();
if(children.isEmpty()) {
v = e.getTextNormalize();
} else {
v = getChildrenText(children);
} m.put(k, v);
} //关闭流
in.close(); return m;
}
/**
* 获取子结点的xml
* @param children
* @return String
*/
public static String getChildrenText(List<?> children) {
StringBuffer sb = new StringBuffer();
if(!children.isEmpty()) {
Iterator<?> it = children.iterator();
while(it.hasNext()) {
Element e = (Element) it.next();
String name = e.getName();
String value = e.getTextNormalize();
List<?> list = e.getChildren();
sb.append("<" + name + ">");
if(!list.isEmpty()) {
sb.append(getChildrenText(list));
}
sb.append(value);
sb.append("</" + name + ">");
}
} return sb.toString();
}
public static InputStream String2Inputstream(String str) {
return new ByteArrayInputStream(str.getBytes());
} /**
* 支付成功微信回调
* @param children
* @return String
* @throws Exception
*/
public static Map<String,String> doReqToMap(InputStream inputStream) throws Exception {
// 解析结果存储在HashMap
Map<String, String> map = new HashMap<String, String>();
SAXBuilder builder = new SAXBuilder();
Document doc = builder.build(inputStream);
Element root = doc.getRootElement();
List<?> list = root.getChildren();
Iterator<?> it = list.iterator();
while(it.hasNext()) {
Element e = (Element) it.next();
String k = e.getName();
String v = "";
List<?> children = e.getChildren();
if(children.isEmpty()) {
v = e.getTextNormalize();
} else {
v = getChildrenText(children);
} map.put(k, v);
} //关闭流
inputStream.close(); return map;
} /**
* 处理返回数据
* @param children
* @return String
*/
public static Map<String,Object> responseData(String prepayId) {
SortedMap<String, Object> map = new TreeMap<String, Object>();
map.put("appid", APPID);//微信分配的公众账号ID
map.put("partnerid", MCH_ID);//微信支付分配的商户号
map.put("prepayid", prepayId);//支付交易会话ID
map.put("package", "Sign=WXPay");//扩展字段 固定值Sign=WXPay
map.put("noncestr", getRandomString(18));//随机字符串
map.put("timestamp", String.valueOf(System.currentTimeMillis()/1000));//10位时间戳 String sign = genPackageSign(map);
map.put("sign", sign);//签名 return map;
} /**
* 关闭上次订单
* @param order
*/
public static void closePrePay(String order) {
//查询订单是否存在
if(checkExists(order))
{
String closeStr = closeParam(createCloseParam(order));
sendClosePost(WXPayDataUtils.WX_CLOSE_ORDER, closeStr);
} } /**
* 查询订单是否存在
* @param order
* @return boolean true存在;false不存在
*/
private static boolean checkExists(String order)
{
boolean flag = false;
String closeStr = closeParam(createCloseParam(order));
flag = sendQueryPost(WXPayDataUtils.WX_ORDER_QUERY, closeStr);
return flag;
}
/**
* 行程请求参数
* @param order
* @return
*/
private static Map<String,Object> createCloseParam(String order)
{
SortedMap<String, Object> map = new TreeMap<String, Object>();
map.put("appid", APPID);//微信分配的公众账号ID
map.put("mch_id", MCH_ID);//微信支付分配的商户号
map.put("out_trade_no", order);//商家订单编号
map.put("nonce_str", getRandomString(18));//随机字符串
String sign = genPackageSign(map);
map.put("sign", sign);//签名
return map;
} /**
* 转为字符串
* @param param
* @return
*/ private static String closeParam(Map<String,Object> param)
{
StringBuffer sb = new StringBuffer();
sb.append("<xml>");
Set<String> key = param.keySet();
for(String k : key)
{
sb.append("<" +k.toString().trim()+">" + param.get(k.trim()) + "</" + k.toString().trim() + ">");
}
sb.append("</xml>");
return sb.toString();
}
}
18/8/2 补充,经网友提醒,发现缺少几个必要的工具类
经网友提醒,发现源代码少贴了几个工具类,不好意思
[code=java]
package com.sanmi.fangxinyuesao.manage.platform.base.utils; import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.impl.client.DefaultHttpClient; public class HttpClientConnectionManager { /**
* 获取SSL验证的HttpClient
* @param httpClient
* @return
*/
public static HttpClient getSSLInstance(HttpClient httpClient){
ClientConnectionManager ccm = httpClient.getConnectionManager();
SchemeRegistry sr = ccm.getSchemeRegistry();
sr.register(new Scheme("https", MySSLSocketFactory.getInstance(), 443));
httpClient = new DefaultHttpClient(ccm, httpClient.getParams());
return httpClient;
} /**
* 模拟浏览器post提交
*
* @param url
* @return
*/
public static HttpPost getPostMethod(String url) {
HttpPost pmethod = new HttpPost(url); // 设置响应头信息
pmethod.addHeader("Connection", "keep-alive");
pmethod.addHeader("Accept", "*/*");
pmethod.addHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
pmethod.addHeader("Host", "api.mch.weixin.qq.com");
pmethod.addHeader("X-Requested-With", "XMLHttpRequest");
pmethod.addHeader("Cache-Control", "max-age=0");
pmethod.addHeader("User-Agent", "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0) ");
return pmethod;
} /**
* 模拟浏览器GET提交
* @param url
* @return
*/
public static HttpGet getGetMethod(String url) {
HttpGet pmethod = new HttpGet(url);
// 设置响应头信息
pmethod.addHeader("Connection", "keep-alive");
pmethod.addHeader("Cache-Control", "max-age=0");
pmethod.addHeader("User-Agent", "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0) ");
pmethod.addHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/;q=0.8");
return pmethod;
}
} [/code]
MySSLSocketFactory
[code=java]
package com.sanmi.fangxinyuesao.manage.platform.base.utils; import org.apache.http.conn.ssl.SSLSocketFactory; import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException; public class MySSLSocketFactory extends SSLSocketFactory{ static{
mySSLSocketFactory = new MySSLSocketFactory(createSContext());
} private static MySSLSocketFactory mySSLSocketFactory = null; private static SSLContext createSContext(){
SSLContext sslcontext = null;
try {
sslcontext = SSLContext.getInstance("SSL");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
try {
sslcontext.init(null, new TrustManager[]{new TrustAnyTrustManager()}, null);
} catch (KeyManagementException e) {
e.printStackTrace();
return null;
}
return sslcontext;
} private MySSLSocketFactory(SSLContext sslContext) {
super(sslContext);
this.setHostnameVerifier(ALLOW_ALL_HOSTNAME_VERIFIER);
} public static MySSLSocketFactory getInstance(){
if(mySSLSocketFactory != null){
return mySSLSocketFactory;
}else{
return mySSLSocketFactory = new MySSLSocketFactory(createSContext());
}
} }
[/code]
ParseXml
[code=java]
/**
* 解析xml文件,形成Map<String,String>
* @author lld
* @version 1.0
*/
package com.sanmi.fangxinyuesao.manage.platform.base.utils; import org.jdom.Element;
import org.jdom.input.SAXBuilder;
import org.xml.sax.InputSource; import java.io.StringReader;
import java.util.HashMap;
import java.util.List;
import java.util.Map; public class ParseXml { public static Map<String,String> parse(String xml)
{
Map<String,String> param = new HashMap<String,String>();
try{
StringReader reader = new StringReader(xml);
StringReader read = new StringReader(xml);
// 创建新的输入源SAX 解析器将使用 InputSource 对象来确定如何读取 XML 输入
InputSource source = new InputSource(read);
// 创建一个新的SAXBuilder
SAXBuilder sb = new SAXBuilder();
// 通过输入源构造一个Document
org.jdom.Document doc = sb.build(source);
Element root = (Element) doc.getRootElement();// 指向根节点
List<Element> es = root.getChildren();
if (es != null && es.size() != 0) {
for (Element element : es) {
param.put(element.getName(), element.getValue());
}
}
}
catch(Exception e) {
e.printStackTrace();
}
return param;
}
} [/code]
TrustAnyTrustManager
[code=java]
package com.sanmi.fangxinyuesao.manage.platform.base.utils; import javax.net.ssl.X509TrustManager;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate; /**
*
* @author Administrator
*
*/
public class TrustAnyTrustManager implements X509TrustManager{
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType)
throws CertificateException { }
@Override
public void checkServerTrusted(X509Certificate[] chain, String authType)
throws CertificateException { }
@Override
public X509Certificate[] getAcceptedIssuers() {
return null;
} }
[/code]
<6>将返回值生成二维码,前端wxpay.html页面,使用qrcode生成
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>微信支付 - $!{config.poweredby}</title>
<meta name="keywords" content="$!config.keywords" />
<meta name="description" content="$!config.description" />
<meta name="generator" content="$!{config.meta_generator}" />
<meta name="author" content="$!{config.meta_author}" />
<meta name="copyright" content="$!{config.copyRight}" />
<!-- <link href="$!webPath/resources/style/system/front/default/css/public.css" type="text/css" rel="stylesheet" /> -->
<link href="$!webPath/resources/style/system/front/default/css/goods.css" type="text/css" rel="stylesheet" />
<script type="text/javascript" src="$!webPath/resources/js/yjs/jquery.js"></script>
<script type="text/javascript" src="$!webPath/resources/js/jquery.qrcode.min.js"></script>
<link href="$!webPath/resources/style/system/front/default/webcss/zhuye/css.css" type="text/css" rel="stylesheet" /> <script type="text/javascript">
function utf16to8(str) {
var out, i, len, c;
out = "";
len = str.length;
for (i = 0; i < len; i++) {
c = str.charCodeAt(i);
if ((c >= 0x0001) && (c <= 0x007F)) {
out += str.charAt(i);
} else if (c > 0x07FF) {
out += String.fromCharCode(0xE0 | ((c >> 12) & 0x0F));
out += String.fromCharCode(0x80 | ((c >> 6) & 0x3F));
out += String.fromCharCode(0x80 | ((c >> 0) & 0x3F));
} else {
out += String.fromCharCode(0xC0 | ((c >> 6) & 0x1F));
out += String.fromCharCode(0x80 | ((c >> 0) & 0x3F));
}
}
return out;
}
jQuery(function(){
jQuery('#output').qrcode({
render : "canvas",//也可以替换为table
width : 200,
height : 200,
text : utf16to8("$!barCode")});
})
</script>
</head>
<body> <div class="main" style="overflow:hidden;"> <div class="payfor_box">
<h3>微信支付</h3>
<h5 style="color:#F00;">付款金额:¥$!order_total_price</h5>
<span class="payfor_textarea" id="output" style="color:#F00"> </span>
<img src="$!webPath/resources/style/channel/images/wxpay.png" />
<h4>支付成功 <a href="$!webPath/index.htm">返回首页逛逛</a></h4>
<h4>支付失败 <a href="$!webPath$!redirect">$!msg</a></h4>
</div> </div> </body>
</html>
(3)前两步完成后,支付链接对应的二维码就可以自动生成,我们还需要对支付结果进行处理,微信回调方法:wxBuyerNotify
/**
* 微信支付回调
* @param response
* @param request
*/
@RequestMapping("/wxBuyerNotify.htm")
public void wxBuyerNotify(HttpServletResponse response,HttpServletRequest request)
{
//TODO 待完成
String result ="<xml> <return_code><![CDATA[%s]]></return_code> <return_msg><![CDATA[%s]]></return_msg></xml>"; StringBuffer xml = new StringBuffer();
String temp = null;
try
{
BufferedReader read = request.getReader();
while((temp = read.readLine()) != null)
{
xml.append(temp);
}
read.close(); }
catch(Exception e){}
Map<String,String> param = ParseXml.parse(xml.toString());
//验证是否微信回调
if(checkSign(param))
{
//获取自定义返回值,此处定义的自定义返回值的格式为:付款类型,订单编号
String attach = param.get("attach"); String type = "" ;
String order_id="" ;
if (attach != null) {
String a[] = attach.split(",");
if (a[0] != null) {
type = a[0].trim();
}
if (a[1] != null) {
order_id = a[1].trim();
}
}
if(!StringUtils.isBlank(order_id) && !StringUtils.isBlank(type) )
{
//签名,返回值,状态码判断之后,开始处理逻辑
OrderForm order = null;
Predeposit obj = null;
GoldRecord gold = null;
IntegralGoodsOrder ig_order = null;
if (type.equals("integral")) {
ig_order = this.integralGoodsOrderService.getObjById(CommUtil
.null2Long(order_id));
}
if (type.equals("cash")) {
obj = this.predepositService.getObjById(CommUtil
.null2Long(order_id));
}
if (type.equals("gold")) {
gold = this.goldRecordService.getObjById(CommUtil
.null2Long(order_id));
}
if (type.equals("goods") || type.equals("group")) {
order = this.orderFormService.getObjById(CommUtil
.null2Long(order_id));
} if (type.equals("cash")) {
obj.setPd_status(1);
obj.setPd_pay_status(2);
this.predepositService.update(obj);
User user = this.userService.getObjById(obj
.getPd_user().getId());
user.setAvailableBalance(BigDecimal.valueOf(CommUtil
.add(user.getAvailableBalance(),
obj.getPd_amount())));
this.userService.update(user);
}
if (type.equals("goods") || type.equals("group")) {
if(order.getLiuCheng()==1){
if(order.getOrder_status()==10){
order.setOrder_status(18);////预售支付定金成功标志
}else if(order.getOrder_status()==18){
order.setOrder_status(20);////支付尾款成功,就是已付款
}
}
if(order.getLiuCheng()==0){
order.setOrder_status(20);////普通商品 ,20为已付款待发货
order.setPayTime(new Date());
} this.orderFormService.update(order);
if (order.getOrder_main() == 1
&& !CommUtil.null2String(
order.getChild_order_detail()).equals(
"")) {// 同步完成子订单付款状态调整
List<Map> maps = this.orderFormTools
.queryGoodsInfo(order
.getChild_order_detail());
for (Map child_map : maps) {
OrderForm child_order = this.orderFormService
.getObjById(CommUtil
.null2Long(child_map
.get("order_id")));
child_order.setOrder_status(20);
this.orderFormService.update(child_order);
// 向加盟商家发送付款成功短信提示,自营商品无需发送短信提示
// 付款成功,发送短信提示
}
}
// 如果是团购订单,则需呀执行团购订单相关流程及发送团购码
if (order.getOrder_cat() == 2) {
Calendar ca = Calendar.getInstance();
ca.add(ca.DATE, this.configService.getSysConfig()
.getAuto_order_return());
SimpleDateFormat bartDateFormat = new SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss");
String latertime = bartDateFormat.format(ca.getTime());
order.setReturn_shipTime(CommUtil.formatDate(latertime));
Map map = this.orderFormTools.queryGroupInfo(order
.getGroup_info());
int count = CommUtil.null2Int(map.get("goods_count")
.toString());
String goods_id = map.get("goods_id").toString();
GroupLifeGoods goods = this.groupLifeGoodsService
.getObjById(CommUtil.null2Long(goods_id));
/* goods.setGroup_count(goods.getGroup_count()
- CommUtil.null2Int(count));
this.groupLifeGoodsService.update(goods);*/
int i = 0;
List<String> code_list = new ArrayList();// 存放团购消费码
/*User user = this.userService.getObjById(SecurityUserHolder
.getCurrentUser().getId());*/
User user = this.userService.getObjById(CommUtil.null2Long(order.getUser_id()));
Map params = new HashMap();
params.put("mark", "wxpay");
List<Payment> payments = this.paymentService.query(
"select obj from Payment obj where obj.mark=:mark", params,
-1, -1);
String codes = "";
System.out.println("微信支付团购消费码开始生成");
while (i < count) {
GroupInfo info = new GroupInfo();
info.setAddTime(new Date());
info.setLifeGoods(goods);
info.setPayment(payments.get(0));
info.setUser_id(CommUtil.null2Long(order.getUser_id()));
info.setUser_name(CommUtil.null2String(order.getUser_name()));
info.setOrder_id(order.getId());
info.setGroup_sn(CommUtil.null2Long(order.getUser_id())
+ CommUtil.formatTime("yyyyMMddHHmmss" + i,
new Date()));
Calendar ca2 = Calendar.getInstance();
ca2.add(ca2.DATE, this.configService.getSysConfig()
.getGrouplife_order_return());
SimpleDateFormat bartDateFormat2 = new SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss");
String latertime2 = bartDateFormat2.format(ca2
.getTime());
info.setRefund_Time(CommUtil.formatDate(latertime2));
this.groupInfoService.save(info);
codes = codes + info.getGroup_sn() + " ";
code_list.add(info.getGroup_sn());
i++;
}
if (order.getOrder_form() == 0) {
Store store = this.storeService.getObjById(CommUtil
.null2Long(order.getStore_id()));
if (store.getAgent_id() != null) {
User agent = this.userService.getObjById(store.getAgent_id());
agent.setAvailableBalance(BigDecimal.valueOf(CommUtil.add(agent.getAvailableBalance(), order.getAgent_commission_amount())));
this.userService.update(agent);
}
PayoffLog plog = new PayoffLog();
plog.setPl_sn("pl"
+ CommUtil.formatTime("yyyyMMddHHmmss",
new Date())
+ store.getUser().getId());
plog.setPl_info("团购码生成成功");
plog.setAddTime(new Date());
plog.setSeller(store.getUser());
plog.setO_id(CommUtil.null2String(order.getId()));
plog.setOrder_id(order.getOrder_id().toString());
plog.setCommission_amount(
order.getCommission_amount());// 该订单总佣金费用
plog.setAgent_commission_amount(
order.getAgent_commission_amount());// 该订单代理佣金费用
// 将订单中group_info({})转换为List<Map>([{}])
List<Map> Map_list = new ArrayList<Map>();
Map group_map = this.orderFormTools
.queryGroupInfo(order.getGroup_info());
Map_list.add(group_map);
plog.setGoods_info(Json.toJson(Map_list,
JsonFormat.compact()));
plog.setOrder_total_price(order.getTotalPrice());// 该订单总商品金额
plog.setTotal_amount(BigDecimal.valueOf(CommUtil.subtract(order.getTotalPrice(), order.getCommission_amount())));// 该订单应结算金额:结算金额=订单总商品金额-总佣金费用
this.payoffLogService.save(plog);
System.out.println("微信支付团购消费码生成成功");
store.setStore_sale_amount(BigDecimal
.valueOf(CommUtil.add(
order.getTotalPrice(),
store.getStore_sale_amount())));// 店铺本次结算总销售金额
// 团购消费码,没有佣金,店铺总佣金不变,有佣金
store.setStore_commission_amount(BigDecimal
.valueOf(CommUtil.add(
order.getCommission_amount(),
store.getStore_commission_amount())));
store.setStore_payoff_amount(BigDecimal
.valueOf(CommUtil.add(
order.getTotalPrice(),
store.getStore_payoff_amount())));// 店铺本次结算总佣金
this.storeService.update(store);
}
// 增加系统总销售金额
SysConfig sc = this.configService.getSysConfig();
sc.setPayoff_all_sale(BigDecimal.valueOf(CommUtil.add(
order.getTotalPrice(), sc.getPayoff_all_sale())));
sc.setPayoff_all_commission(BigDecimal.valueOf(CommUtil.add(
order.getCommission_amount(), sc.getPayoff_all_commission())));
this.configService.update(sc);
// 更新lucene索引
/*String goods_lucene_path = "";
if (goods.getArea_id() != 0) {
goods_lucene_path = System.getProperty("user.dir")
+ File.separator + "luence"
+ File.separator + "lifegoods"
+ goods.getArea_id();
} else {
goods_lucene_path = System.getProperty("user.dir")
+ File.separator + "luence"
+ File.separator + "lifegoods";
}
File file = new File(goods_lucene_path);
if (!file.exists()) {
CommUtil.createFolder(goods_lucene_path);
}
LuceneUtil lucene = LuceneUtil.instance();
lucene.setIndex_path(goods_lucene_path);
lucene.update(CommUtil.null2String(goods.getId()),
luceneVoTools.updateLifeGoodsIndex(goods));*/
String msg_content = "恭喜您成功购买团购"
+ map.get("goods_name") + ",团购消费码分别为:" + codes
+ "您可以到用户中心-我的生活购中查看消费码的使用情况";
// 发送系统站内信给买家
Message tobuyer_msg = new Message();
tobuyer_msg.setAddTime(new Date());
tobuyer_msg.setStatus(0);
tobuyer_msg.setType(0);
tobuyer_msg.setContent(msg_content);
tobuyer_msg.setFromUser(this.userService
.getObjByProperty("userName", "admin"));
tobuyer_msg.setToUser(user);
this.messageService.save(tobuyer_msg);
// 付款成功,发送短信团购消费码
}
// this.update_goods_inventory(order,null);// 更新商品库存
if (order.getOrder_cat() != 2) { List<Goods> goods_list = this.orderFormTools
.queryOfGoods(CommUtil.null2String(order
.getId()));
for (Goods goods : goods_list) {
// 造成搜索数据重复的原因
String goods_lucene_path = null;
if (goods.getGoods_type() == 0) { // 如果商品是自营商品
goods_lucene_path = System
.getProperty("user.dir")
+ File.separator
+ "luence"
+ File.separator + "goods";
} else { // 如果商品是店铺商品
if (goods.getGoods_store().getArea() != null) { // 店铺入驻到地区
goods_lucene_path = System
.getProperty("user.dir")
+ File.separator
+ "luence"
+ File.separator
+ "goods"
+ goods.getGoods_store().getArea()
.getId();
} else {
goods_lucene_path = System // 店铺入住到中国大区
.getProperty("user.dir")
+ File.separator + "luence"
+ File.separator + "goods_store";
} }
File file = new File(goods_lucene_path);
if (!file.exists()) {
CommUtil.createFolder(goods_lucene_path);
}
LuceneUtil lucene = LuceneUtil.instance();
lucene.setIndex_path(goods_lucene_path);
lucene.update(CommUtil.null2String(goods.getId()),
luceneVoTools.updateGoodsIndex(goods));
}
}
OrderFormLog ofl = new OrderFormLog();
ofl.setAddTime(new Date());
ofl.setLog_info("微信支付");
ofl.setLog_user(SecurityUserHolder.getCurrentUser());
ofl.setOf(order);
this.orderFormLogService.save(ofl);
} if (type.equals("gold")) {
gold.setGold_status(1);
gold.setGold_pay_status(2);
this.goldRecordService.update(gold);
User user = this.userService.getObjById(gold
.getGold_user().getId());
user.setGold(user.getGold() + gold.getGold_count());
this.userService.update(user);
GoldLog log = new GoldLog();
log.setAddTime(new Date());
log.setGl_payment(gold.getGold_payment());
log.setGl_content("微信支付");
log.setGl_money(gold.getGold_money());
log.setGl_count(gold.getGold_count());
log.setGl_type(0);
log.setGl_user(gold.getGold_user());
log.setGr(gold);
this.goldLogService.save(log);
}
if (type.equals("integral")) {
ig_order.setIgo_status(20);
ig_order.setIgo_pay_time(new Date());
ig_order.setIgo_payment("wxpay");
this.integralGoodsOrderService.update(ig_order);
for (IntegralGoodsCart igc : ig_order.getIgo_gcs()) {
IntegralGoods goods = igc.getGoods();
goods.setIg_goods_count(goods.getIg_goods_count()
- igc.getCount());
goods.setIg_exchange_count(goods
.getIg_exchange_count() + igc.getCount());
this.integralGoodsService.update(goods);
}
}
//处理业务逻辑结束
result = "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>"
+ "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> ";
}
}else{
result = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>"
+ "<return_msg><![CDATA[报文为空]]></return_msg>" + "</xml> ";
}
//處理業務完畢,輸出結果
try
{
response.getOutputStream().write(result.getBytes());
}
catch(Exception ioe)
{
ioe.printStackTrace();
} }
<-----------------------------结束------------------------------------------>
小结:支付环节步骤很复杂,但是根据官方API按步骤对接,可以有条理的进行对接
官方接口地址:https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=6_5,微信工具类请下载最新版
java对接微信支付的更多相关文章
- Android对接微信支付体验
在写正文之前我不得不吐槽一下:微信支付所提供的参考文档以及技术支持真心太烂了. 微信的坑: 1.在生成prepay_id向微信服务器传递参数时<body>不支持中文.需要对其进行转码,否则 ...
- Java 后端微信支付demo
Java 后端微信支付demo 一.导入微信SDK 二.在微信商户平台下载证书放在项目的resources目录下的cert文件夹下(cert文件夹需要自己建) 三.实现微信的WXPayConfig接口 ...
- PHP对接微信支付采坑
第一次做PHP商城项目对接微信支付接口,踩了N次坑,这也不对,那也不对,搞了很久,查了一些资料,终于实现了支付功能,小小总结一下,万一下次遇到就不用到处找资料了. 微信扫码支付 前期准备: 1.微信公 ...
- java实现微信支付
java实现微信支付 package com.hk.wx.pay.service.impl; @Service public class PayServiceImpl implements PaySe ...
- java版微信支付/查询/撤销
最近公司接入微信刷卡支付,网上根本没见到很直接的教程(可能眼拙),一直摸滚打爬,加班加点才走通,忍不了必须写一写 微信 刷卡支付/查询/撤销... 必须要有公众号然后去申请,申请自己去看文档,这里主要 ...
- JAVA实现微信支付V3
喜欢的朋友可以关注下,粉丝也缺. 相信很多的码友在项目中都需要接入微信支付,虽说微信支付已成为一个普遍的现象,但是接入的过程中难免会遇到各种各样的坑,这一点支付宝的SDK就做的很好,已经完成的都知道了 ...
- JAVA开发微信支付-公众号支付/微信浏览器支付(JSAPI)
写这篇文章的目的有2个,一是自己的项目刚开发完微信支付功能,趁热回个炉温习一下,二也是帮助像我这样对微信支付不熟悉,反复看了多天文档还是一知半解,原理都没摸清,更不要说实现了.本以为网上的微信开发教程 ...
- java做微信支付notify_url异步通知服务端的写法
最近团队在接入微信支付,APP和JSAPI的接口都需要填写一个notify_url回调地址,但是坑爹的官方文档并没有找到JSAPI模式的java版的demo,所以不得不自己看文档写了一个接受微信异步通 ...
- python - 对接微信支付(PC)和 注意点
注:本文仅提供 pc 端微信扫码支付(模式一)的示例代码. 关于对接过程中遇到的问题总结在本文最下方. 参考: 官方文档, https://blog.csdn.net/lm_is_dc/arti ...
随机推荐
- js实现base64编码与解码(原生js)
一直以来很多人使用到 JavaScript 进行 base64 编码解码时都是使用的 Base64.js,但事实上,浏览器很早就原生支持 base64 的编码与解码了 以前的方式 编码: <ja ...
- rel 属性<small>H5保留属性</small>
源文件
- 服务器常用命令之 启用/禁用PING状态
启用 echo 0 > /proc/sys/net/ipv4/icmp_echo_ignore_all (PING的通) 禁用 echo 1 > /proc/sys/net/ipv4/i ...
- May 13th 2017 Week 19th Saturday
Mountains look beautiful from a distance. 远处看山山更美. This gnomic seems to circulate very long, its mor ...
- C++ double 小数精度控制
第一种方法:cout<<fixed<<setprecision(20)<<mydouble<<endl; #include <iostream&g ...
- 学习和运用scrum
作为长大的大三老腊肉,我们已经在长大生活了两年多,对于什么是长大人最想完善的校园需求.最想拥有的校园服务媒介也有了更加深切的体会. 于是,GoodJob小团队blingbling闪现啦!! GoodJ ...
- SSH 学习记录及在SSH模式下使用XShell连接服务器
传统的网络服务程序,如rsh.FTP.POP和Telnet其本质上都是不安全的:因为它们在网络上用明文传送数据.用户帐号和用户口令,很容易受到中间人(man-in-the-middle)攻击方式的攻击 ...
- IOS 播放视频(MPMoviePlayerController、MPMoviePlayerViewController)
● iOS提供了叫 做MPMoviePlayerController.MPMoviePlayerViewController的两个 类,可以用来轻松播放视频 ➢ YouTobe就是用MPMoviePl ...
- 《编程导论(Java)·9.3.1回调·3》回调的实现
版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/yqj2065/article/details/31441221 接<9.3.1Java回调 · ...
- 2018.11.7 关于将Web项目部署到阿里云服务器-5个步骤搞定
将Eclipse导出的War包部署到阿里云服务器上,提供给移动端实时的访问 1. 先登录阿里云网站注册账号,选择服务器类型(我用的是 云服务器ECS), 如果你还是在读大学生可享受优惠价,最低好像是9 ...