微信公众号授权,支付,退款总结【shoucang】
1.支付前准备
1.1首先两个平台接入账户。
- 商户平台:https://pay.weixin.qq.com/index.php/core/home/login?return_url=%2F
- 公众平台:https://mp.weixin.qq.com/
1.2两个平台的作用
3 商户平台:支付收款方,通俗点将就是网站用户支付的钱给谁。里面有商户的一些信息以及秘钥支付时要用。
4.公众号平台:在这里需要它提供网页授权的一些信息。
2.微信公众号支付流程
关于支付流程,官方给了一张很详细的流程图如下:
当然这是所有支付的流程图,在这里博主结合自己的实现方式也画了一张只有授权和公众号支付流程的图。大家可以参考有画的不对的地方还请路过的大牛多多指教。
3. 微信公众号支付的那些坑
1:获取授权的时候,访问授权接口不要用ajax提交。如果用ajax提交方式提交请求,微信服务端会报跨域请求不允许的错误。
2:获取授权openid的时候appid,secret一定要正确,这里的secret获取方式为下图,如果忘记,可以重置:
3:如果用的springmvc的框架,在统一支付接口记得用注解@ResponseBody,因为统一支付接口返回的数据一般是一个map,这个map中的数据前台页面要解析,所以需要这个注解。
4:调用统一支付接口时,请求报文是xml格式的,所以要把需要的参数转变为xml形式。
5:异步回调方法是支付成功后微信通知商户后台时调用,所以测试时需要在外网测试
7:授权时,只授一次就行,所以在授权之前判断是否已经授权。
8:微信支付以分为单位,支付金额需要注意转换单位。
9:如果签名失败,一定要仔细检查参数是否都拼接完毕,拼接正确,一般签名失败最可能的原因就是secret错误,应该去微信公众平台重新查找并且核对。
10:退款时,注意双向证书的路径。一般退款回调失败最可能的原因就是证书出错。
4. 微信公众号开发需要的一些官网网站
商户平台开发者文档网址
https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_4
用户授权需要查看的网址,重点查看用户管理相关说明
http://mp.weixin.qq.com/wiki/17/c0f37d5704f0b64713d5d2c37b468d75.html
商户平台微信支付网址
https://pay.weixin.qq.com/wiki/doc/api/index.html
商户平台登录网址
https://pay.weixin.qq.com/index.php/core/home/login?return_url=%2Findex.php%2Fcore%2Faccount
微信公众平台登录入口
https://mp.weixin.qq.com/
5.公众号支付代码
前端网页js代码
var pay_orderno; //订单编号
//判断是否是授权回来的outh
var outh = $.getUrlParam("outh");
if (!empty(outh)){
//说明outh不为空,即为授权回来的,则直接微信支付
wxzhifu();
}
function getRequest() {
var url = location.search; //获取url中"?"符后的字串
var theRequest = new Object();
if (url.indexOf("?") != -1) {
var str = url.substr(1);
strs = str.split("&");
for (var i = 0; i < strs.length; i++) {
theRequest[strs[i].split("=")[0]] = unescape(strs[i].split("=")[1]);
}
}
return theRequest;
}
//保存订单信息
function saveOrder(){
var mode = "";
if($("#AliPay")[0].checked) {
mode = "支付宝";
}else if($("#bankpay")[0].checked) {
mode = "银联支付";
}else if($("#wxpay")[0].checked) {
mode = "微信支付";
}
var dishjson = data.dishJson; //订单表dishJson内容
var dishJson = (JSON.parse(dishjson))[0];
var oldcanpin = dishJson.canpin;
var newcanpin = oldcanpin + ",支付方式:"+ mode; //拼接支付方式以后的菜品信息
//alert(newcanpin);
dishJson["canpin"] = newcanpin;
data["dishJson"] = JSON.stringify(dishJson);
var url="/cyDishorder/saveCyDcOrders";
var successfull= function (datas) {
var bizData=datas.bizData;
pay_orderno = bizData.orderNum;
//alert(pay_orderno);
//var paymoney = $("#ydmoney").text().substring(1);
if(datas.rtnCode == "0000000"){
pay(); //跳转支付方法
//alert("==============")
}
}
ajaxPostFun(url, data, successfull,null, "保存餐厅预定订单");
}
//跳转到支付页面
function pay() {
if($("#AliPay")[0].checked) {
location.href = server+"/AliPayDingCan/" + pay_orderno;
}else if($("#bankpay")[0].checked) {
location.href = server+"/CYChinapay/" + pay_orderno;
}else if($("#wxpay")[0].checked){
//查询该用户是否微信授权
var url = server+"/Member/FindById/"+userid;
var successFun = function (data) {
if(empty(data.bizData.openid)){
//alert("微信未授权");
//如果该用户没有授权,则进行授权操作
wxshouquan();
}else{
//alert("微信已授权");
//用户已经授权,直接微信支付
wxzhifu();
}
}
ajaxPostFun(url, {}, successFun, null, "查询用户是否授权");
}else {
layer.msg("请选择支付方式");
return false;
}
}
//微信授权
function wxshouquan() {
location.href = server + "/CyWechatPay/outh?userid=" + userid;
}
//微信支付
function wxzhifu(){
var url = server+"/CyWechatPay/unifiedorder";
ajaxPostFun(url, {userid:userid,orderno:pay_orderno}, function(res) {
var _data = res.bizData;
function onBridgeReady(){
WeixinJSBridge.invoke(
'getBrandWCPayRequest', {
"appId":_data.appId, //公众号名称,由商户传入
"timeStamp":_data.timeStamp, //时间戳,自1970年以来的秒数
"nonceStr":_data.nonceStr, //随机串
"package" :_data.package,
"signType":_data.signType, //微信签名方式:
"paySign": _data.paySign //微信签名
},
function(ress){
alert( JSON.stringify(ress));
if(ress.err_msg == "get_brand_wcpay_request:ok" ) {
layer.msg("支付成功!",{time:2000});
//window.location.href = "buyGoodsChenggong.html?orderid="+orderid;
}else if(ress.err_msg == "get_brand_wcpay_request:cancel"){
layer.msg("支付取消!",{time:2000});
}else {
layer.msg("未知错误!",{time:2000});
} // 使用以上方式判断前端返回,微信团队郑重提示:res.err_msg将在用户支付成功后返回 ok,但并不保证它绝对可靠。
}
);
}
if (typeof WeixinJSBridge == "undefined"){
if( document.addEventListener ){
document.addEventListener('WeixinJSBridgeReady', onBridgeReady, false);
}else if (document.attachEvent){
document.attachEvent('WeixinJSBridgeReady', onBridgeReady);
document.attachEvent('onWeixinJSBridgeReady', onBridgeReady);
}
}else{
onBridgeReady();
}
}, null, "微信支付获取package包");
}
支付,退款,controller代码
@Controller
@RequestMapping(value = "/CyWechatPay")
public class CyWechatController {
@Autowired
private IMemberService memberService;
@Autowired
private IMobileCyDishorderService mobileCyDishorderService;
@Autowired
private IMobileMemberService mobileMemberService;
@Autowired
private IMobileServiceStyleService mobileServiceStyleService;
private static Logger logger = Logger.getLogger(CyWechatController.class);
private static String url_snsapi_base = "https://open.weixin.qq.com/connect/oauth2/authorize";
private static String url_access_token = "https://api.weixin.qq.com/sns/oauth2/access_token";
private static String url_unifiedorder = "https://api.mch.weixin.qq.com/pay/unifiedorder";
/**
* 统一下单
* @return prepare_id 预付款id
* @throws IOException
* @throws JDOMException
*/
@ResponseBody
@RequestMapping("/unifiedorder")
public Map<String, Object> unifiedorder(@RequestParam(value = "orderno", required = true)String orderno, String userid,HttpServletRequest request) throws Exception {
//根据订单号查询订单时间
CyDishorderEntity orderEntity = (CyDishorderEntity) mobileCyDishorderService.findOne("orderNum", orderno);
//获得随机数
String nonce_str = WxTool.getRandomCode(32);
//根据用户id查询用户信息
Map<String,Object> memberEntity =memberService.findByid("id",userid);
String openid = memberEntity.get("openid").toString();
//生成xml,参数说明(说明,标识码,订单号,IP,价格,openid用户在微信端的唯一标示)
String xml = this.getXmlData(orderEntity.getRemarks(), nonce_str,
orderno, WxTool.getRemoteHost(request), new BigDecimal(orderEntity.getPayMoney()),openid);
logger.info("生成的订单信息======>" + xml);
//订单提交的微信地址(预支付地址)
String result = HttpRequest.httpsRequest("https://api.mch.weixin.qq.com/pay/unifiedorder", "POST", xml);
//告诉编译器忽略 unchecked 警告信息,如使用List,ArrayList等未进行参数化产生的警告信息。
@SuppressWarnings("unchecked")
Map<String, Object> map2 = XMLUtil.doXMLParse(result);
logger.info("统一下单接口返回的结果集======>" + map2);
//return_code为微信返回的状态码,SUCCESS表示支付成功
//return_msg 如非空,为错误原因 签名失败 参数格式校验错误
if (map2.get("return_code").toString().equalsIgnoreCase("SUCCESS")
&& map2.get("result_code").toString().equalsIgnoreCase("SUCCESS")) {
//预支付成功
logger.info("微信预支付成功!");
//map2.put("timestamp",Long.toString(System.currentTimeMillis() / 1000));
//传递map2给前台页面处理
Map<String, Object> map = new HashMap<String, Object>();
map.put("appId", map2.get("appid"));
map.put("timeStamp", Long.toString(System.currentTimeMillis() / 1000));
map.put("nonceStr", map2.get("nonce_str"));
map.put("package", "prepay_id=" + map2.get("prepay_id"));
map.put("signType", "MD5");
map.put("paySign", WxTool.getSignUtil(map, ConfigUtil.APP_SECRECT));
logger.info("统一下------->" + map);
return map;
} else {
//支付失败,进行相应的失败业务处理
logger.info("微信预支付失败!");
//传递null给页面处理
return null;
}
}
/**
* 申请退款
*/
@RequestMapping("refund/{orderno}")
@ResponseBody
public String refund(@PathVariable String orderno) throws Exception {
//根据订单号查询订单
CyDishorderEntity orderEntity = (CyDishorderEntity) mobileCyDishorderService.findOne("orderNum", orderno);
//获得随机数
String nonce_str = WxTool.getRandomCode(32);
StringBuilder sb2 = new StringBuilder();
//微信签名需要的参数
Map<String, Object> signMap = new HashMap<String, Object>();
signMap.put("appid",ConfigUtil.APPID);//应用APPID
signMap.put("mch_id",ConfigUtil.MCH_ID);//微信支付商户号
signMap.put("nonce_str",nonce_str);//随机数
signMap.put("op_user_id",ConfigUtil.MCH_ID);
signMap.put("out_trade_no",orderEntity.getOrderNum());//订单号out_refund_no
signMap.put("out_refund_no",orderEntity.getRefund_queryid());//退款流水号
signMap.put("refund_fee",new BigDecimal(orderEntity.getPayMoney()).multiply(new BigDecimal(100)).intValue());//退款金额
signMap.put("total_fee",new BigDecimal(orderEntity.getPayMoney()).multiply(new BigDecimal(100)).intValue());//总金额
signMap.put("transaction_id","");//微信生成的订单号,在支付通知中有返回
//生成xml,微信要求的xml形式
StringBuffer xml =new StringBuffer();
xml.append("<xml>");
xml.append("<appid>"+ConfigUtil.APPID+"</appid>");//应用ID
xml.append("<mch_id>"+ConfigUtil.MCH_ID+"</mch_id>");//微信支付分配的商户号
xml.append("<nonce_str>"+nonce_str+"</nonce_str>");//随机字符串,不长于32位。
xml.append("<op_user_id>"+ConfigUtil.MCH_ID+"</op_user_id>");//操作员,默认为商户号
xml.append("<out_refund_no>"+orderEntity.getRefund_queryid()+"</out_refund_no>");//商户退款单号,商户系统内部的退款单号,商户系统内部唯一
xml.append("<out_trade_no>"+orderEntity.getOrderNum()+"</out_trade_no>");//商户订单号
xml.append("<refund_fee>"+new BigDecimal(orderEntity.getPayMoney()).multiply(new BigDecimal(100)).intValue()+"</refund_fee>");//退款金额
xml.append("<total_fee>"+new BigDecimal(orderEntity.getPayMoney()).multiply(new BigDecimal(100)).intValue()+"</total_fee>");//订单金额
xml.append("<transaction_id>"+"</transaction_id>");//微信订单号,微信生成的订单号,在支付通知中有返回
xml.append("<sign>"+WxTool.getSignUtil(signMap, ConfigUtil.APP_SECRECT)+"</sign>");//签名
xml.append("</xml>");
logger.info("生成的申请退款信息=============================>" + xml.toString());
/**
* JAVA使用证书文件
*/
logger.info("加载证书开始=========================================》》》》》");
//指定读取证书格式为PKCS12
KeyStore keyStore = KeyStore.getInstance("PKCS12");
//读取本机存放的PKCS12证书文件
FileInputStream instream = new FileInputStream(new File("/home/smit/down/apiclient_cert.p12"));
try {
//指定PKCS12的密码(商户ID)
keyStore.load(instream, ConfigUtil.MCH_ID.toCharArray());
} finally {
instream.close();
}
//ssl双向验证发送http请求报文
SSLContext sslcontext = null;
sslcontext = SSLContexts.custom().loadKeyMaterial(keyStore, ConfigUtil.MCH_ID.toCharArray()).build();
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext, new String[]{"TLSv1"}, null, SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).build();
HttpPost httppost = new HttpPost("https://api.mch.weixin.qq.com/secapi/pay/refund");
StringEntity se = new StringEntity(xml.toString(), "UTF-8");
httppost.setEntity(se);
//定义响应实例对象
CloseableHttpResponse responseEntry = null;
String xmlStr2 = null;//读入响应流中字符串的引用
responseEntry = httpclient.execute(httppost);//发送请求
HttpEntity entity = responseEntry.getEntity();//获得响应实例对象
if (entity != null) {//读取响应流的内容
BufferedReader bufferedReader = null;
bufferedReader = new BufferedReader(new InputStreamReader(entity.getContent(), "UTF-8"));
while ((xmlStr2 = bufferedReader.readLine()) != null) {
sb2.append(xmlStr2);
}
}
Map<String, Object> map = XMLUtil.doXMLParse(sb2.toString());
logger.info("申请退款接口返回的结果集======>" + map);
//return_code为微信返回的状态码,SUCCESS表示申请退款成功,return_msg 如非空,为错误原因 签名失败 参数格式校验错误
if (map.get("return_code").toString().equalsIgnoreCase("SUCCESS")
&& map.get("result_code").toString().equalsIgnoreCase("SUCCESS")) {
logger.info("****************退款申请成功!**********************");
//修改订单状态为申请退款
orderEntity.setOrderStatus(CyOrderStatusEnum.REFUND_SUCCESS.getCode());
mobileCyDishorderService.update(orderEntity);
return "SUCCESS";
} else {
logger.info("*****************退款申请失败!*********************");
return "FAIL";
}
}
//生成xml方法
private static String getXmlData(String body, String nonce_str, String tradeNo,
String ip, BigDecimal totla, String openid) throws Exception {
Map<String, Object> signMap = new HashMap<String, Object>();
signMap.put("appid", ConfigUtil.APPID);//应用APPID
signMap.put("nonce_str", nonce_str);//随机数
signMap.put("body", body);//商品描述
signMap.put("mch_id", ConfigUtil.MCH_ID);//微信支付商户号
signMap.put("notify_url", "http://域名/CyWechatPay/paysuccess.do");//异步通知回调地址
signMap.put("out_trade_no", tradeNo);//订单号
signMap.put("total_fee", totla.multiply(new BigDecimal(100)).intValue());//总金额
signMap.put("trade_type", "JSAPI");//支付类型
signMap.put("spbill_create_ip", ip);//客户端IP地址
signMap.put("openid", openid);//支付用户的唯一标识
StringBuffer xml = new StringBuffer();
xml.append("<xml>");
xml.append("<appid>" + signMap.get("appid") + "</appid>");//应用ID
xml.append("<body>" + signMap.get("body") + "</body>");
xml.append("<mch_id>" + signMap.get("mch_id") + "</mch_id>");//微信支付分配的商户号
xml.append("<nonce_str>" + signMap.get("nonce_str") + "</nonce_str>");//随机字符串,不长于32位。
xml.append("<notify_url>" + signMap.get("notify_url") + "</notify_url>");//接收微信支付异步通知回调地址
xml.append("<openid>" + signMap.get("openid") + "</openid>");//用户的openid 唯一标示,用户授权时或的
xml.append("<out_trade_no>" + signMap.get("out_trade_no") + "</out_trade_no>");//订单号
xml.append("<spbill_create_ip>" + signMap.get("spbill_create_ip") + "</spbill_create_ip>");//用户端实际ip
xml.append("<total_fee>" + signMap.get("total_fee") + "</total_fee>");//订单总金额,单位为分
xml.append("<trade_type>" + signMap.get("trade_type") + "</trade_type>");//支付类型
xml.append("<sign>" + WxTool.getSignUtil(signMap, ConfigUtil.APP_SECRECT) + "</sign>");//签名
xml.append("</xml>");
return xml.toString();
}
//微信支付异步回调
@RequestMapping(value = "/paysuccess")
public void PaySuccess(HttpServletRequest request, HttpServletResponse response){
try {
logger.info("微信支付回调开始========================================================");
PrintWriter print = null;
InputStream inStream = request.getInputStream();
ByteArrayOutputStream outSteam = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len = 0;
while ((len = inStream.read(buffer)) != -1) {
outSteam.write(buffer, 0, len);
}
outSteam.close();
inStream.close();
String result = new String(outSteam.toByteArray(), "utf-8");
//告诉编译器忽略 unchecked 警告信息,如使用List,ArrayList等未进行参数化产生的警告信息。
@SuppressWarnings("unchecked")
Map<Object, Object> map = XMLUtil.doXMLParse(result);
//return_code为微信返回的状态码,SUCCESS表示支付成功
//return_msg 如非空,为错误原因 签名失败 参数格式校验错误
logger.info("微信返回的信息:"+map.toString());
if (map.get("result_code").toString().equalsIgnoreCase("SUCCESS")
&& map.get("return_code").toString().equalsIgnoreCase("SUCCESS")) {
String tradeNo = map.get("out_trade_no").toString();
//这里做出判断,防止微信服务的多次调用这里,造成一次支付,生成多个订单
CyDishorderEntity order =(CyDishorderEntity)mobileCyDishorderService.findOne("orderNum",tradeNo);
if(order!=null && order.getOrderStatus().equals(CyOrderStatusEnum.PREPAID.getCode())){
//该订单已经支付成功,直接return
response.getWriter().write(
"<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>");
}
updateOrder(map);//更新订单状态
}
response.getWriter().write(
"<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>");
}catch (Exception e) {
e.printStackTrace();
}
}
/**
* 用户授权
*
* @param response
* @throws IOException
*/
@RequestMapping("/outh")
public void outh(@RequestParam(value = "userid", required = true) int userid,
HttpServletResponse response, HttpServletRequest request) {
StringBuffer url = request.getRequestURL();
//String tempContextUrl = url.delete(url.length() - request.getRequestURI().length(), url.length()).append("/").toString();
try {
// 回调地址
String redirecturl = URLEncoder.encode(new String(("http://域名/CyWechatPay/getopenid.do?userid=" + userid).getBytes("utf-8"), "utf-8"),"utf-8");
logger.info("[微信获取OPENID回调地址]"+redirecturl);
// 用户授权 snsapi_userinfo
response.sendRedirect("https://open.weixin.qq.com/connect/oauth2/authorize?appid="
+ ConfigUtil.APPID
+ "&redirect_uri="
+ redirecturl
+ "&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* 商户获取用户资料
*
* @param request
* @return
* @throws IOException
*/
@RequestMapping("/getopenid")
public void getopenid(@RequestParam(value = "userid", required = true) int userid,
HttpServletRequest request, HttpServletResponse response) {
String code = request.getParameter("code");
Map<String, Object> map = null; // 存放授权access_token和openid
Map<String, Object> map2 = null;// 存放用户基本资料open
// 获取授权的access_token和openid
logger.info("[获取授权的access_token和openid]");
map = WXUtils.requestUrl("https://api.weixin.qq.com/sns/oauth2/access_token?appid="
+ ConfigUtil.APPID
+ "&secret="
+ConfigUtil.APP_SECRECT
+ "&code="
+ code
+ "&grant_type=authorization_code");
String access_token = map.get("access_token").toString();
String openid = map.get("openid").toString();
// 获取用户资料
map2 = WXUtils.requestUrl("https://api.weixin.qq.com/sns/userinfo?access_token=" + access_token + "&openid=" + openid + "&lang=zh_CN");
//设置用户的openid
memberService.updateuser(Integer.valueOf(userid),openid);
try {
response.sendRedirect("http://域名/Mobile/cyLijiZhifuX.html?=outh=outh");
} catch (IOException e) {
e.printStackTrace();
}
}
//更新订单信息
private void updateOrder(Map<Object, Object> map) {
//TODO:支付成功后更新订单的逻辑。
}
}
微信公众号授权,支付,退款总结【shoucang】的更多相关文章
- 【tp5.1】微信公众号授权登录及获取信息录入数据库
微信公众号开发文档链接:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1445241432 微信公众号授权登录分为两种: 1.以 ...
- 微信公众号JSAPI支付
微信公众号JSAPI支付 一:配置参数 申请成功后,获取接口文件, 将所有文件放入项目根目录weixin下,在WxPay.ub.config.php中填入配置账户信息; 二:设置授权 开发者中心-&g ...
- uniapp - 微信公众号授权登录
[缘由] 采用uniapp进行微信小程序和微信公众号双版本开发:考虑到用户唯一性,我们后端确定了以“unionid”.作为唯一标识. 有的小伙伴估计也是刚入这坑,我就简单说一下步骤流程 [摸索] ...
- 网站如何接入微信公众号JSAPI支付PHP版
1.首先,我们要有一个微信公众号(分类类型有订阅号,服务号,企业号)我们的微信公众号一定是个服务号只有它才有微信支付接口.. 并且这个微信公众号一定要进行微信认证才能申请微信支付接口. 2.申请JSA ...
- 微信公众号JSAPI支付-多公众号向同一商户号支付的问题解决
一.背景 项目提供公众号商城集成,在公众号里进行商品的购买,并与多家公众号合作增加渠道流量. . 二.实现 有关微信公众号.商户号的开通与支付绑定不细说 从背景里可知,我们需要实现多个公众号购买向同一 ...
- java微信公众号JSAPI支付以及所遇到的坑
上周做了个支付宝微信扫码支付,今天总结一下.微信相比支付宝要麻烦许多 由于涉及到代理商,没办法,让我写个详细的申请流程,懵逼啊. 笔记地址 http://note.youdao.com/notesha ...
- PHP应用如何对接微信公众号JSAPI支付
微信支付的产品有很多,1. JSAPI支付 2. APP支付 3. Native支付 4.付款码支付 5. H5支付. 其中基于微信公众号开发的应用选择“JSAPI支付“产品,其他APP支付需 ...
- 微信公众号H5支付遇到的那些坑
简史 官方文档说的很清楚,商户已有H5商城网站,用户通过消息或扫描二维码在微信内打开网页时,可以调用微信支付完成下单购买的流程. 当然,最近微信支付平台也加入了纯H5支付,也就是说用户可以在微信以外的 ...
- 解决微信公众号授权登录和开放平台微信第三方应用授权登录获取到的用户Openid关联问题
开发背景: 最近一段时间一直在做关于微信方面的网站应用开发,这段时间也收获的不少关于微信开发方面的开发技能,接触的比较多的主要有微信公众号和微信网站app第三方登录授权,以及微信会员卡,优惠券和扫描二 ...
随机推荐
- 更改MySQL/Postgresql密码
Parrot包括几个SQL引擎,但是当它们被预先安装时,默认密码未被配置,并且拒绝访问其root用户. 重新配置Mysql / Mariadb密码 停止MySQL服务. sudo service my ...
- GC调优
Gc调优的目标:1.降低停顿时间 2.提高吞吐量 3.避免full-gc 调优可以使用的手段:1.各个内存区的大小调整:堆,年轻代,老年代,方法区等等2.减少短暂对象的存活时间,提高长期对象的复用率( ...
- 反射 XML和JSON
反射: 反射概念:在运行状态中,对于任意一个类都能知道这个类的所有方法和属性:对于任意一个对象,都能调用它的任意一个方法和属性,这种动态获取信息以及动态调用对象的方法的功能称为反射机制.java反射相 ...
- Scala知识点汇总
Scala数组小结 1.定长数组 定长数组:指长度不可变的数组Array.第一种方式:先声明一个数组,后初始化该数组: scala> val array = new Array[Double]( ...
- 《JavaScript 高级程序设计》读书笔记五 引用类型
一 Object类型 a.两种创建方式: 1.new+构造函数Object; 2.对象字面量表示法: b.两种访问属性方式: 1.点表示法(.属性): 2.方括号([“属性”]): 二 Arr ...
- Javascript高级编程学习笔记(31)—— BOM(5)screen、history对象
screen对象 screen对象应该是BOM对象中最不常用的对象了 其主要用于提供客户端的显示能力信息 包括浏览器外部显示的信息,和像素的宽高等 这个对象的主要用于检测客户端能力,一般不会影响功能 ...
- FragmentTabHost用法
FragmentTabHost组成 Tabhost,TabWidget,切换的内容容器FrameLayout 层级关系 ----FragmentTabHost |-----TabWidget |--- ...
- 2.AsyncQueryHandler、内容提供者
会话页面 Test :测试 public class Test extends AndroidTestCase{ public void test(){ Uri uri = Uri.parse(&qu ...
- PHP调用百度地图API
//百度地理位置接口API $lat = 39.912108791024; $lng = 116.48299016095; $ak = "5slgyqGDENN7Sy7pw29IUvrZ&q ...
- canvas转图片中的文字自动换行
概述 最近项目用到了canvas转图片,但是由于canvas对文字排版的支持非常弱,一般我们在canvas上画不同排版的文字(比如竖排文字)都是利用js计算横纵坐标,然后一个字一个字地画出来,今天无意 ...