项目实战—springboot整合微信、支付宝NATIVE扫码支付

目录

  • 微信支付
    • 申请微信支付
    • 添加依赖
    • WechatConstant
    • 配置httpClient
    • 生成支付二维码
    • 支付成功回调
    • 订单退款
  • 支付宝支付
    • 申请支付宝支付
    • 添加依赖
    • 配置AlipayClient
    • 生成支付二维码
    • 支付成功回调
    • 订单退款
  • 可能出现的问题

微信支付

申请微信支付

接入微信支付前需要再微信开放平台、公众号平台申请appid和商家号并绑定
微信支付申请操作流程

添加依赖

		<!--    微信支付SDK     --><dependency><groupId>com.github.wechatpay-apiv3</groupId><artifactId>wechatpay-apache-httpclient</artifactId><version>0.4.5</version></dependency>

WechatConstant

public class WechatPayConstant {public static final String CANCEL_PAY_URL="/v3/pay/transactions/out-trade-no/%s/close";public static final String CREATE_PAY_URL="/v3/pay/transactions/native";public static final String QUERY_PAY_URL="/v3/pay/transactions/out-trade-no/%s?mchid=%s";public static final String CREATE_REFUND_URL="/v3/refund/domestic/refunds";public static final String QUERY_REFUND_URL="/v3/refund/domestic/refunds/%s";public static final String TRADE_BILL_URL="/v3/bill/tradebill?bill_date=%s&bill_type=%s";public static final String FLOW_BILL_URL="/v3/bill/fundflowbill?bill_date=%s";public static final String TRADE_STATE_SUCCESS="SUCCESS";public static final String REFUND_STATE_SUCCESS="SUCCESS";
}

配置httpClient

