此方法为V3版本

位置支付配置文件:wechat_pay_v3.properties

v3.keyPath=/opt/wechat_pay_v3_key/apiclient_key.pem
v3.certPath=/opt/wechat_pay_v3_key/apiclient_cert.pem
v3.certP12Path=/opt/wechat_pay_v3_key/apiclient_cert.p12
v3.platformCertPath=/opt/wechat_pay_v3_key/wx_cert.pem
v3.mchId=
v3.apiKey3=
#v3.apiKey= Api \u5BC6\u94A5
v3.domain= https://newzdc.jinckji.com/prod-api#v3.passengerAppId=
v3.passengerAppId=
#v3.passengerMiniappSecret=
v3.passengerMiniappSecret=v3.driverAppId=
v3.driverMiniappSecret=
微信配置类:
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;/**** <p>不依赖任何第三方 mvc 框架,仅仅作为工具使用简单快速完成支付模块的开发,可轻松嵌入到任何系统里。 </p>*** <p>Node.js 版: https://gitee.com/javen205/TNWX</p>** <p>微信配置</p>** @author Javen*/
@Component
@PropertySource("classpath:wechat/wechat_pay_v3.properties")
@ConfigurationProperties(prefix = "v3")
public class WechatPayV3Bean {private String keyPath;private String certPath;private String certP12Path;private String platformCertPath;private String mchId;private String apiKey;private String apiKey3;private String domain;private String passengerAppId;//乘客小程序private String passengerMiniappSecret; //乘客小程序秘钥private String driverAppId;//司机小程序private String driverMiniappSecret; //司机小程序秘钥public String getDriverAppId() {return driverAppId;}public void setDriverAppId(String driverAppId) {this.driverAppId = driverAppId;}public String getDriverMiniappSecret() {return driverMiniappSecret;}public void setDriverMiniappSecret(String driverMiniappSecret) {this.driverMiniappSecret = driverMiniappSecret;}public String getPassengerMiniappSecret() {return passengerMiniappSecret;}public void setPassengerMiniappSecret(String passengerMiniappSecret) {this.passengerMiniappSecret = passengerMiniappSecret;}public String getPassengerAppId() {return passengerAppId;}public void setPassengerAppId(String passengerAppId) {this.passengerAppId = passengerAppId;}public String getKeyPath() {return keyPath;}public void setKeyPath(String keyPath) {this.keyPath = keyPath;}public String getCertPath() {return certPath;}public void setCertPath(String certPath) {this.certPath = certPath;}public String getCertP12Path() {return certP12Path;}public void setCertP12Path(String certP12Path) {this.certP12Path = certP12Path;}public String getPlatformCertPath() {return platformCertPath;}public void setPlatformCertPath(String platformCertPath) {this.platformCertPath = platformCertPath;}public String getMchId() {return mchId;}public void setMchId(String mchId) {this.mchId = mchId;}public String getApiKey() {return apiKey;}public void setApiKey(String apiKey) {this.apiKey = apiKey;}public String getApiKey3() {return apiKey3;}public void setApiKey3(String apiKey3) {this.apiKey3 = apiKey3;}public String getDomain() {return domain;}public void setDomain(String domain) {this.domain = domain;}@Overridepublic String toString() {return "WxPayV3Bean{" +"keyPath='" + keyPath + '\'' +", certPath='" + certPath + '\'' +", certP12Path='" + certP12Path + '\'' +", platformCertPath='" + platformCertPath + '\'' +", mchId='" + mchId + '\'' +", apiKey='" + apiKey + '\'' +", apiKey3='" + apiKey3 + '\'' +", domain='" + domain + '\'' +'}';}
}

