Web API POST [FromBody] string value 接受参数
网上看到很多关于这这个问题的解决方案,但是都不正确,我也恰巧遇到这个问题,所有把正确的解决方案写出来,希望给后来人参考,如有不同意见欢迎指正
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
namespace WebApi.Controllers { [Route("api/[controller]")] [ApiController] public class ValuesController : ControllerBase { // GET api/values [HttpGet] public ActionResult<IEnumerable<string>> Get() { return new string[] { "value1", "value2" }; } // GET api/values/5 [HttpGet("{id}")] public ActionResult<string> Get(int id) { return "value"; } // POST api/values [HttpPost] public IActionResult Post([FromBody] string value) { return Ok(value); } // PUT api/values/5 [HttpPut("{id}")] public void Put(int id, [FromBody] string value) { } } } |
1 2 3 4 5 6 |
### POST http://localhost:49518/api/values HTTP/1.1 Content-Type: application/json "ddddff" |
1 2 3 4 5 6 7 |
var value = '1111';$.ajax({ type: 'POST', contentType: "application/json", url: url, data: value, //如果是 string,int 直接传值 ,如果是模型 就要传对象{} .......省略 }); |
也就是data 不要传{} 对象,直接传字符串或者int from:https://www.cnblogs.com/microestc/p/11003233.html
View Detailsswap空间不足需要扩充
1 2 3 4 5 6 7 8 9 10 |
mkdir /swap cd /swap # 创建4G分区文件 dd if=/dev/zero of=swapfile bs=1G count=4 # 修改权限 chmod 600 /swap/swapfile # 设置swap mkswap /swap/swapfile # 启用swap swapon /swap/swapfile |
1 2 3 4 |
[root@datagrad swap]# swapon -s Filename Type Size Used Priority /dev/dm-1 partition 4194300 0 -2 /swap/swapfile file 4194300 0 -3 |
1 2 |
# 开机挂载 echo '/swap/swapfile swap swap defaults 0 0' >> /etc/fstab |
from:https://www.cnblogs.com/leoshi/p/12679962.html
View DetailsAsp.Net Core实战常见加密算法(C#)
先问个问题:为什么要使用加密算法? 因为数据在网络中传输时面临4个问题: 窃听 假冒 篡改 事后否认 加密技术就是用来解决“窃听”这个问题的。通常分为两大类:对称加密和非对称加密。 对称加密 概念:对称加密就是加密和解密使用同一个密钥,通常称之为“Session Key ”,这种加密技术在当今被广泛采用,如美国政府所采用的DES加密标准就是一种典型的对称加密算法,它的Session Key长度为56bits。 优点:算法公开、计算量小、加密速度快、加密效率高。适用于需要加密大量数据的场景。 缺点:由于加解密使用同一个密钥,密钥传输的过程不安全,且容易被破解,密钥管理也比较麻烦。例如:不适用于浏览器到服务器的通信,因为密钥一旦发送到浏览器端就很容易暴露。 常见算法:AES,DES,3DES,TDEA,Blowfish,RC5,IDEA 非对称加密 概念:非对称加密就是加密和解密所使用的不是同一个密钥,通常有两个密钥,称为“公钥”和“私钥”,它们两个必需配对使用。“公钥”是指可以对外公布的,“私钥”则不能,只能由持有人一个人知道。 优点:由于加解密是用不同的密钥,私钥并不公开,这样就保证了信息在网络传输中的安全性:即使被拦截也无法解密。非常适用于客户端到服务端的数据传输。例如:支付宝的支付请求,数字签名等。 缺点:加密速度慢,比较耗资源。只适用于少量敏感信息的加密。如果加密大量消息则效率会变得低下。另外,如果动态生成公钥和私钥也比较耗资源。 常见算法:RSA,Elgamal,背包算法,Rabin,D-H,ECC 有人可能会问,上面两类加密方式怎么没有MD5?MD5……严格意义上说不是一种加密算法,因为它不能解密。它只是一种密码散列算法,只是为了校验信息用的:保证信息没有篡改。如:你下载软件或游戏时,在下载页面官方都会提供一个“MD5字符串”,你下载完成后可以用md5工具对下载到的软件md5校验,如果得到的md5串和下载页面的一致,就说明软件或游戏没有被篡改过,可放心使用。 下面我们就一块来实战几种常见的加密方式和散列算法: DES 分类:对称加密 DES全称为Data Encryption Standard,即数据加密标准,是一种使用密钥加密的块算法,1977年被美国联邦政府的国家标准局确定为联邦资料处理标准(FIPS),并授权在非密级政府通信中使用,随后该算法在国际上广泛流传开来。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 |
using System; using System.IO; using System.Security.Cryptography; using System.Text; namespace EncryptionPractice.Utils { public class DESUtils { /// <summary> /// 加密数据 /// </summary> /// <param name="text"></param> /// <param name="sessionKey"></param> /// <returns></returns> public static string Encrypt(string text, string sessionKey) { try { var des = GetDESProvider(sessionKey); var bytes = Encoding.Default.GetBytes(text); using var memoryStream = GetMemoryStream(des.CreateEncryptor(), bytes); var result = new StringBuilder(); foreach (var byteItem in memoryStream.ToArray()) { result.AppendFormat("{0:X2}", byteItem); } return result.ToString(); } catch { return string.Empty; } } /// <summary> /// 解密数据 /// </summary> /// <param name="ciphertext"></param> /// <param name="sessionKey"></param> /// <returns></returns> public static string Decrypt(string ciphertext, string sessionKey) { try { var length = ciphertext.Length / 2; var bytes = new byte[length]; for (var i=0; i<length; i++) { var j = Convert.ToInt32(ciphertext.Substring(i * 2, 2), 16); bytes[i] = (byte) j; } var des = GetDESProvider(sessionKey); using var memoryStream = GetMemoryStream(des.CreateDecryptor(), bytes); return Encoding.Default.GetString(memoryStream.ToArray()); } catch { return string.Empty; } } /// <summary> /// 获取DES引擎 /// </summary> /// <param name="sessionKey"></param> /// <returns></returns> private static DESCryptoServiceProvider GetDESProvider(string sessionKey) { var md5Key = MD5Utils.Get32(sessionKey).Substring(8, 8); var des = new DESCryptoServiceProvider { Key = Encoding.ASCII.GetBytes(md5Key), IV = Encoding.ASCII.GetBytes(md5Key) }; return des; } /// <summary> /// 获取内存流 /// </summary> /// <param name="cryptoTransform"></param> /// <param name="bytes"></param> /// <returns></returns> private static MemoryStream GetMemoryStream(ICryptoTransform cryptoTransform, byte[] bytes) { var memoryStream = new MemoryStream(); using var cryptoStream = new CryptoStream(memoryStream, cryptoTransform, CryptoStreamMode.Write); cryptoStream.Write(bytes, 0, bytes.Length); cryptoStream.FlushFinalBlock(); return memoryStream; } } } |
AES 分类:对称加密 高级加密标准(Advanced Encryption Standard,AES),又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准。这个标准用来替代原先的DES(Data Encryption Standard),已经被多方分析且广为全世界所使用。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
using System; using System.IO; using System.Security.Cryptography; using System.Text; namespace EncryptionPractice.Utils { public class AESUtils { /// <summary> /// 默认Key /// </summary> const string KEY = "E10ADC3949BA59AB"; /// <summary> /// 默认偏移量 /// </summary> const string IV = "BE56E057F20F883E"; /// <summary> /// 加密 /// </summary> /// <param name="text"></param> /// <param name="key"></param> /// <param name="iv"></param> /// <returns></returns> public static string Encrypt(string text, string key = KEY, string iv = IV) { var bytes = Encoding.UTF8.GetBytes(text); var result = Origin(bytes, false, key, iv); return Convert.ToBase64String(result, 0, result.Length); } /// <summary> /// 解密 /// </summary> /// <param name="ciphertext"></param> /// <param name="key"></param> /// <param name="iv"></param> /// <returns></returns> public static string Decrypt(string ciphertext, string key = KEY, string iv = IV) { var bytes = Convert.FromBase64String(ciphertext); var result = Origin(bytes, true, key, iv); if (result.Length < 1) return string.Empty; return Encoding.UTF8.GetString(result); } /// <summary> /// 底层方法 /// </summary> /// <param name="bytes"></param> /// <param name="isDecrypt"></param> /// <param name="key"></param> /// <param name="iv"></param> /// <returns></returns> private static byte[] Origin(byte[] bytes, bool isDecrypt, string key = KEY, string iv = IV) { try { var keyBytes = Encoding.UTF8.GetBytes(key); var ivBytes = Encoding.UTF8.GetBytes(iv); var rijndaelManaged = new RijndaelManaged { BlockSize = 128, KeySize = 256, FeedbackSize = 128, Padding = PaddingMode.PKCS7, Key = keyBytes, IV = ivBytes, Mode = CipherMode.CBC }; var cryptoTransform = isDecrypt ? rijndaelManaged.CreateDecryptor() : rijndaelManaged.CreateEncryptor(); var result = cryptoTransform.TransformFinalBlock(bytes, 0, bytes.Length); return result; } catch { return new byte[] { }; } } } } |
RSA 分类:非对称加密 RSA是1977年由罗纳德·李维斯特(Ron Rivest)、阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adleman)一起提出的。RSA就是他们三人姓氏开头字母拼在一起组成的。RSA公开密钥密码体制是一种使用不同的加密密钥与解密密钥,“由已知加密密钥推导出解密密钥在计算上是不可行的”密码体制。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
using System; using System.IO; using System.Security.Cryptography; using System.Text; namespace EncryptionPractice.Utils { public class RSAUtils { /// <summary> /// 加密 /// </summary> /// <param name="text">明文</param> /// <param name="publicKey">公钥</param> /// <returns>密文</returns> public static string Encrypt(string text, string publicKey) { var blockSize = 256; // 加密块大小,越大越慢 var bytes = Encoding.UTF8.GetBytes(text); var length = bytes.Length; // rsa实例 var rsa = new RSACryptoServiceProvider(); rsa.FromXmlString(publicKey); var offSet = 0; // 游标 var i = 0; byte[] cache; var ms = new MemoryStream(); while (length - offSet > 0) { var len = length - offSet > blockSize ? blockSize : length - offSet; var temp = new byte[len]; Array.Copy(bytes, offSet, temp, 0, len); cache = rsa.Encrypt(bytes, false); ms.Write(cache, 0, cache.Length); i++; offSet = i * blockSize; } var cipherBytes = ms.ToArray(); return Convert.ToBase64String(cipherBytes); } /// <summary> /// RSA解密 /// </summary> /// <param name="ciphertext">密文</param> /// <param name="privateKey">私钥</param> /// <returns>明文</returns> public static string Decrypt(string ciphertext, string privateKey) { var blockSize = 256; var bytes = Convert.FromBase64String(ciphertext); var length = bytes.Length; // rsa实例 var rsa = new RSACryptoServiceProvider(); rsa.FromXmlString(privateKey); var offSet = 0; // 游标 var i = 0; byte[] cache; var ms = new MemoryStream(); while (length - offSet > 0) { var len = length - offSet > blockSize ? blockSize : length - offSet; var temp = new byte[len]; Array.Copy(bytes, offSet, temp, 0, len); cache = rsa.Decrypt(temp, false); ms.Write(cache, 0, cache.Length); i++; offSet = i * blockSize; } var cipherBytes = ms.ToArray(); return Encoding.UTF8.GetString(cipherBytes); } } } |
生成公钥/密钥的方法(只适用于C#,其他编程语言使用需要转换)
1 2 3 |
var rsa = new RSACryptoServiceProvider(); var publicKey = rsa.ToXmlString(false); var privateKey = rsa.ToXmlString(true); |
MD5 分类:散列算法 MD5信息摘要算法(MD5 Message-Digest Algorithm),一种被广泛使用的密码散列函数,可以产生出一个128位(16字节)的散列值(hash value),用于确保信息传输完整一致。MD5由美国密码学家罗纳德·李维斯特(Ronald Linn Rivest)设计,于1992年公开。1996年后该算法被证实存在弱点,可以被加以破解,对于需要高度安全性的数据,专家一般建议改用其他算法,如SHA-2。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
using System; using System.Security.Cryptography; using System.Text; namespace EncryptionPractice.Utils { public class MD5Utils { /// <summary> /// 获取16位散列值 /// </summary> /// <param name="text"></param> /// <returns></returns> public static string Get16(string text) { return Get32(text).Substring(7, 16); } /// <summary> /// 获取32位散列值 /// </summary> /// <param name="text"></param> /// <returns></returns> public static string Get32(string text) { using var md5 = MD5.Create(); var hash = md5.ComputeHash(Encoding.UTF8.GetBytes(text)); var result = BitConverter.ToString(hash); return result.Replace("-", "").ToUpper(); } /// <summary> /// 获取16位散列值 v2 /// </summary> /// <param name="text"></param> /// <returns></returns> public static string Get16v2(string text) { return Get32v2(text).Substring(7, 16); } /// <summary> /// 获取32位散列值 /// </summary> /// <param name="text">字符串</param> /// <returns></returns> public static string Get32v2(string text) { var md5 = new MD5CryptoServiceProvider(); var hash = md5.ComputeHash(Encoding.Default.GetBytes(text)); var resutl = new StringBuilder(); for (int i = 0; i < hash.Length; i++) { resutl.Append(hash[i].ToString("x2")); } return resutl.ToString().ToUpper(); } } } |
SHA-2 分类:散列算法 SHA-2,名称来自于安全散列算法2(英语:Secure Hash Algorithm 2)的缩写,一种密码散列函数算法标准,由美国国家安全局研发,由美国国家标准与技术研究院(NIST)在2001年发布。属于SHA算法之一,是SHA-1的后继者。其下又可再分为六个不同的算法标准,包括了:SHA-224、SHA-256、SHA-384、SHA-512、SHA-512/224、SHA-512/256。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
using System.Security.Cryptography; using System.Text; namespace EncryptionPractice.Utils { public class SHAUtils { /// <summary> /// SHA256加密 /// </summary> /// <param name="data"></param> /// <returns></returns> public static string Encrypt(string data) { var bytes = Encoding.UTF8.GetBytes(data); var hash = SHA256.Create().ComputeHash(bytes); var result = new StringBuilder(); for (int i = 0; i < hash.Length; i++) { result.Append(hash[i].ToString("x2")); } return result.ToString(); } } } |
欢迎转载,请注明出处:龙生时代
View DetailsJAVA版身份证获取性别、出生日期及年龄
工作中需要根据身份证获取性别、出生日期及年龄,且要还要支持15位长度的身份证号码,网上搜索了一下,经过测试好像多少存在点问题,干脆自已写一个。 CertificateNo.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
package com.bijian.study; import java.util.Calendar; import java.util.regex.Pattern; /** * 根据身份证获取性别、出生日期、年龄,支持15、18位身份证 */ public class CertificateNo { public ResultDTO parseCertificateNo(String certificateNo) { ResultDTO resultDTO = new ResultDTO(); String myRegExpIDCardNo = "^\\d{6}(((19|20)\\d{2}(0[1-9]|1[0-2])(0[1-9]|[1-2][0-9]|3[0-1])\\d{3}([0-9]|x|X))|(\\d{2}(0[1-9]|1[0-2])(0[1-9]|[1-2][0-9]|3[0-1])\\d{3}))$"; boolean valid=Pattern.matches(myRegExpIDCardNo,certificateNo)||(certificateNo.length() == 17 && Pattern.matches(myRegExpIDCardNo,certificateNo.substring(0,15))); if(!valid){ resultDTO.setStatueMessage("证件号码不规范!"); return resultDTO; } int idxSexStart = 16; int birthYearSpan = 4; //如果是15位的证件号码 if(certificateNo.length() == 15) { idxSexStart = 14; birthYearSpan = 2; } //性别 String idxSexStr = certificateNo.substring(idxSexStart, idxSexStart + 1); int idxSex = Integer.parseInt(idxSexStr) % 2; String sex = (idxSex == 1) ? "M" : "F"; resultDTO.setSex(sex); //出生日期 String year = (birthYearSpan == 2 ? "19" : "") + certificateNo.substring(6, 6 + birthYearSpan); String month = certificateNo.substring(6 + birthYearSpan, 6 + birthYearSpan + 2); String day = certificateNo.substring(8 + birthYearSpan, 8 + birthYearSpan + 2); String birthday = year + '-' + month + '-' + day; resultDTO.setBirthday(birthday); //年龄 Calendar certificateCal = Calendar.getInstance(); Calendar currentTimeCal = Calendar.getInstance(); certificateCal.set(Integer.parseInt(year), Integer.parseInt(month)-1, Integer.parseInt(day)); int yearAge = (currentTimeCal.get(currentTimeCal.YEAR)) - (certificateCal.get(certificateCal.YEAR)); certificateCal.set(currentTimeCal.get(Calendar.YEAR), Integer.parseInt(month)-1, Integer.parseInt(day)); int monthFloor = (currentTimeCal.before(certificateCal) ? 1 : 0); resultDTO.setAge(yearAge - monthFloor); return resultDTO; } } |
ResultDTO.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
package com.bijian.study; public class ResultDTO { private String statueMessage; private String sex; private String birthday; private int age; public String getStatueMessage() { return statueMessage; } public void setStatueMessage(String statueMessage) { this.statueMessage = statueMessage; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public String getBirthday() { return birthday; } public void setBirthday(String birthday) { this.birthday = birthday; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String toString() { String res = ""; if(this.statueMessage != null) { res += this.statueMessage; }else { res += "sex:" + this.sex + ",birthday:" + this.birthday + ",age:" + this.age; } return res; } } |
CertificateNoTest.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 |
package com.bijian.test; import junit.framework.Assert; import org.junit.Before; import org.junit.Test; import com.bijian.study.CertificateNo; import com.bijian.study.ResultDTO; /** * 说明: * 1.身份证信息完全是测试时随便写的,如有雷同,纯属巧合 * 2.写此测试案例的日期是2015-02-08,有测生日当天及前后的案例,后续再运行需更改 */ public class CertificateNoTest { private CertificateNo certificateNo; private ResultDTO resultDTO; @Before public void setUp() throws Exception { certificateNo = new CertificateNo(); } @Test public void test_abnormality_certificateNo_of_18_digit_430522199812623535() { resultDTO = certificateNo.parseCertificateNo("430522199812623535"); Assert.assertNotNull(resultDTO); Assert.assertEquals("证件号码不规范!", resultDTO.getStatueMessage()); } @Test public void test_abnormality_certificateNo_of_18_digit_430522198813013210() { resultDTO = certificateNo.parseCertificateNo("430522198813013210"); Assert.assertNotNull(resultDTO); Assert.assertEquals("证件号码不规范!", resultDTO.getStatueMessage()); } @Test public void test_normality_certificateNo_of_18_digit_430522199812101515() { resultDTO = certificateNo.parseCertificateNo("430522199812101515"); Assert.assertNotNull(resultDTO); Assert.assertEquals("M", resultDTO.getSex()); Assert.assertEquals("1998-12-10", resultDTO.getBirthday()); Assert.assertEquals(16, resultDTO.getAge()); } @Test public void test_normality_certificateNo_of_18_digit_430522199812101595() { resultDTO = certificateNo.parseCertificateNo("430522199812101595"); Assert.assertNotNull(resultDTO); Assert.assertEquals("M", resultDTO.getSex()); Assert.assertEquals("1998-12-10", resultDTO.getBirthday()); Assert.assertEquals(16, resultDTO.getAge()); } @Test public void test_normality_certificateNo_of_18_digit_430522199812101585() { resultDTO = certificateNo.parseCertificateNo("430522199812101585"); Assert.assertNotNull(resultDTO); Assert.assertEquals("F", resultDTO.getSex()); Assert.assertEquals("1998-12-10", resultDTO.getBirthday()); Assert.assertEquals(16, resultDTO.getAge()); } @Test public void test_normality_certificateNo_of_18_digit_430522198810103212() { resultDTO = certificateNo.parseCertificateNo("430522198810103212"); Assert.assertNotNull(resultDTO); Assert.assertEquals("M", resultDTO.getSex()); Assert.assertEquals("1988-10-10", resultDTO.getBirthday()); Assert.assertEquals(26, resultDTO.getAge()); } @Test public void test_normality_certificateNo_of_18_digit_before_birthday() { //测试的时间是2015-02-08,表明昨天刚过生日 resultDTO = certificateNo.parseCertificateNo("430522198802073210"); Assert.assertNotNull(resultDTO); Assert.assertEquals("M", resultDTO.getSex()); Assert.assertEquals("1988-02-07", resultDTO.getBirthday()); Assert.assertEquals(27, resultDTO.getAge()); } @Test public void test_normality_certificateNo_of_18_digit_birthday() { //测试的时间是2015-02-08,表明当天正好生日 resultDTO = certificateNo.parseCertificateNo("430522198802083210"); Assert.assertNotNull(resultDTO); Assert.assertEquals("M", resultDTO.getSex()); Assert.assertEquals("1988-02-08", resultDTO.getBirthday()); Assert.assertEquals(27, resultDTO.getAge()); } @Test public void test_normality_certificateNo_of_18_digit_after_birthday() { //测试的时间是2015-02-08,表明第二天才过生日 resultDTO = certificateNo.parseCertificateNo("430522198802093210"); Assert.assertNotNull(resultDTO); Assert.assertEquals("M", resultDTO.getSex()); Assert.assertEquals("1988-02-09", resultDTO.getBirthday()); Assert.assertEquals(26, resultDTO.getAge()); } @Test public void test_abnormality_certificateNo_of_15_digit_130503671401001() { resultDTO = certificateNo.parseCertificateNo("130503671401001"); Assert.assertNotNull(resultDTO); Assert.assertEquals("证件号码不规范!", resultDTO.getStatueMessage()); } @Test public void test_normality_certificateNo_of_15_digit_430522760201356() { resultDTO = certificateNo.parseCertificateNo("430522760201356"); Assert.assertNotNull(resultDTO); Assert.assertEquals("F", resultDTO.getSex()); Assert.assertEquals("1976-02-01", resultDTO.getBirthday()); Assert.assertEquals(39, resultDTO.getAge()); } @Test public void test_normality_certificateNo_of_15_digit_130503670401001() { resultDTO = certificateNo.parseCertificateNo("130503670401001"); Assert.assertNotNull(resultDTO); Assert.assertEquals("M", resultDTO.getSex()); Assert.assertEquals("1967-04-01", resultDTO.getBirthday()); Assert.assertEquals(47, resultDTO.getAge()); } @Test public void test_normality_certificateNo_of_15_digit_370802940221002() { resultDTO = certificateNo.parseCertificateNo("370802940221002"); Assert.assertNotNull(resultDTO); Assert.assertEquals("F", resultDTO.getSex()); Assert.assertEquals("1994-02-21", resultDTO.getBirthday()); Assert.assertEquals(20, resultDTO.getAge()); } @Test public void test_normality_certificateNo_of_15_digit_370802941031331() { resultDTO = certificateNo.parseCertificateNo("370802941031331"); Assert.assertNotNull(resultDTO); Assert.assertEquals("M", resultDTO.getSex()); Assert.assertEquals("1994-10-31", resultDTO.getBirthday()); Assert.assertEquals(20, resultDTO.getAge()); } @Test public void test_normality_certificateNo_of_15_digit_before_birthday() { //测试的时间是2015-02-08,表明昨天刚过生日 resultDTO = certificateNo.parseCertificateNo("370802940207331"); Assert.assertNotNull(resultDTO); Assert.assertEquals("M", resultDTO.getSex()); Assert.assertEquals("1994-02-07", resultDTO.getBirthday()); Assert.assertEquals(21, resultDTO.getAge()); } @Test public void test_normality_certificateNo_of_15_digit_birthday() { //测试的时间是2015-02-08,表明当天正好生日 resultDTO = certificateNo.parseCertificateNo("370802940208331"); Assert.assertNotNull(resultDTO); Assert.assertEquals("M", resultDTO.getSex()); Assert.assertEquals("1994-02-08", resultDTO.getBirthday()); Assert.assertEquals(21, resultDTO.getAge()); } @Test public void test_normality_certificateNo_of_15_digit_after_birthday() { //测试的时间是2015-02-08,表明第二天才过生日 resultDTO = certificateNo.parseCertificateNo("370802940209331"); Assert.assertNotNull(resultDTO); Assert.assertEquals("M", resultDTO.getSex()); Assert.assertEquals("1994-02-09", resultDTO.getBirthday()); Assert.assertEquals(20, resultDTO.getAge()); } } |
from:https://www.iteye.com/blog/bijian1013-2184409
View Detailsgit fetch & pull详解
1、简单概括 先用一张图来理一下git fetch和git pull的概念: 可以简单的概括为: git fetch是将远程主机的最新内容拉到本地,用户在检查了以后决定是否合并到工作本机分支中。 而git pull 则是将远程主机的最新内容拉下来后直接合并,即:git pull = git fetch + git merge,这样可能会产生冲突,需要手动解决。 下面我们来详细了解一下git fetch 和git pull 的用法。 2、分支的概念 在介绍两种方法之前,我们需要先了解一下分支的概念: 分支是用来标记特定代码的提交,每一个分支通过SHA1sum值来标识,所以对分支的操作是轻量级的,你改变的仅仅是SHA1sum值。 如下图所示,当前有2个分支,A,C,E属于master分支,而A,B,D,F属于dev分支。
1 2 3 |
A----C----E(master) \ B---D---F(dev) |
它们的head指针分别指向E和F,对上述做如下操作:
1 2 |
git checkout master //选择or切换到master分支 git merge dev //将dev分支合并到当前分支(master)中 |
合并完成后:
1 2 3 |
A---C---E---G(master) \ / B---D---F(dev) |
现在ABCDEFG属于master,G是一次合并后的结果,是将E和F的代码合并后的结果,可能会出现冲突。而ABDF依然属于dev分支。可以继续在dev的分支上进行开发:
1 2 3 |
A---C---E---G---H(master) \ / B---D---F---I(dev) |
分支(branch)的基本操作:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
git branch //查看本地所有分支 git branch -r //查看远程所有分支 git branch -a //查看本地和远程的所有分支 git branch <branchname> //新建分支 git branch -d <branchname> //删除本地分支 git branch -d -r <branchname> //删除远程分支,删除后还需推送到服务器 git push origin:<branchname> //删除后推送至服务器 git branch -m <oldbranch> <newbranch> //重命名本地分支 /** *重命名远程分支: *1、删除远程待修改分支 *2、push本地新分支到远程服务器 */ //git中一些选项解释: -d --delete:删除 -D --delete --force的快捷键 -f --force:强制 -m --move:移动或重命名 -M --move --force的快捷键 -r --remote:远程 -a --all:所有 |
3、git fetch 用法 git fetch 命令:
1 |
$ git fetch <远程主机名> //这个命令将某个远程主机的更新全部取回本地 |
如果只想取回特定分支的更新,可以指定分支名:
1 |
$ git fetch <远程主机名> <分支名> //注意之间有空格 |
最常见的命令如取回origin 主机的master 分支:
1 |
$ git fetch origin master |
取回更新后,会返回一个FETCH_HEAD ,指的是某个branch在服务器上的最新状态,我们可以在本地通过它查看刚取回的更新信息:
1 |
$ git log -p FETCH_HEAD |
如图: 可以看到返回的信息包括更新的文件名,更新的作者和时间,以及更新的代码(19行红色[删除]和绿色[新增]部分)。 我们可以通过这些信息来判断是否产生冲突,以确定是否将更新merge到当前分支。 4、git pull 用法 前面提到,git pull 的过程可以理解为:
1 2 |
git fetch origin master //从远程主机的master分支拉取最新内容 git merge FETCH_HEAD //将拉取下来的最新内容合并到当前所在的分支中 |
即将远程主机的某个分支的更新取回,并与本地指定的分支合并,完整格式可表示为:
1 |
$ git pull <远程主机名> <远程分支名>:<本地分支名> |
如果远程分支是与当前分支合并,则冒号后面的部分可以省略:
1 |
$ git pull origin next |
from:https://www.cnblogs.com/runnerjack/p/9342362.html
View Detailscontainerd简述
containerd是容器虚拟化技术,从docker中剥离出来,形成开放容器接口(OCI)标准的一部分。 docker对容器的管理和操作基本都是通过containerd完成的。Containerd 是一个工业级标准的容器运行时,它强调简单性、健壮性和可移植性。Containerd 可以在宿主机中管理完整的容器生命周期:容器镜像的传输和存储、容器的执行和管理、存储和网络等。详细点说,Containerd 负责干下面这些事情: •管理容器的生命周期(从创建容器到销毁容器) •拉取/推送容器镜像 •存储管理(管理镜像及容器数据的存储) •调用 runC 运行容器(与 runC 等容器运行时交互) •管理容器网络接口及网络 注意:Containerd 被设计成嵌入到一个更大的系统中,而不是直接由开发人员或终端用户使用。 我们可以从下面几点来理解为什么需要独立的 containerd: •继续从整体 docker 引擎中分离出的项目(开源项目的思路) •可以被 Kubernets CRI 等项目使用(通用化) •为广泛的行业合作打下基础(就像 runC 一样) docker安装后containerd默认已安装,containerd包含如下命令组件: •containerd:高性能容器运行时。 •ctr:containerd的命令行客户端。 •runc:运行容器的命令行工具。 docker、containerd、docker-shim、runC关系: docker:docker本身而言,包括了docker client和dockerd,dockerd实属是对容器相关操作的api的最上层封装,直接面向操作用户。 containerd:dockerd实际真实调用的还是containerd的api接口(rpc方式实现),containerd是dockerd和runC之间的一个中间交流组件。 docker-shim:一个真实运行容器的载体,每启动一个容器都会起一个新的docker-shim的进程。它通过指定三个参数:容器ID、boundle目录(containerd对应某个容器生成目录)、运行时二进制(默认是runC)来调用runC的api创建一个容器。 runC:一个命令行工具端,根据OCI的标准来创建和运行容器。 containerd应用 docker镜像和containerd镜像通用,但组织方式和存放目录不同,导致docker与ctr命令不通用,各自管理自己的镜像和容器。 此外k8s还有客户端命令crictl,用法与docker基本相同,可crictl -h查看用法。 containerd的默认配置文件为/etc/containerd/config.toml,可通过命令:
1 |
containerd config default |
输出默认配置,可参考文档https://github.com/containerd/containerd/blob/master/docs/ops.md
1 2 3 4 |
root = "/var/lib/containerd" state = "/run/containerd" oom_score = 0 …… |
root键值用于存储containerd持久化数据。 state键值用于存储containerd临时性数据,设备重启后数据丢失。 显示containerd镜像
1 |
sudo ctr images ls |
拉取hello-world镜像
1 |
sudo ctr images pull docker.io/library/hello-world:latest |
注:必须全路径,从dockerhub上下载默认hello-world镜像。 运行容器
1 2 |
sudo ctr run docker.io/library/hello-world:latestmy_hello-world sudo ctr run -t docker.io/library/busybox:latestmybusybox_demosh |
参考: 1.https://github.com/containerd/containerd 2.https://containerd.io/docs/getting-started/ 3.Containerd 简介 4.Docker组件介绍(一):runc和containerd from:https://www.cnblogs.com/embedded-linux/p/10850491.html
View DetailsMethod not found: '!!0[] System.Array.Empty()'.
错误原因:程序里面没有可调用的方法(程序使用的是 .NET Framework 4.6,但是你自己的系统里面使用的不是 4.6版本) 解决方法:1.安装window sp1 ,下载地址是:https://www.microsoft.com/zh-cn/download/details.aspx?id=5842 2.安装.NET Framework 4.6 ,下载地址是 :https://www.microsoft.com/zh-cn/download/details.aspx?id=49981 3.重启电脑,OK from:https://www.cnblogs.com/soundcode/p/5837673.html
View DetailsElectron
使用 JavaScript,HTML 和 CSS 构建跨平台的桌面应用程序。 Electron提供了丰富的本地(操作系统)的API,使你能够使用纯JavaScript来创建桌面应用程序。与其它各种的Node.js运行时不同的是Electron专注于桌面应用程序而不是Web服务器。 比你想象的更简单 如果你可以建一个网站,你就可以建一个桌面应用程序。 Electron 是一个使用 JavaScript, HTML 和 CSS 等 Web 技术创建原生程序的框架,它负责比较难搞的部分,你只需把精力放在你的应用的核心上即可。 Web 技术 Electron 基于 Chromium 和 Node.js, 让你可以使用 HTML, CSS 和 JavaScript 构建应用。 开源 Electron 是一个由 GitHub 及众多贡献者组成的活跃社区共同维护的开源项目。 跨平台 Electron 兼容 Mac、Windows 和 Linux,可以构建出三个平台的应用程序。
View Details创业公司开发APP用原生还是RN、weex或flutter
近半年,自己创业做在线教育,近期也打算开发自己的APP,作为一个技术出身的创业者,所以可以在开发APP时自己做技术选型。 但想到还有很多创业者或架构师也面临类似的问题,所以把自己的思考分享给需要的人。 我的客户端经验 笔者2011年毕业于北京交大,2015年下半年开始由操作系统开发转向安卓开发,2016年在搜狐开始使用react-native开发APP。 2017年曾短期在便利蜂参与过三个RN项目的开发,然后去易鑫从事大前端团队的管理,团队开发维护的原生APP,通过搭桥嵌入H5。 2019年初在快陪练负责前端团队,以纯flutter的方式上线了一个iOS版的钢琴资讯APP,且在直播上课APP中的订单模块接入了flutter。 过去半年多,使用uni-app开发了多个跨端小程序,其中uni-app集成了weex跨端APP开发框架,可以一套代码生成h5,各种小程序以及安卓和iOS的原生APP。 不管是原生APP、还是近几年比较热门的RN、weex或flutter跨端开发APP的技术,笔者都在真实项目中使用过。 正因为都用过,所以各自的坑有都进去过,虽然因为学的东西多,导致精力分散,很多技术都是略懂,但是总结一下,相信还是能有一定参考价值的。 移动应用开发的趋势 由于对移动应用的大量需求,很多公司已经把他们应用开发的重心转移到移动应用上了,这是一个不断有更好的技术、平台和框架流入的领域。 移动行业渴望进行一场革命,以遏制移动应用程序开发过程中出现的成本高、耗时长等问题。 因此,该变革以跨平台开发的形式出现。现在,维护代码和开发应用程序对于开发人员来说变得简单且省时。 现在,跨平台应用开发正在创业公司中变得越来越流行,相继出现了多种跨端开发原生APP的技术方案。 除了weex只在阿里系的公司用得多外,react native 和 flutter目前都有大量的公司在使用,并且互相竞争,试图证明自己是跨平台移动应用的最合适的王者。 React native 是 Facebook 2015年开源的,并且很快获得了大众的欢迎。而Google 的 flutter 则是这两年才火起来的新技术,它优势是更好的性能。 不仅对于资金紧张的初创公司,即使是大公司的新项目,初期都需要快速验证产品的可行性,因此多数公司都不会选择原生开发,而是基于跨端技术。 那么对于开发者来说,应该选用哪个跨平台应用程序开发框架比较好呢? 由于采用react native 和 flutter 的技术栈项目最多,所以本文主要分享我作为创业者在做客户端技术选型时,最后采纳的是使用RN还是flutter的过程。 react native vs flutter 环境搭建 从当前两个框架的最新版本来看,搭建原生开发环境都是比较复杂的,相对来讲,flutter要容易一些,特别是搭建Android开发环境。 编程语言 React Native 允许你使用 Javascript 开发应用程序,通过简单配置也可以使用微软维护的Typescript 语言进行开发,克服JS作为动态语言的一些不足。 由谷歌开发的 Flutter 提出了一种名为 Dart 的新编程语言。它对于开发人员来说是新手,但是那些具有 OOP 语言经验的人,比如 C ++ 和 JAVA,可以很容易地学习的。 IDE 和易于编码 如果我们讨论 React Native 的 IDE,那么它几乎支持所有领先的 IDE。然而,Flutter 受 Android studio / IntelliJ 和 visual studio 代码支持。 代码结构 Google 的 Dart 没有模板、样式和数据文件的分离,因此代码变得有点难以理解。 而 Javascript 遵循简单的代码结构,因此开发人员更清楚地理解和编写代码。 性能 因为 React Native 通过 JS […]
View DetailsWin10任务栏上的图标都放在哪个文件夹?Win10任务栏快捷图标路径分享
在Win10系统中,我们都会把常用的程序或应用图标放在任务栏,这样打开就方便多了,当然有的朋友会疑惑,这些图标都放在Win10系统的哪个文件夹中呢?带着这些疑问我们就来分享下任务栏图标存放路径。 推荐:Win10正式版64位 找到文件夹技巧: 1、按住SHIFT,然后右键点击图标,我们可以看到“复制为路径”; 2、复制到地址栏上或是记事本中,就可以看到文件具体位置了; 3、要打开文件夹,我们可以去除复制路径两边的引号,然后把如:360安装浏览器7.lnk 去除,回车就可以进入了。 得到地址为:C:\Users\Administrator\AppData\Roaming\Microsoft\Internet Explorer\Quick Launch\User Pinned\TaskBar\www.w10zj.com 以上就是我们要找的任务栏图标存放文件夹了~,希望Win10之家小编分享的技巧对大家有用。 from:http://www.w10zj.com/Win10xy/Win10yh_1067.html
View Details