/*** @Author:* @Description:**/
@Component
@Data
@Slf4j
@ConfigurationProperties(prefix = "wxpay")
public class WechatPayConfig {/*** 应用编号*/private String appId;/*** 商户号*/private String mchId;/*** 服务商商户号*/private String slMchId;/*** APIv2密钥*/private String apiKey;/*** APIv3密钥*/private String apiV3Key;/*** 支付通知回调地址*/private String notifyUrl;/*** 退款回调地址*/private String refundNotifyUrl;/*** API 证书中的 key.pem*/private String keyPemPath;/*** key.pem*/private String privateKey;/*** 证书序列号*/private String merchantSerialNumber;/*** 微信支付V3-url前缀*/private String baseUrl;public PrivateKey getPrivateKey(String keyPemPath){InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream(keyPemPath);if(inputStream == null){throw new RuntimeException("私钥文件不存在");}return PemUtil.loadPrivateKey(inputStream);}/*** 获取签名验证器*/public Verifier getVerifier() {// 获取商户私钥PrivateKey privateKey = getPrivateKey(keyPemPath);// 私钥签名对象PrivateKeySigner privateKeySigner = new PrivateKeySigner(merchantSerialNumber, privateKey);// 身份认证对象WechatPay2Credentials wechatPay2Credentials = new WechatPay2Credentials(mchId, privateKeySigner);// 获取证书管理器实例CertificatesManager certificatesManager = CertificatesManager.getInstance();try {// 向证书管理器增加需要自动更新平台证书的商户信息certificatesManager.putMerchant(mchId, wechatPay2Credentials, apiV3Key.getBytes(StandardCharsets.UTF_8));} catch (IOException | GeneralSecurityException | HttpCodeException e) {e.printStackTrace();}try {return certificatesManager.getVerifier(mchId);} catch (NotFoundException e) {e.printStackTrace();throw new RuntimeException("获取签名验证器失败");}}/*** 给容器中加入WechatPay的HttpClient,虽然它是WechatPay的,* 但可以用它给任何外部发请求,因为它只对发给WechatPay的请求做处理而不对发给别的的请求做处理.*/@Beanpublic CloseableHttpClient httpClient(){//私钥PrivateKey merchantPrivateKey = getPrivateKey(keyPemPath);Verifier verifier = getVerifier();WechatPayHttpClientBuilder builder = WechatPayHttpClientBuilder.create().withMerchant(mchId,merchantSerialNumber,merchantPrivateKey).withValidator(new WechatPay2Validator(verifier));
// 				  不需要签名验证
//                withValidator(response->true);CloseableHttpClient httpClient = builder.build();return httpClient;}}

生成支付二维码

public void genQRCode(HttpServletResponse httpResponse, PayDTO payDTO) throws Exception {String key = RedisContents.WX_QR_PREFIX + payDTO.getOrderId();SimpleDateFormat sdfTime = commonUtils.getSdfTime();Date openDate = sdfTime.parse(payDTO.getTimeExpire());long nowTime = new Date().getTime();long openTime = openDate.getTime();long sur = openTime - nowTime;String qrCode = (String) redisTemplate.opsForValue().get(key);if (qrCode != null){QrCodeUtil.generate(qrCode, 300, 300,"png", httpResponse.getOutputStream());return ;}//请求构造HttpPost httpPost = new HttpPost(wechatPayConfig.getBaseUrl()+ WechatPayConstant.CREATE_PAY_URL);String orderId = payDTO.getOrderId();Map<String, Object> bodyData = new HashMap<>();bodyData.put("appid", wechatPayConfig.getAppId());bodyData.put("mchid", wechatPayConfig.getMchId());bodyData.put("description", payDTO.getSubject());bodyData.put("out_trade_no", orderId);bodyData.put("notify_url", wechatPayConfig.getNotifyUrl());// 设置绝对超时时间,即开标时间SimpleDateFormat wxpaySdfDate = commonUtils.getWxpaySdfDate();bodyData.put("time_expire",wxpaySdfDate.format(openDate));// 金额单位是分HashMap<String,Integer> amount = new HashMap<>();//单位是分BigDecimal bigDecimal = new BigDecimal(payDTO.getOrderAmount()).multiply(BigDecimal.valueOf(100));amount.put("total",bigDecimal.intValue());bodyData.put("amount",amount);String jsonReqData = new Gson().toJson(bodyData);StringEntity entity = new StringEntity(jsonReqData,"utf-8");entity.setContentType("application/json");httpPost.setEntity(entity);//请求头httpPost.setHeader("Accept","application/json");//完成签名并执行请求CloseableHttpResponse wxpayResponse =  httpClient.execute(httpPost);Map<String,String> dataMap = null;try{int statusCode = wxpayResponse.getStatusLine().getStatusCode();//成功if(statusCode==200){String body= EntityUtils.toString(wxpayResponse.getEntity());dataMap = new Gson().fromJson(body,HashMap.class);String qrCodeUrl = dataMap.get("code_url");redisTemplate.opsForValue().set(key,qrCodeUrl,sur, TimeUnit.MILLISECONDS);QrCodeUtil.generate(qrCodeUrl, 300, 300,"png", httpResponse.getOutputStream());}//失败else{if(statusCode!=204){String body = EntityUtils.toString(wxpayResponse.getEntity());log.error(body);return ;}}}finally{wxpayResponse.close();}}

支付成功回调

	@PostMapping("/wxpay/notify")public HashMap<String,String> wxPayNotify(@RequestBody Map<String,Object> signalRes, HttpServletResponse response){log.debug("收到微信回调");try{//验签,用密文解密出明文Map<String,String> resource = (Map<String,String>)signalRes.get("resource");String ciphertext = resource.get("ciphertext");String associatedData = resource.get("associated_data");String nonce = resource.get("nonce");String plainText = new AesUtil(wechatPayConfig.getApiV3Key().getBytes(StandardCharsets.UTF_8)).decryptToString(associatedData.getBytes(StandardCharsets.UTF_8),nonce.getBytes(StandardCharsets.UTF_8),ciphertext);//转换HashMap<String,Object> data = new Gson().fromJson(plainText,HashMap.class);// 查询是否支付LambdaQueryWrapper<PaymentInfo> pWrapper = new LambdaQueryWrapper<>();pWrapper.eq(PaymentInfo::getTradeNo,(String)data.get("transaction_id"));PaymentInfo paymentInfoDb = paymentService.getOne(pWrapper);if (paymentInfoDb != null){return null;}synchronized(this){// 保存支付信息PaymentInfo paymentInfo = new PaymentInfo();long id = commonUtils.nextId("wx:pay");paymentInfo.setId(id);paymentInfo.setOrderId((String)data.get("out_trade_no"));paymentInfo.setTradeNo((String)data.get("transaction_id"));paymentInfo.setPaymentType("wechat");paymentInfo.setTradeType((String)data.get("trade_type"));paymentInfo.setTradeState((String)data.get("trade_state"));// 获取金额LinkedTreeMap<String,Object> amountMap = (LinkedTreeMap<String, Object>) data.get("amount");BigDecimal totalAmount = new BigDecimal((Double) amountMap.get("total")).divide(new BigDecimal(100)).setScale(2, BigDecimal.ROUND_DOWN);paymentInfo.setTotalAmount(totalAmount);Date date = new Date();paymentInfo.setTradeTime(date);paymentInfo.setCreateTime(date);paymentInfo.setUpdateTime(date);//交易类型(扫码 刷脸等等)paymentInfo.setTradeType((String)data.get("trade_type"));paymentInfo.setTradeState((String)data.get("trade_state"));//存放全部数据(json)以备不时之需paymentInfo.setContent(plainText);paymentService.save(paymentInfo);log.info("订单{}的支付记录添加成功,支付记录id为{}.",(String)data.get("out_trade_no"),paymentInfo.getId());}return null;} catch(Exception e){log.error(e.getMessage());response.setStatus(HttpStatus.SC_INTERNAL_SERVER_ERROR);HashMap<String,String> map=new HashMap<>();map.put("code","FAIL");map.put("message","支付失败");return map;}}

订单退款

public boolean wechatRefund(String orderId,String tradeNo,String refundAmount) throws IOException {// 请求构造HttpPost httpPost = new HttpPost(wechatPayConfig.getBaseUrl()+ WechatPayConstant.CREATE_REFUND_URL );// 构造请求体HashMap<String,Object> reqData = new HashMap<>();reqData.put("out_trade_no",orderId);//订单编号reqData.put("out_refund_no",tradeNo);//退款单编号reqData.put("reason","xxxx");//退款原因reqData.put("notify_url",wechatPayConfig.getRefundNotifyUrl());//退款通知地址HashMap<String,Object> amount = new HashMap<>();// 单位是分BigDecimal bigDecimal = new BigDecimal(refundAmount).multiply(BigDecimal.valueOf(100));//退款金额amount.put("refund",bigDecimal.intValue());//原订单金额amount.put("total",bigDecimal.intValue());amount.put("currency","CNY");//币种reqData.put("amount",amount);//将参数转换成json字符串String jsonData = new Gson().toJson(reqData);log.info("请求参数 ===> {}"+jsonData);StringEntity entity = new StringEntity(jsonData,"utf-8");httpPost.setEntity(entity);//将请求报文放入请求对象//请求头httpPost.setHeader("content-type","application/json");httpPost.setHeader("Accept","application/json");//设置响应报文格式//完成签名并执行请求CloseableHttpResponse response = httpClient.execute(httpPost);try{//解析响应结果String bodyAsString = EntityUtils.toString(response.getEntity());int statusCode = response.getStatusLine().getStatusCode();if(statusCode == 200){log.info("成功, 退款返回结果 = "+bodyAsString);return true;} else{if(statusCode!=204){log.warn("退款异常:"+bodyAsString);}return false;}}finally{response.close();}}

支付宝支付

申请支付宝支付

接入支付宝支付前需要在支付宝开放平台创建应用和申请商户,并将appid和商家号并绑定
支付宝支付申请流程

添加依赖

      <!--    支付宝支付SDK    --><dependency><groupId>com.alipay.sdk</groupId><artifactId>alipay-sdk-java</artifactId><!-- 对接正式环境需要这个版本及以上--><version>4.38.183.ALL</version></dependency>

配置AlipayClient

支付宝接口参数

@Data
@Component
@ConfigurationProperties(prefix = "alipay")
public class AlipayProperty {// 应用idprivate String appId;// 应用私钥private String appPrivateKey;// 支付宝公钥private String alipayPublicKey;// 支付宝异步通知地址private String notifyUrl;// 支付宝网关private String gatewayUrl;
}

配置AlipayClient

/*** 支付宝支付客户端* 验签时 charset要一致,不然会验签失败* @return*/@Beanpublic AlipayClient alipayClient(){return new DefaultAlipayClient(alipayProperty.getGatewayUrl(),alipayProperty.getAppId(),alipayProperty.getAppPrivateKey(),"json",AlipayConstants.CHARSET_UTF8,alipayProperty.getAlipayPublicKey(),AlipayConstants.SIGN_TYPE_RSA2);}

生成支付二维码

/*** 生成支付二维码* @return*/public void genQRCode(HttpServletResponse httpResponse,PayDTO payDTO) throws Exception {String key = RedisContents.ZFB_QR_PREFIX + payDTO.getOrderId();String timeExpire = payDTO.getTimeExpire();Date nowDate = new Date();SimpleDateFormat sdfTime = commonUtils.getSdfTime();Date openDate = sdfTime.parse(timeExpire);long nowTime = nowDate.getTime();long openTime = openDate.getTime();String qrCode = (String) redisTemplate.opsForValue().get(key);if (qrCode != null){QrCodeUtil.generate(qrCode, 300, 300,"png", httpResponse.getOutputStream());return ;}AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest();// 异步通知支付结果request.setNotifyUrl(alipayProperty.getNotifyUrl());//将商品的属性填写进去JSONObject bizContent = new JSONObject();bizContent.put("out_trade_no", payDTO.getOrderId());bizContent.put("total_amount", payDTO.getOrderAmount());bizContent.put("subject", payDTO.getSubject());// 设置绝对超时时间,即开标时间bizContent.put("time_expire",timeExpire);request.setBizContent(bizContent.toString());AlipayTradePrecreateResponse response = null;try {response = alipayClient.execute(request);} catch (AlipayApiException e) {throw new RuntimeException(e);}if(response.isSuccess()){log.info("++++++++++++++++调用成功++++++++++++++++");String respQrCode = response.getQrCode();// 保存respQrCode到redisredisTemplate.opsForValue().set(key,respQrCode,sur, TimeUnit.MILLISECONDS);// 生成支付二维码并输出到响应QrCodeUtil.generate(respQrCode, 300, 300,"png", httpResponse.getOutputStream());// JSAPI支付宝收银台
//            String form = "";
//            form = alipayClient.pageExecute(request).getBody();
//            //设置响应结果,将返回的内容写出到浏览器
//            httpResponse.setContentType("text/html;charset=UTF-8");
//            httpResponse.getWriter().write(form);//直接将完整的表单html输出到页面
//            httpResponse.getWriter().flush();
//            httpResponse.getWriter().close();}

支付成功回调

 /*** 支付宝异步回调通知* @return*/@AutoLog(value = "支付宝支付通知")@PostMapping("/alipay/notify")public void alipayNotify(HttpServletRequest request, HttpServletResponse response) throws Exception {request.setCharacterEncoding("UTF-8");response.setCharacterEncoding("UTF-8");log.info("+++++++++++支付宝异步通知+++++++++++");String outTradeNo = request.getParameter("out_trade_no");String tradeNo = request.getParameter("trade_no");String totalAmount = request.getParameter("total_amount");// TODO 业务处理
//        商户订单号(out_trade_no):商户网站生成的唯一订单号。
//        支付宝交易号(trade_no):支付宝交易凭证号。
//        交易状态(trade_status):交易的当前状态,包括支付成功、支付失败等。
//        通知时间(notify_time):支付宝服务器发送通知的时间。
//        交易金额(total_amount):本次交易支付的订单金额。Map<String, String[]> requestParams = request.getParameterMap();PrintWriter out = response.getWriter();try {// 这里首先验签 验证是支付宝发来的请求HashMap<String, String> params = new HashMap<>();for (Iterator<String> iter = requestParams.keySet().iterator(); iter.hasNext(); ) {String name = iter.next();String[] values = requestParams.get(name);String valueStr = "";for (int i = 0; i < values.length; i++) {valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";}
//                    valueStr = new String(valueStr.getBytes(),"UTF-8");params.put(name, valueStr);}
//                params.put("subject","保费");log.info("sign params:{}",params);log.info("alipay params:{}",alipayProperty);// 验证签名,确保是支付宝发送的// 验签失败可以原因// 1、参数2为支付宝公钥// 2、字符编码不统一  AlipayClient的字符编码要与参数3的字符编码统一boolean signVerified = AlipaySignature.rsaCheckV1(params,alipayProperty.getAlipayPublicKey(),AlipayConstants.CHARSET_UTF8,AlipayConstants.SIGN_TYPE_RSA2);if (!signVerified) {log.error("验签失败");out.print("fail");return;}// 查询是否支付LambdaQueryWrapper<PaymentInfo> pWrapper = new LambdaQueryWrapper<>();pWrapper.eq(PaymentInfo::getTradeNo,tradeNo);PaymentInfo paymentInfoDb = paymentService.getOne(pWrapper);if (paymentInfoDb != null){return;}// 保存支付信息PaymentInfo paymentInfo = new PaymentInfo();long id = commonUtils.nextId("ali:pay");paymentInfo.setId(id);paymentInfo.setOrderId(outTradeNo);paymentInfo.setTradeNo(tradeNo);paymentInfo.setPaymentType("alipay");paymentInfo.setTradeType("NATIVE");paymentInfo.setTradeState(request.getParameter("trade_status"));paymentInfo.setTotalAmount(new BigDecimal(totalAmount));Date date = new Date();paymentInfo.setTradeTime(date);paymentInfo.setCreateTime(date);paymentInfo.setUpdateTime(date);paymentService.save(paymentInfo);}catch (Exception e){}// 获取支付订单号log.info("异步通知参数outTradeNo:{}",outTradeNo);log.info("异步通知参数tradeNo:{}",tradeNo);}

订单退款

/*** 支付宝退款* @return*/public boolean alipayRefund(String tradeNo,String refundAmount) {AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();// TODO 业务代码查询订单信息JSONObject bizContent = new JSONObject();bizContent.put("trade_no", tradeNo);bizContent.put("refund_amount", refundAmount);bizContent.put("out_request_no", "HZ01RF001");request.setBizContent(bizContent.toString());try{AlipayTradeRefundResponse response = alipayClient.execute(request);if(response.isSuccess()){System.out.println("退款成功");return true;} else {System.out.println("退款失败");return false;}}catch (Exception e){e.printStackTrace();return false;}}

可能出现的问题

1、解决微信支付 java.security.InvalidKeyException: Illegal key size

2、关于支付宝、微信支付成功回调验签失败问题,仔细检查公钥,字符集编码,参数等

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/30726.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Python驯化-01】python中set去重数据每次结果不一致问题解决

【Python驯化-01】python中set去重数据每次结果不一致问题解决 本次修炼方法请往下查看 &#x1f308; 欢迎莅临我的个人主页 &#x1f448;这里是我工作、学习、实践 IT领域、真诚分享 踩坑集合&#xff0c;智慧小天地&#xff01; &#x1f387; 免费获取相关内容文档关注…

信息安全系列课程之网络空间测绘与态势感知技术揭秘(一)

今天&#xff0c;我们来讲一下网络安全&#xff01; 本文章仅提供学习&#xff0c;切勿将其用于不法手段&#xff01; 目前&#xff0c;在信息安全攻防领域&#xff0c;主要分为了两个技术发展方向&#xff0c;分别为渗透测试&#xff08;红队技术&#xff09; 和 安全运维&a…

考研计组chap2数据的表示和运算

3一、进位计数制 1.r进制 第i位表示r进制的权为i 2.进制转换 &#xff08;1&#xff09;r->10 对应位置数*权值 &#xff08;2&#xff09;2 -> 16 or 8 每三位2进制数可表示1位16进制 每四位2进制数可表示1位16进制 so 分开之后转为16进制即可 eg&#xff1a;1…

江苏省SAP代理商之选:无锡哲讯为企业信息化管理开启新篇章

江苏省&#xff0c;作为中国东部沿海的经济重镇&#xff0c;拥有众多行业领先企业。随着数字化转型的浪潮&#xff0c;SAP代理商在这片热土上扮演着至关重要的角色。无锡哲讯智能科技有限公司&#xff08;iP-Solutions&#xff09;&#xff0c;作为SAP在华东地区的金牌合作伙伴…

基于51单片机恒温箱设计

基于51单片机恒温箱设计 &#xff08;程序&#xff0b;原理图&#xff0b;设计报告&#xff09; 功能介绍 具体功能&#xff1a; 本设计由STC89C52单片机电路数字温度传感器DS18B20电路按键电路蜂鸣器报警电路继电器控制电路LCD1602液晶显示电路电源电路组成。 1.LCD1602液…

Spring源码中是如何使用设计模式六大原则的

设计模式的六大原则&#xff0c;通常指的是SOLID原则&#xff0c;它们是面向对象设计中用于提高代码可维护性、灵活性和可扩展性的五个指导原则&#xff0c;学习六大原则&#xff0c;可以让你的代码变得高级而优雅&#xff0c;今天的内容 V 哥结合 Spring源码中如何运用六大原则…

偏微分方程算法之抛物型方程差分格式编程示例四(Richardson外推)

目录 一、研究问题 二、C++代码 三、结果分析 一、研究问题 已知其精确解为。分别取以下三种步长: ①

流程引擎框架

SpiffWorkflow python 流程引擎框架哪个好 Camunda 核心表介绍 https://zhuanlan.zhihu.com/p/645786758 camunda流程引擎基本使用&#xff08;笔记&#xff09; https://blog.csdn.net/weixin_46949627/article/details/129255647 python连接FastDfs服务封装类 https://blog.c…

树形dp,CF 1926 G - Vlad and Trouble at MIT

一、题目 1、题目描述 2、输入输出 2.1输入 2.2输出 3、原题链接 Problem - G - Codeforces 二、解题报告 1、思路分析 考虑每个结点最终状态只可能为和P连通或者和S连通 我们我们自然而然的将问题划分为这样的状态 f[x][0]代表结点x和P连通需要割掉最少的边 f[x][1]代…

Windows Server配置NFS,做ESXI共享存储

1:登录wINDOWS系统&#xff0c;点击添加角色和功能。 2:根据向导提示&#xff0c;一路下一步。在服务器角色中选择文件和存储服务器在文件和iSCSI服务中勾选NFS服务器。 3&#xff1a;按照提示一路下一步&#xff0c;安装NFS。 4&#xff1a;安装完成后关闭安装界面。 5&#x…

代码随想录算法训练营第六十五天 | 岛屿数量 深搜、岛屿数量 广搜、岛屿的最大面积

岛屿数量 深搜 题目链接&#xff1a;99. 岛屿数量 文字讲解&#xff1a;99. 岛屿数量 | 代码随想录 解题思路 本题已经说明&#xff0c;只有水平方向和竖直方向才能组成岛屿 本题思路&#xff0c;是遇到一个没有遍历过的节点陆地&#xff0c;计数器就加一&#xff0c;然后把…

为电脑小白推荐的5款实用工具软件

​ 电脑上的各类软件有很多&#xff0c;除了那些常见的大众化软件&#xff0c;还有很多不为人知的小众软件&#xff0c;专注于实用功能&#xff0c;简洁干净、功能强悍。 1.磁盘空间分析——TreeSize Free ​ TreeSize Free是一款免费的磁盘空间分析工具&#xff0c;能够扫描…

Sip协议(四) -注册流程

Sip协议(四) -注册流程 本文主要介绍下sip协议中, agent的注册流程. 一: 流程图 简单的流程图如下: agent发起注册fs 返回401 ,并携带WWW-Authenticateagent第二次发起注册,增加Authorizationfs返回授权成功, 或者失败. 二: sip流程 发起注册REGISTER 首先agent发起注册请求…

重磅!鹅厂大牛带你30分钟玩转AI智能结对编程!

在大模型时代&#xff0c;人工智能技术的突破性进展正重塑着软件开发的面貌。AI的融入不仅优化了代码编写过程&#xff0c;更开启了智能编程的新纪元&#xff0c;为开发者带来了前所未有的工作效率和创新可能。AI结对编程不仅能够极大提升研发效率&#xff0c;还能通过智能分析…

Java基础入门day65

day65 web项目 页面设计 仿照小米官网&#xff0c;将首页保存到本地为一个html页面&#xff0c;再将html页面保存为jsp页面&#xff0c;在项目中的web.xml文件中配置了欢迎页 <welcome-file-list><welcome-file>TypesServlet</welcome-file> </welcome-…

linux源码编译

1/进入源码目录 cd linux.4.9.1 2. 从当前机器的启动目录拷贝配置信息到源代码目录。这步操作的意思是我们编译内核的配置采用用当前环境一致的配置。 cp -v /boot/config-$(uname -r) .config 3.配置界面 make menuconfig 4/先编译所有模块&#xff0c;确保正确 make -j…

【查缺补漏】python

python查缺补漏 底板除 还有一种除法是//&#xff0c;称为地板除&#xff0c;两个整数的除法仍然是整数&#xff1a; >>> 10 // 3 3你没有看错&#xff0c;整数的地板除//永远是整数&#xff0c;即使除不尽。要做精确的除法&#xff0c;使用/就可以。 因为//除法只…

rsa加签验签C#和js、java、微信小程序互通

js实现rsa加签验签 https://github.com/kjur/jsrsasign 11.1.0版本 解压选择需要的版本&#xff0c;这里选择all版本了 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>JS RSA加签验签</title&g…

有趣网站分享 - 生成 O‘Reilly 类型封面

文章目录 网站介绍效果 网站介绍 –> O’RLY 封面工厂 https://orly.nanmu.me 你可以… 设置文本内容 选择图片 选择颜色 效果 2024-06-20&#xff08;四&#xff09;

机器人----控制方式

位置控制 点位控制 点到点--PTP 只关心起点和目标点&#xff0c;不关心走过的轨迹。 连续轨迹控制 CP(continus path) eg&#xff1a;焊接&#xff0c;切割。 力控制 使用多大的力进行控制。 eg:用多大的力写字。