微信支付V3接口:

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.file.FileWriter;
import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.ContentType;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.ijpay.core.IJPayHttpResponse;
import com.ijpay.core.enums.RequestMethod;
import com.ijpay.core.kit.AesUtil;
import com.ijpay.core.kit.HttpKit;
import com.ijpay.core.kit.PayKit;
import com.ijpay.core.kit.WxPayKit;
import com.ijpay.core.utils.DateTimeZoneUtil;
import com.ijpay.wxpay.WxPayApi;
import com.ijpay.wxpay.enums.WxApiType;
import com.ijpay.wxpay.enums.WxDomain;
import com.ijpay.wxpay.model.v3.*;import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayInputStream;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.security.cert.X509Certificate;
import java.util.*;/*** 微信支付V3接口**/
@Slf4j
@Controller
@RequestMapping("wechat/operation/pay")
public class WechatPayV3Controller {@ResourceWechatPayV3Bean wechatPayV3Bean;String serialNo;String platSerialNo;/*** 获取证书序列号** @return*/private String getSerialNumber() {if (StrUtil.isEmpty(serialNo)) {// 获取证书序列号X509Certificate certificate = PayKit.getCertificate(FileUtil.getInputStream(wechatPayV3Bean.getCertPath()));
//            X509Certificate certificate = PayKit.getCertificate(FileUtil.getInputStream("D:\\Documents\\wechat\\apiclient_cert.pem"));serialNo = certificate.getSerialNumber().toString(16).toUpperCase();}System.out.println("serialNo:" + serialNo);return serialNo;}/*** 获取平台证书序列号** @return*/private String getPlatSerialNumber() {if (StrUtil.isEmpty(platSerialNo)) {// 获取平台证书序列号X509Certificate certificate = PayKit.getCertificate(FileUtil.getInputStream(wechatPayV3Bean.getPlatformCertPath()));platSerialNo = certificate.getSerialNumber().toString(16).toUpperCase();}System.out.println("platSerialNo:" + platSerialNo);return platSerialNo;}/*** 保存平台证书** @param associatedData* @param nonce* @param cipherText* @param certPath* @return*/private String savePlatformCert(String associatedData, String nonce, String cipherText, String certPath) {try {AesUtil aesUtil = new AesUtil(wechatPayV3Bean.getApiKey3().getBytes(StandardCharsets.UTF_8));// 平台证书密文解密// encrypt_certificate 中的  associated_data nonce  ciphertextString publicKey = aesUtil.decryptToString(associatedData.getBytes(StandardCharsets.UTF_8),nonce.getBytes(StandardCharsets.UTF_8),cipherText);// 保存证书FileWriter writer = new FileWriter(certPath);writer.write(publicKey);// 获取平台证书序列号X509Certificate certificate = PayKit.getCertificate(new ByteArrayInputStream(publicKey.getBytes()));return certificate.getSerialNumber().toString(16).toUpperCase();} catch (Exception e) {e.printStackTrace();return e.getMessage();}}/*** 刷新平台证书** @return*/@RequestMapping("/get")@ResponseBodypublic String v3Get() {// 获取平台证书列表try {IJPayHttpResponse response = WxPayApi.v3(RequestMethod.GET,WxDomain.CHINA.toString(),WxApiType.GET_CERTIFICATES.toString(),wechatPayV3Bean.getMchId(),getSerialNumber(),null,wechatPayV3Bean.getKeyPath(),"");String timestamp = response.getHeader("Wechatpay-Timestamp");String nonceStr = response.getHeader("Wechatpay-Nonce");String serialNumber = response.getHeader("Wechatpay-Serial");String signature = response.getHeader("Wechatpay-Signature");String body = response.getBody();int status = response.getStatus();log.info("serialNumber: {}", serialNumber);log.info("status: {}", status);log.info("body: {}", body);int isOk = 200;if (status == isOk) {JSONObject jsonObject = JSONUtil.parseObj(body);JSONArray dataArray = jsonObject.getJSONArray("data");// 默认认为只有一个平台证书JSONObject encryptObject = dataArray.getJSONObject(0);JSONObject encryptCertificate = encryptObject.getJSONObject("encrypt_certificate");String associatedData = encryptCertificate.getStr("associated_data");String cipherText = encryptCertificate.getStr("ciphertext");String nonce = encryptCertificate.getStr("nonce");String serialNo = encryptObject.getStr("serial_no");final String platSerialNo = savePlatformCert(associatedData, nonce, cipherText, wechatPayV3Bean.getPlatformCertPath());log.info("平台证书序列号: {} serialNo: {}", platSerialNo, serialNo);}// 根据证书序列号查询对应的证书来验证签名结果boolean verifySignature = WxPayKit.verifySignature(response, wechatPayV3Bean.getPlatformCertPath());System.out.println("verifySignature:" + verifySignature);return body;} catch (Exception e) {e.printStackTrace();return null;}}/*** 统一下单* @param openid* @param orderInfoId* @return*/@GetMapping("/jsApiPay")@ResponseBody@ApiOperation(value = "统一下单")@ApiImplicitParams({@ApiImplicitParam(name = "openid", value = "微信用户openid", dataType = "string", required = true),@ApiImplicitParam(name = "orderInfoId", value = "订单id", dataType = "int", required = true),@ApiImplicitParam(name = "payType", value = "支付类型:1-零钱;2-微信", dataType = "Long", required = false)})@Transactionalpublic AjaxResult jsApiPay(@RequestParam("openid") String openid,@RequestParam("orderInfoId") Long orderInfoId,@RequestParam(value = "payType", required = false) Long payType) {if (StringUtils.isEmpty(openid)) {return AjaxResult.error("微信用户openid不能为空");}if (orderInfoId==null) {return AjaxResult.error("订单编号不能为空");}try {//交易结束时间,暂定10年String timeExpire = DateTimeZoneUtil.dateToTimeZone(System.currentTimeMillis() + 1000 * 60 * 31530);UnifiedOrderModel unifiedOrderModel = new UnifiedOrderModel().setAppid(wechatPayV3Bean.getPassengerAppId()).setMchid(wechatPayV3Bean.getMchId()).setDescription("支付").setOut_trade_no(payOrderId).setTime_expire(timeExpire).setAttach("众人").setNotify_url(wechatPayV3Bean.getDomain().concat("/wechat/operation/pay/payNotify"))//金额的单位是分.setAmount(new Amount().setTotal("100").setPayer(new Payer().setOpenid(openid));log.info("统一下单参数 {}", JSONUtil.toJsonStr(unifiedOrderModel));IJPayHttpResponse response = WxPayApi.v3(RequestMethod.POST,WxDomain.CHINA.toString(),WxApiType.JS_API_PAY.toString(),wechatPayV3Bean.getMchId(),getSerialNumber(),null,wechatPayV3Bean.getKeyPath(),JSONUtil.toJsonStr(unifiedOrderModel));log.info("统一下单响应 {}", response);if (response.getStatus() == HttpStatus.SUCCESS) {// 根据证书序列号查询对应的证书来验证签名结果boolean verifySignature = WxPayKit.verifySignature(response, wechatPayV3Bean.getPlatformCertPath());log.info("verifySignature: {}", verifySignature);if (verifySignature) {String body = response.getBody();JSONObject jsonObject = JSONUtil.parseObj(body);String prepayId = jsonObject.getStr("prepay_id");Map<String, String> map = WxPayKit.jsApiCreateSign(wechatPayV3Bean.getPassengerAppId(), prepayId, wechatPayV3Bean.getKeyPath());log.info("唤起支付参数:{}", map);return AjaxResult.success(map);}}return AjaxResult.error(response.toString());} catch (Exception e) {e.printStackTrace();return AjaxResult.error(e.getMessage());}}/*** 申请交易账单** @param billDate 2020-06-14 当天账单后一天出,不然会出现「账单日期格式不正确」错误* @return 交易账单下载地址*/@RequestMapping("/tradeBill")@ResponseBodypublic String tradeBill(@RequestParam(value = "billDate", required = false) String billDate) {try {if (StrUtil.isEmpty(billDate)) {Calendar calendar = Calendar.getInstance();calendar.setTime(new Date());calendar.add(Calendar.DATE, -1);billDate = DateUtil.format(calendar.getTime(), "YYYY-MM-dd");}Map<String, String> params = new HashMap<>(12);params.put("bill_date", billDate);params.put("bill_type", "ALL");params.put("tar_type", "GZIP");IJPayHttpResponse result = WxPayApi.v3(RequestMethod.GET,WxDomain.CHINA.toString(),WxApiType.TRADE_BILL.toString(),wechatPayV3Bean.getMchId(),getSerialNumber(),null,wechatPayV3Bean.getKeyPath(),params);// 根据证书序列号查询对应的证书来验证签名结果boolean verifySignature = WxPayKit.verifySignature(result, wechatPayV3Bean.getPlatformCertPath());log.info("verifySignature: {}", verifySignature);log.info("result:{}", result);return JSONUtil.toJsonStr(result);} catch (Exception e) {e.printStackTrace();return e.getMessage();}}/*** 申请资金账单** @param billDate 2020-06-14 当天账单后一天出,不然会出现「账单日期格式不正确」错误* @return 资金账单下载地址*/@RequestMapping("/fundFlowBill")@ResponseBodypublic String fundFlowBill(@RequestParam(value = "billDate", required = false) String billDate) {try {if (StrUtil.isEmpty(billDate)) {Calendar calendar = Calendar.getInstance();calendar.setTime(new Date());calendar.add(Calendar.DATE, -1);billDate = DateUtil.format(calendar.getTime(), "YYYY-MM-dd");}Map<String, String> params = new HashMap<>(12);params.put("bill_date", billDate);params.put("account_type", "BASIC");IJPayHttpResponse result = WxPayApi.v3(RequestMethod.GET,WxDomain.CHINA.toString(),WxApiType.FUND_FLOW_BILL.toString(),wechatPayV3Bean.getMchId(),getSerialNumber(),null,wechatPayV3Bean.getKeyPath(),params);// 根据证书序列号查询对应的证书来验证签名结果boolean verifySignature = WxPayKit.verifySignature(result, wechatPayV3Bean.getPlatformCertPath());log.info("verifySignature: {}", verifySignature);log.info("result:{}", result);return JSONUtil.toJsonStr(result);} catch (Exception e) {e.printStackTrace();return e.getMessage();}}@RequestMapping("/billDownload")@ResponseBodypublic String billDownload(@RequestParam(value = "token") String token,@RequestParam(value = "tarType", required = false) String tarType) {try {Map<String, String> params = new HashMap<>(12);params.put("token", token);if (StrUtil.isNotEmpty(tarType)) {params.put("tartype", tarType);}IJPayHttpResponse result = WxPayApi.v3(RequestMethod.GET,WxDomain.CHINA.toString(),WxApiType.BILL_DOWNLOAD.toString(),wechatPayV3Bean.getMchId(),getSerialNumber(),null,wechatPayV3Bean.getKeyPath(),params);log.info("result:{}", result);return JSONUtil.toJsonStr(result);} catch (Exception e) {e.printStackTrace();return e.getMessage();}}/*** 退款接口* @param transactionId* @param outTradeNo* @return*/@RequestMapping("/refund")@ResponseBody@Transactionalpublic String refund(@RequestParam(required = false) String transactionId,@RequestParam(required = false) String outTradeNo) {return estOrderCancelFund(transactionId, outTradeNo);}/*** 退款*/public String estOrderCancelFund(String transactionId, String outTradeNo){try {log.info("transactionId: {}", transactionId);log.info("outTradeNo: {}", outTradeNo);String outRefundNo = PayKit.generateStr();log.info("商户退款单号: {}", outRefundNo);List<RefundGoodsDetail> list = new ArrayList<>();RefundGoodsDetail refundGoodsDetail = new RefundGoodsDetail().setMerchant_goods_id(orderInfo1.getOrderId()).setGoods_name("取消订单").setUnit_price("100")              //金额,单位为分.setRefund_amount("100").setRefund_quantity(1);list.add(refundGoodsDetail);RefundModel refundModel = new RefundModel().setOut_refund_no(outRefundNo).setReason("取消订单")//.setNotify_url(wechatPayV3Bean.getDomain().concat("/wechat/operation/pay/refundNotify")) //退款异步回调通知.setAmount(new RefundAmount().setRefund("100").setGoods_detail(list);if (StrUtil.isNotEmpty(transactionId) && StringUtils.isNotNull(transactionId)) {refundModel.setTransaction_id(transactionId);}if (StrUtil.isNotEmpty(outTradeNo) && StringUtils.isNotNull(outTradeNo)) {refundModel.setOut_trade_no(orderInfo1.getPayOrderId());}log.info("退款参数 {}", JSONUtil.toJsonStr(refundModel));IJPayHttpResponse response = WxPayApi.v3(RequestMethod.POST,WxDomain.CHINA.toString(),WxApiType.DOMESTIC_REFUNDS.toString(),wechatPayV3Bean.getMchId(),getSerialNumber(),null,wechatPayV3Bean.getKeyPath(),
//                "D:\\Documents\\wechat\\apiclient_key.pem",JSONUtil.toJsonStr(refundModel));// 根据证书序列号查询对应的证书来验证签名结果boolean verifySignature = WxPayKit.verifySignature(response, wechatPayV3Bean.getPlatformCertPath());
//            boolean verifySignature = WxPayKit.verifySignature(response, "D:\\Documents\\wechat\\wx_cert.pem");log.info("verifySignature: {}", verifySignature);log.info("退款响应 {}", response);String body = response.getBody();//转换为JSONJSONObject jsonObject = JSONUtil.parseObj(body);if(response.getStatus()==200){//退款成功,处理业务逻辑}if (verifySignature) {return response.getBody();}} catch (Exception e) {e.printStackTrace();return e.getMessage();}return null;}/*** 支付成功回调通知,微信有可能多次回调,业务要做幂等性** @param request* @param response*/@RequestMapping(value = "/payNotify", method = {org.springframework.web.bind.annotation.RequestMethod.POST, org.springframework.web.bind.annotation.RequestMethod.GET})@ResponseBodypublic void payNotify(HttpServletRequest request, HttpServletResponse response) {Map<String, String> map = new HashMap<>(12);try {String timestamp = request.getHeader("Wechatpay-Timestamp");String nonce = request.getHeader("Wechatpay-Nonce");String serialNo = request.getHeader("Wechatpay-Serial");String signature = request.getHeader("Wechatpay-Signature");log.info("timestamp:{} nonce:{} serialNo:{} signature:{}", timestamp, nonce, serialNo, signature);String result = HttpKit.readData(request);log.info("支付通知密文 {}", result);// 需要通过证书序列号查找对应的证书,verifyNotify 中有验证证书的序列号String plainText = WxPayKit.verifyNotify(serialNo, result, signature, nonce, timestamp,wechatPayV3Bean.getApiKey3(), wechatPayV3Bean.getPlatformCertPath());log.info("支付通知明文 {}", plainText);if (StrUtil.isNotEmpty(plainText)) {response.setStatus(200);map.put("code", "SUCCESS");map.put("message", "SUCCESS");//处理自己的业务HashMap hashMap = JSON.parseObject(plainText, HashMap.class);if (hashMap.containsKey("out_trade_no")) {//业务逻辑处理} else {//数据有问题,没有订单编号order_idlog.error("支付通知明文解析失败");}} else {response.setStatus(500);map.put("code", "ERROR");map.put("message", "签名错误");}response.setHeader("Content-type", ContentType.JSON.toString());response.getOutputStream().write(JSONUtil.toJsonStr(map).getBytes(StandardCharsets.UTF_8));response.flushBuffer();} catch (Exception e) {e.printStackTrace();}}}

pom.xml依赖:

<!-- 微信支付工具 --><dependency><groupId>com.github.binarywang</groupId><artifactId>weixin-java-pay</artifactId><version>4.0.0</version></dependency>

微信支付开发文档:微信支付开发者文档

java 微信支付、退款V3相关推荐

