第一步配置API key:微信支付文档
第二步下载并配置商户证书:微信支付文档
第三步对接微信支付接口:微信支付文档
<!-- 微信支付API -->
<dependency>
<groupId>com.github.wechatpay-apiv3</groupId>
<artifactId>wechatpay-java</artifactId>
<version>0.2.12</version>
</dependency>
<!-- SBSS 用到的HTTP工具包:okhttp 3.13.1 -->
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>3.13.1</version>
</dependency>
<!--工具类-->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.3.1</version>
</dependency>
weixin:
# AppID(小程序ID)
appId: xxxxxxx
# AppSecret(小程序密钥)
appSecret: xxxxxxx
# 接口链接
url: https://api.weixin.qq.com
# 认证类型
schema: xxxxxxx
# 商户号ID
mchid: xxxxxxx
# 商户证书序号
serialNo: xxxxxxx
# 商户私钥字符串
privateKey: xxxxxxx
#支付接口链接
payUrl: https://api.mch.weixin.qq.com
#回调接口链接
notifyUrl: https://xxx.xxx.com
#支付金额:1元
amount: 100
#apiv3密钥
apiV3Key: xxxxxxx
package com.example.demo.config;
import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.math.BigDecimal;
@Data
@Component
public class WechatConfig {
/**
* AppID(小程序ID)
*/
@Value("${weixin.appId}")
private String appId;
/**
* AppSecret(小程序密钥)
*/
@Value("${weixin.appSecret}")
private String appSecret;
/**
* 微信接口链接
*/
@Value("${weixin.url}")
private String url;
/**
* 商户私钥字符串(下载并配置商户证书中的私钥)
*/
@Value("${weixin.privateKey}")
private String privateKey;
/**
* 商户号
*/
@Value("${weixin.mchid}")
private String mchid;
/**
* 商户证书序号
*/
@Value("${weixin.serialNo}")
private String serialNo;
/**
* 认证类型
*/
@Value("${weixin.schema}")
private String schema;
/**
* 支付接口链接
*/
@Value("${weixin.payUrl}")
private String payUrl;
/**
* 回调路径
*/
@Value("${weixin.notifyUrl}")
private String notifyUrl;
/**
* 支付金额(单位是分)
*/
@Value("${weixin.amount}")
private BigDecimal amount;
/**
* 认证类型
*/
@Value("${weixin.apiV3Key}")
private String apiV3Key;
}
package com.example.demo.util;
import com.example.demo.config.WechatConfig;
import com.wechat.pay.java.core.util.PemUtil;
import okhttp3.HttpUrl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.util.Base64;
@Component
public class WechatCreateToken {
@Autowired
private WechatConfig wechatConfig;
/**
* 获取签名认证信息
* @param method 请求类型
* @param url 请求路径
* @param timestamp 时间戳
* @param nonceStr 随机数
* @param body 请求参数
* @return 结果
*/
public String getAuthorization(String method, HttpUrl url, long timestamp, String nonceStr, String body){
//构造签名串
String message = buildMessage(method, url, timestamp, nonceStr, body);
//Base64编码得到签名值
String signature = sign(message);
return "mchid=\"" + wechatConfig.getMchid() + "\","
+ "serial_no=\"" + wechatConfig.getSerialNo() + "\","
+ "nonce_str=\"" + nonceStr + "\","
+ "timestamp=\"" + timestamp + "\","
+ "signature=\"" + signature + "\"";
}
/**
* 构造签名串
* @param method 请求类型
* @param url 请求路径
* @param timestamp 时间戳
* @param nonceStr 随机数
* @param body 请求参数
* @return 结果
*/
String buildMessage(String method, HttpUrl url, long timestamp, String nonceStr, String body) {
String canonicalUrl = url.encodedPath();
if (url.encodedQuery() != null) {
canonicalUrl += "?" + url.encodedQuery();
}
return method + "\n"
+ canonicalUrl + "\n"
+ timestamp + "\n"
+ nonceStr + "\n"
+ body + "\n";
}
/**
*对签名结果进行Base64编码得到签名值
* @param message 参数
* @return 结果
*/
public String sign(String message){
try {
//加载商户私钥(privateKey:私钥字符串)
Signature sign = Signature.getInstance("SHA256withRSA");
PrivateKey merchantPrivateKey = PemUtil.loadPrivateKeyFromString(wechatConfig.getPrivateKey());
sign.initSign(merchantPrivateKey);
sign.update(message.getBytes(StandardCharsets.UTF_8));
return Base64.getEncoder().encodeToString(sign.sign());
} catch (NoSuchAlgorithmException | InvalidKeyException | SignatureException e) {
throw new IllegalArgumentException(e.getMessage());
}
}
/**
*获取支付签名值
* @param timestamp 时间戳
* @param nonceStr 随机数
* @param prepayId 预支付交易会话标识
* @return 结果
*/
public String getPaySignStr(long timestamp, String nonceStr,String prepayId){
//签名
String message = wechatConfig.getAppId() + "\n"
+ timestamp + "\n"
+ nonceStr + "\n"
+ "prepay_id=" + prepayId + "\n";
return sign(message);
}
}
package com.example.demo.util;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.example.demo.config.WechatConfig;
import okhttp3.HttpUrl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
@Component
public class WechatUtil {
@Autowired
private WechatConfig wechatConfig;
@Autowired
private WechatCreateToken wechatCreateToken;
/**
* 获取小程序全局唯一后台接口调用凭据,token有效期为7200s
* @return 结果
*/
public String getAccessToken(){
//请求参数
JSONObject paramMap = new JSONObject();
paramMap.put("grant_type","client_credential");
paramMap.put("appid", wechatConfig.getAppId());
paramMap.put("secret", wechatConfig.getAppSecret());
String body = HttpUtil.createGet(wechatConfig.getUrl() + "/cgi-bin/token")
.form(paramMap)
.execute()
.body();
//返回值
JSONObject result = JSONUtil.parseObj(body);
if (result.get("errcode") != null){
throw new IllegalArgumentException("获取token失败");
}
return result.get("access_token", String.class);
}
/**
* 手机号验证
* @param accessToken 接口调用凭证
* @param code 微信code
* @return 结果
*/
public String getPhoneNumber(String accessToken,String code){
//请求参数
JSONObject paramMap = new JSONObject();
paramMap.put("code", code);
String body = HttpUtil.createPost(wechatConfig.getUrl() + "/wxa/business/getuserphonenumber?access_token=" + accessToken)
.header("Content-Type", "application/json")
.body(paramMap.toString())
.execute()
.body();
//返回值
JSONObject result = JSONUtil.parseObj(body);
if (result.get("errcode").equals(0)){
//用户手机号信息
Map phoneInfo = result.get("phone_info", Map.class);
return String.valueOf(phoneInfo.get("phoneNumber"));
}else {
throw new IllegalArgumentException("code无效");
}
}
/**
* 获取用户openid
* @param code 微信code
* @return 结果
*/
public String getOpenid(String code){
//请求参数
JSONObject paramMap = new JSONObject();
paramMap.put("js_code", code);
paramMap.put("appid", wechatConfig.getAppId());
paramMap.put("secret", wechatConfig.getAppSecret());
paramMap.put("grant_type", "authorization_code");
String body = HttpUtil.createGet(wechatConfig.getUrl() + "/sns/jscode2session")
.form(paramMap)
.execute()
.body();
//返回值
JSONObject result = JSONUtil.parseObj(body);
if (result.get("openid") != null){
return result.get("openid", String.class);
}else {
throw new IllegalArgumentException("微信认证失败");
}
}
/**
*获取微信支付的必要参数
*/
public Map<String,Object> getPaySignParam(String openid) {
//商户订单号(自定义)
String orderNo = "WX" + DateUtil.format(new Date(), "yyyyMMddHHmmss") + RandomUtil.randomNumbers(12);
//预支付交易会话标识
String prepayId = getPrepayId(openid, orderNo);
//时间戳
long timestamp = System.currentTimeMillis() / 1000;
//随机数
String nonceStr = UUID.randomUUID().toString().replace("-", "");
//签名
String paySign = wechatCreateToken.getPaySignStr(timestamp, nonceStr, prepayId);
//返回参数
HashMap<String, Object> resultParam = new HashMap<>();
resultParam.put("orderId", orderNo);
resultParam.put("timeStamp", timestamp + "");
resultParam.put("nonceStr", nonceStr);
resultParam.put("package", "prepay_id=" + prepayId);
resultParam.put("signType", "RSA");
resultParam.put("paySign", paySign);
return resultParam;
}
/**
* 获取预支付交易会话标识(生成订单)
* @param openid 微信id
* @param orderNo 商户订单号
* @return 结果
*/
public String getPrepayId(String openid,String orderNo){
//请求参数
JSONObject param = new JSONObject();
//小程序id
param.put("appid", wechatConfig.getAppId());
//商户号id
param.put("mchid", wechatConfig.getMchid());
//商品描述
param.put("description", "xxx费用");
//商户订单号
param.put("out_trade_no", orderNo);
//支付通知回调接口(需要https路径)
param.put("notify_url", wechatConfig.getNotifyUrl() + "/notifyUrl");
//金额
JSONObject amountParam = new JSONObject();
amountParam.put("total", wechatConfig.getAmount());
amountParam.put("currency", "CNY");
param.put("amount", amountParam);
//支付者信息
JSONObject payerParam = new JSONObject();
payerParam.put("openid", openid);
param.put("payer",payerParam);
//随机数
String nonceStr = UUID.randomUUID().toString().replace("-", "");
//时间戳
long timestamp = System.currentTimeMillis() / 1000;
//下单生成预订单
String body = param.toString();
//生成签名
String authorization = wechatConfig.getSchema() + " " + wechatCreateToken.getAuthorization("POST", Objects.requireNonNull(HttpUrl.parse(wechatConfig.getPayUrl() + "/v3/pay/transactions/jsapi")), timestamp, nonceStr, body);
String result = HttpUtil.createPost(wechatConfig.getPayUrl() + "/v3/pay/transactions/jsapi")
.header("Authorization", authorization)
.header("Content-Type", "application/json")
.header("Accept","application/json")
.body(body)
.execute()
.body();
//返回值
JSONObject data = JSONUtil.parseObj(result);
if (data.get("prepay_id") == null){
throw new IllegalArgumentException("下单失败");
}
return data.get("prepay_id",String.class);
}
/**
*获取订单信息
*/
public Map<String,Object> getOrderInfo(String orderNo){
//请求参数
JSONObject paramMap = new JSONObject();
paramMap.put("mchid", wechatConfig.getMchid());
//随机数
String nonceStr = UUID.randomUUID().toString().replace("-", "");
//时间戳
long timestamp = System.currentTimeMillis() / 1000;
String authorization = wechatConfig.getSchema() + " " + wechatCreateToken.getAuthorization("GET", Objects.requireNonNull(HttpUrl.parse(wechatConfig.getPayUrl() + "/v3/pay/transactions/out-trade-no/" + orderNo + "?mchid=" + wechatConfig.getMchid())), timestamp, nonceStr, "");
String result = HttpUtil.createGet(wechatConfig.getPayUrl() + "/v3/pay/transactions/out-trade-no/" + orderNo)
.header("Authorization",authorization)
.header("Accept","application/json")
.form(paramMap)
.execute()
.body();
JSONObject data = JSONUtil.parseObj(result);
String tradeState = data.get("trade_state",String.class);
if ("SUCCESS".equals(tradeState)) {
//支付成功
Map<String,Object> map = new HashMap<>();
map.put("out_trade_no",data.get("out_trade_no",String.class));
map.put("success_time",data.get("success_time",Date.class));
BigDecimal money = new BigDecimal(data.get("amount", Map.class).get("payer_total").toString());
map.put("amount",money.divide(new BigDecimal(100),2, RoundingMode.HALF_UP));
return map;
} else {
throw new IllegalArgumentException("支付失败");
}
}
}
实体类
package com.example.demo.dto;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import java.io.Serializable;
@Data
public class LoginDTO implements Serializable{
@NotBlank(message = "手机code不能为空")
@ApiModelProperty("手机code")
private String weixinCode;
@NotBlank(message = "登录code不能为空")
@ApiModelProperty("登录code")
private String loginCode;
}
package com.example.demo.dto;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
@Data
public class WechatDTO implements Serializable {
@ApiModelProperty("随机串")
private String nonceStr;
@ApiModelProperty("签名")
private String signature;
@ApiModelProperty("证书序列号")
private String serialNo;
@ApiModelProperty("时间戳")
private String timestamp;
@ApiModelProperty("加密类型")
private String signatureType;
@ApiModelProperty("报文")
private String body;
}
控制层controller
package com.example.demo.controller;
import com.alibaba.fastjson.JSONObject;
import com.example.demo.dto.LoginDTO;
import com.example.demo.dto.WechatDTO;
import com.example.demo.service.WechatService;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Map;
@RestController
public class WechatController {
@Autowired
private WechatService wechatService;
@ApiOperation(value = "授权登录获取手机号")
@RequestMapping(value = "/auth", method = RequestMethod.POST)
public String login(@Valid @RequestBody LoginDTO loginDTO){
return wechatService.login(loginDTO);
}
@ApiOperation(value = "获取支付签名")
@GetMapping("/getPaySign")
public Map<String,Object> getPaySign(){
return wechatService.getPaySign();
}
@ApiOperation(value = "获取订单信息")
@GetMapping("/getOrderInfo")
public Map<String,Object> getOrderInfo(String orderNo){
return wechatService.getOrderInfo(orderNo);
}
@ApiOperation("支付通知(回调)")
@RequestMapping(value = "/notifyUrl",method = RequestMethod.POST)
@ResponseBody
public JSONObject payNotifyUrl(HttpServletRequest request) {
//获取报文
String body = getRequestBody(request);
//随机串
String nonceStr = request.getHeader("Wechatpay-Nonce");
//微信传递过来的签名
String signature = request.getHeader("Wechatpay-Signature");
//证书序列号(微信平台)
String serialNo = request.getHeader("Wechatpay-Serial");
//时间戳
String timestamp = request.getHeader("Wechatpay-Timestamp");
//加密类型
String signatureType = request.getHeader("Wechatpay-Signature-Type");
WechatDTO wechatDTO = new WechatDTO();
wechatDTO.setBody(body);
wechatDTO.setNonceStr(nonceStr);
wechatDTO.setSerialNo(serialNo);
wechatDTO.setTimestamp(timestamp);
wechatDTO.setSignatureType(signatureType);
wechatDTO.setSignature(signature);
wechatService.payNotifyUrl(wechatDTO);
JSONObject jsonObject = new JSONObject();
jsonObject.put("code","SUCCESS");
jsonObject.put("message","成功");
return jsonObject;
}
/**
* 读取请求数据流
*/
private String getRequestBody(HttpServletRequest request) {
StringBuffer sb = new StringBuffer();
try (ServletInputStream inputStream = request.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
) {
String line;
while ((line = reader.readLine()) != null) {
sb.append(line);
}
} catch (IOException e) {
throw new IllegalArgumentException(e);
}
return sb.toString();
}
}
service接口
package com.example.demo.service;
import com.example.demo.dto.LoginDTO;
import com.example.demo.dto.WechatDTO;
import java.util.Map;
public interface WechatService {
String login(LoginDTO loginDTO);
Map<String,Object> getPaySign();
void payNotifyUrl(WechatDTO wechatDTO);
Map<String, Object> getOrderInfo(String orderNo);
}
业务逻辑处理
package com.example.demo.service.impl;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONObject;
import com.example.demo.config.WechatConfig;
import com.example.demo.dto.LoginDTO;
import com.example.demo.dto.WechatDTO;
import com.example.demo.service.WechatService;
import com.example.demo.util.AesUtil;
import com.example.demo.util.WechatUtil;
import com.wechat.pay.java.service.partnerpayments.jsapi.model.Transaction;
import com.wechat.pay.java.core.notification.NotificationParser;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.security.GeneralSecurityException;
import java.util.Map;
@Slf4j
@Service
public class WechatServiceImpl implements WechatService {
@Autowired
private WechatUtil wechatUtil;
@Autowired
private WechatConfig wechatConfig;
@Override
public String login(LoginDTO loginDTO) {
//获取微信用户ID,存储在数据库中
String openid = wechatUtil.getOpenid(loginDTO.getLoginCode());
//获取小程序全局唯一后台接口调用凭据
String accessToken = wechatUtil.getAccessToken();
//微信获取手机号
String phoneNumber = wechatUtil.getPhoneNumber(accessToken, loginDTO.getWeixinCode());
return phoneNumber;
}
@Override
public Map<String,Object> getPaySign() {
//获取数据库存储的微信id
String openid = "xxxx";
return wechatUtil.getPaySignParam(openid);
}
@Override
public Map<String, Object> getOrderInfo(String orderNo) {
return wechatUtil.getOrderInfo(orderNo);
}
@Override
public void payNotifyUrl(WechatDTO wechatDTO) {
//第一种
manualDecryption(wechatDTO);
//第二种
notificationParser(wechatDTO);
}
}
第一种使用AesUtil解密工具类
package com.example.demo.util;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.security.GeneralSecurityException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
import javax.crypto.Cipher;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.GCMParameterSpec;
import javax.crypto.spec.SecretKeySpec;
public class AesUtil {
static final int KEY_LENGTH_BYTE = 32;
static final int TAG_LENGTH_BIT = 128;
private final byte[] aesKey;
public AesUtil(byte[] key) {
if (key.length != KEY_LENGTH_BYTE) {
throw new IllegalArgumentException("无效的ApiV3Key,长度必须为32个字节");
}
this.aesKey = key;
}
public String decryptToString(byte[] associatedData, byte[] nonce, String ciphertext) throws GeneralSecurityException, IOException {
try {
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
SecretKeySpec key = new SecretKeySpec(aesKey, "AES");
GCMParameterSpec spec = new GCMParameterSpec(TAG_LENGTH_BIT, nonce);
cipher.init(Cipher.DECRYPT_MODE, key, spec);
cipher.updateAAD(associatedData);
return new String(cipher.doFinal(Base64.getDecoder().decode(ciphertext)), StandardCharsets.UTF_8);
} catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
throw new IllegalStateException(e);
} catch (InvalidKeyException | InvalidAlgorithmParameterException e) {
throw new IllegalArgumentException(e);
}
}
}
业务处理
public void manualDecryption(WechatDTO wechatDTO){
//证书序列号(微信平台)
if (wechatDTO.getSerialNo().equals(wechatConfig.getSerialNo())){
throw new IllegalArgumentException("验签失败");
}
//附加数据
String associatedData = (String) JSONUtil.getByPath(JSONUtil.parse(wechatDTO.getBody()), "resource.associated_data");
//数据密文
String ciphertext = (String) JSONUtil.getByPath(JSONUtil.parse(wechatDTO.getBody()), "resource.ciphertext");
//随机串
String nonce = (String) JSONUtil.getByPath(JSONUtil.parse(wechatDTO.getBody()), "resource.nonce");
//解密
try {
//验签成功
String decryptData = new AesUtil(wechatConfig.getApiV3Key().getBytes(StandardCharsets.UTF_8)).decryptToString(associatedData.getBytes(StandardCharsets.UTF_8), nonce.getBytes(StandardCharsets.UTF_8), ciphertext);
//支付参数
Transaction transaction = JSONObject.parseObject(decryptData, Transaction.class);
log.info("参数-------" + JSONObject.toJSONString(transaction));
//订单编号(本地生成)
String outTradeNo = transaction.getOutTradeNo();
//通过本地订单编号处理业务逻辑(并将付款编号保存到本地)
log.info("订单编码" + outTradeNo);
//业务逻辑处理
if (transaction.getTradeState().equals(Transaction.TradeStateEnum.SUCCESS)) {
}
} catch (GeneralSecurityException | IOException e) {
log.error("解密失败:"+JSONObject.toJSONString(wechatDTO.getBody()));
throw new IllegalArgumentException(e);
}
}
第二种初始化获取证书
package com.example.demo.config;
import com.wechat.pay.java.core.Config;
import com.wechat.pay.java.core.RSAAutoCertificateConfig;
import com.wechat.pay.java.core.notification.NotificationConfig;
import com.wechat.pay.java.core.notification.NotificationParser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.annotation.PostConstruct;
@Configuration
public class WechatInitConfig {
private Config config;
@Autowired
private WechatConfig wechatConfig;
@PostConstruct
public void init(){
config = new RSAAutoCertificateConfig.Builder()
.merchantId(wechatConfig.getMchid())
.privateKey(wechatConfig.getPrivateKey())
.merchantSerialNumber(wechatConfig.getSerialNo())
.apiV3Key(wechatConfig.getApiV3Key())
.build();
}
@Bean("NotificationParser")
public NotificationParser getNotificationParser(){
return new NotificationParser((NotificationConfig) config);
}
}
业务数据处理
@Autowired
private NotificationParser notificationParser;
public void notificationParser(WechatDTO wechatDTO){
// 获取HTTP请求头中的 Wechatpay-Signature 、 Wechatpay-Nonce 、 Wechatpay-Timestamp 、 Wechatpay-Serial 、 Request-ID 、Wechatpay-Signature-Type 对应的值,构建 RequestParam 。
RequestParam requestParam = new RequestParam.Builder()
.serialNumber(wechatDTO.getSerialNo())
.nonce(wechatDTO.getNonceStr())
.signature(wechatDTO.getSignature())
.timestamp(wechatDTO.getTimestamp())
// 若未设置signType,默认值为 WECHATPAY2-SHA256-RSA2048
.signType(wechatDTO.getSignatureType())
.body(wechatDTO.getBody())
.build();
Transaction transaction = notificationParser.parse(requestParam, Transaction.class);
System.out.println("参数-------"+ JSONObject.toJSONString(transaction));
//处理业务逻辑
Transaction.TradeStateEnum tradeState = transaction.getTradeState();
//订单编号(本地生成)
String outTradeNo = transaction.getOutTradeNo();
System.out.println("订单编号"+outTradeNo);
//付款编号 (微信返回)
String transactionId = transaction.getTransactionId();
//通过本地订单编号处理业务逻辑(并将付款编号保存到本地)
System.out.println("付款编号"+transactionId);
if (tradeState.equals(Transaction.TradeStateEnum.SUCCESS)) {
//业务处理
}
}
文章浏览阅读1.1k次。一、选择题1. 串行接口是指( )。A. 接口与系统总线之间串行传送,接口与I/0设备之间串行传送B. 接口与系统总线之间串行传送,接口与1/0设备之间并行传送C. 接口与系统总线之间并行传送,接口与I/0设备之间串行传送D. 接口与系统总线之间并行传送,接口与I/0设备之间并行传送【答案】C2. 最容易造成很多小碎片的可变分区分配算法是( )。A. 首次适应算法B. 最佳适应算法..._874 计算机科学专业基础综合题型
文章浏览阅读9.7k次,点赞5次,收藏15次。连接xshell失败,报错如下图,怎么解决呢。1、通过ps -e|grep ssh命令判断是否安装ssh服务2、如果只有客户端安装了,服务器没有安装,则需要安装ssh服务器,命令:apt-get install openssh-server3、安装成功之后,启动ssh服务,命令:/etc/init.d/ssh start4、通过ps -e|grep ssh命令再次判断是否正确启动..._could not connect to '192.168.17.128' (port 22): connection failed.
文章浏览阅读209次。00000000_杰理 空白芯片 烧入key文件
文章浏览阅读475次。2023年初,“ChatGPT”一词在社交媒体上引起了热议,人们纷纷探讨它的本质和对社会的影响。就连央视新闻也对此进行了报道。作为新传专业的前沿人士,我们当然不能忽视这一热点。本文将全面解析ChatGPT,打开“技术黑箱”,探讨它对新闻与传播领域的影响。_引发对chatgpt兴趣的表述
文章浏览阅读259次。用Python数据分析方法进行汉字声调频率统计分析木合塔尔·沙地克;布合力齐姑丽·瓦斯力【期刊名称】《电脑知识与技术》【年(卷),期】2017(013)035【摘要】该文首先用Python程序,自动获取基本汉字字符集中的所有汉字,然后用汉字拼音转换工具pypinyin把所有汉字转换成拼音,最后根据所有汉字的拼音声调,统计并可视化拼音声调的占比.【总页数】2页(13-14)【关键词】数据分析;数据可..._汉字声调频率统计
文章浏览阅读64次。最近在做一个android系统移植的项目,所使用的开发板com1是调试串口,就是说会有uboot和kernel的调试信息打印在com1上(ttySAC0)。因为后期要使用ttySAC0作为上层应用通信串口,所以要把所有的调试信息都给去掉。参考网上的几篇文章,自己做了如下修改,终于把调试信息重定向到ttySAC1上了,在这做下记录。参考文章有:http://blog.csdn.net/longt..._嵌入式rootfs 输出重定向到/dev/console
文章浏览阅读1.2k次,点赞4次,收藏12次。1,先去iconfont登录,然后选择图标加入购物车 2,点击又上角车车添加进入项目我的项目中就会出现选择的图标 3,点击下载至本地,然后解压文件夹,然后切换到uniapp打开终端运行注:要保证自己电脑有安装node(没有安装node可以去官网下载Node.js 中文网)npm i -g iconfont-tools(mac用户失败的话在前面加个sudo,password就是自己的开机密码吧)4,终端切换到上面解压的文件夹里面,运行iconfont-tools 这些可以默认也可以自己命名(我是自己命名的_uniapp symbol图标
文章浏览阅读1.2w次,点赞25次,收藏192次。char*和char[]都是指针,指向第一个字符所在的地址,但char*是常量的指针,char[]是指针的常量_c++ char*
文章浏览阅读930次。代码编辑器或者文本编辑器,对于程序员来说,就像剑与战士一样,谁都想拥有一把可以随心驾驭且锋利无比的宝剑,而每一位程序员,同样会去追求最适合自己的强大、灵活的编辑器,相信你和我一样,都不会例外。我用过的编辑器不少,真不少~ 但却没有哪款让我特别心仪的,直到我遇到了 Sublime Text 2 !如果说“神器”是我能给予一款软件最高的评价,那么我很乐意为它封上这么一个称号。它小巧绿色且速度非
文章浏览阅读4.1k次。一、选择法这是每一个数出来跟后面所有的进行比较。2.冒泡排序法,是两个相邻的进行对比。_对十个数进行大小排序java
文章浏览阅读2.9k次。物联网开发笔记——使用网络调试助手连接阿里云物联网平台(基于MQTT协议)其实作者本意是使用4G模块来实现与阿里云物联网平台的连接过程,但是由于自己用的4G模块自身的限制,使得阿里云连接总是无法建立,已经联系客服返厂检修了,于是我在此使用网络调试助手来演示如何与阿里云物联网平台建立连接。一.准备工作1.MQTT协议说明文档(3.1.1版本)2.网络调试助手(可使用域名与服务器建立连接)PS:与阿里云建立连解释,最好使用域名来完成连接过程,而不是使用IP号。这里我跟阿里云的售后工程师咨询过,表示对应_网络调试助手连接阿里云连不上
文章浏览阅读544次,点赞5次,收藏6次。运算符与表达式任何高级程序设计语言中,表达式都是最基本的组成部分,可以说C++中的大部分语句都是由表达式构成的。_无c语言基础c++期末速成