  1. java 微信转账 ca_error_java,微信支付退款_微信支付退款接口调用证书出现错误,java,微信支付退款,ssl - phpStudy...

    微信支付退款接口调用证书出现错误 PS:代码是copy腾讯提供的demo,但运行有问题,望大拿能够帮忙解决 加载证书时间出现如下错误: java.io.IOException: DER input, ...

  2. Java 微信支付APP V3示例思路

    这篇文章只是说一下个人的实现思路,大家了解一下实现的思路就行了,并不是全流程可以粘贴复制就能用的案例,个人觉得整体比较麻烦的地方就是前期准备工作,你要去注册账号获取 商户ID 商户证书,商户证书下载后 ...

  3. java微信支付v3系列——7.微信支付之申请退款

    目录 java微信支付v3系列--1.微信支付准备工作 java微信支付v3系列--2.微信支付基本配置 java微信支付v3系列--3.订单创建准备操作 java微信支付v3系列--4.创建订单的封 ...

  4. java微信支付v3系列——8.微信支付之退款成功回调

    目录 java微信支付v3系列--1.微信支付准备工作 java微信支付v3系列--2.微信支付基本配置 java微信支付v3系列--3.订单创建准备操作 java微信支付v3系列--4.创建订单的封 ...

  5. java微信支付v3系列——6.微信支付查询订单API

    目录 java微信支付v3系列--1.微信支付准备工作 java微信支付v3系列--2.微信支付基本配置 java微信支付v3系列--3.订单创建准备操作 java微信支付v3系列--4.创建订单的封 ...

  6. java微信支付v3系列——1.微信支付准备工作

    目录 java微信支付v3系列--1.微信支付准备工作 java微信支付v3系列--2.微信支付基本配置 java微信支付v3系列--3.订单创建准备操作 java微信支付v3系列--4.创建订单的封 ...

  7. java微信支付v3系列——4.创建订单的封装及使用

    目录 java微信支付v3系列--1.微信支付准备工作 java微信支付v3系列--2.微信支付基本配置 java微信支付v3系列--3.订单创建准备操作 java微信支付v3系列--4.创建订单的封 ...

  8. java微信支付v3系列——5.微信支付成功回调

    目录 java微信支付v3系列--1.微信支付准备工作 java微信支付v3系列--2.微信支付基本配置 java微信支付v3系列--3.订单创建准备操作 java微信支付v3系列--4.创建订单的封 ...

  9. java微信支付v3系列——3.订单创建准备操作

    目录 java微信支付v3系列--1.微信支付准备工作 java微信支付v3系列--2.微信支付基本配置 java微信支付v3系列--3.订单创建准备操作 java微信支付v3系列--4.创建订单的封 ...

  10. 微信接口java解密_java使用AES-256-ECB(PKCS7Padding)解密——微信支付退款通知接口指定解密方式...

    1.场景 在做微信支付退款通知接口时,微信对通知的内容做了加密,并且指定用 AES256 解密,官方指定的解密方式如下: 2.导包 org.bouncycastle bcprov-jdk15on 1. ...

最新文章

  1. 【GoLang】GoLang GOPATH 工程管理 最佳实践
  2. python中3or5什么意思_示例详解Python3 or Python2 两者之间的差异
  3. ONVIF网络摄像头(IPC)客户端开发—RTSP RTCP RTP加载H264视频流
  4. .net 服务器自动执行,自动检测服务器使用流量并执行命令脚本
  5. Mac 终端连接linux程服务器并相互传输文件
  6. c语言二叉树的构造输出,C语言数据结构树状输出二叉树,谁能给详细的解释一下...
  7. go语言的安装、环境变量配置及简单使用
  8. 理解$watch ,$apply 和 $digest --- 理解数据绑定过程
  9. 伪静态页面在iis7.0中的配置
  10. Windows 2012部署Exchange2013
  11. 管理感情:精力有限,要么干活,要么内斗
  12. 带你快速读懂ITIL4
  13. STM32单片机(一).相关的开发工具软件
  14. 嵌入式 | 51 单片机《手把手教你51单片机-C语言版》
  15. 2、恩智浦-车规级-MCU :S32K11X GPIO实验
  16. java 汽车加油问题_贪心算法---汽车加油问题
  17. 以衍复为例,聊聊当下的沪深300指数增强
  18. 【机器学习】数据驱动方法在电网稳定分析应用浅谈
  19. springboot项目在外部tomcat运行出现的问题
  20. sicily 4379 bicoloring

热门文章

  1. 苹果2万亿美元市值一夜崩塌!AR/VR或是救命丸,最全头显爆料来了
  2. 《概率论与数理统计》笔记——知识点总结
  3. 新书推荐 |《当计算机体系结构遇到深度学习:面向计算机体系结构设计师的深度学习概论》...
  4. 第四次作业数据备份与还原
  5. Android TV 智能电视/盒子 APP 开发焦点控制 两种方法实例
  6. Filter - 通过拦截器与动态代理实现敏感词汇过滤
  7. matting笔记_一周小结
  8. 22考研DS (2021-06-15)
  9. (三)使用 Vue 脚手架
  10. 为什么等价无穷小不能在加减法中使用