1、C#代码 C#采用的RSACryptoServiceProvider类进行的加解密,由于该类默认是不支持私钥加密公钥解密的,需要通过BouncyCastle.Crypto.dll转换一下才可以。 代码如下:
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 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 |
using System; using System.Collections.Generic; using System.Text; using System.Security.Cryptography; using System.IO; using Org.BouncyCastle.Crypto; using Org.BouncyCastle.Security; using System.Xml; using Org.BouncyCastle.Math; using Org.BouncyCastle.Crypto.Parameters; using Org.BouncyCastle.Asn1.Pkcs; using Org.BouncyCastle.Pkcs; using Org.BouncyCastle.X509; using Org.BouncyCastle.Asn1.X509; namespace RSADemo { /// <summary> /// RSA加解密帮助类 /// 作者:代浩然 /// 时间:2019-1-21 18:37 /// </summary> public class RSAHelper { /// <summary> /// 生成公钥和私钥对 /// </summary> public static void GeneratePublicAndPrivateKeyInfo() { RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(); using (StreamWriter writer = new StreamWriter("PrivateKey.xml")) //这个文件要保密... { string privateKey = rsa.ToXmlString(true); writer.WriteLine(privateKey); } using (StreamWriter writer = new StreamWriter("PublicKey.xml")) { string publicKey = rsa.ToXmlString(false); writer.WriteLine(publicKey); } } /// <summary> /// 用私钥给数据进行RSA加密 /// </summary> /// <param name="xmlPrivateKey"> 私钥(XML格式字符串)</param> /// <param name="strEncryptString">要加密的数据</param> /// <returns> 加密后的数据 </returns> public static string PrivateKeyEncrypt(string xmlPrivateKey, string strEncryptString) { //加载私钥 RSACryptoServiceProvider privateRsa = new RSACryptoServiceProvider(); privateRsa.FromXmlString(ReadFile(xmlPrivateKey)); //转换密钥 AsymmetricCipherKeyPair keyPair = DotNetUtilities.GetKeyPair(privateRsa); IBufferedCipher c = CipherUtilities.GetCipher("RSA/ECB/PKCS1Padding"); //使用RSA/ECB/PKCS1Padding格式 //第一个参数为true表示加密,为false表示解密;第二个参数表示密钥 c.Init(true, keyPair.Private); byte[] dataToEncrypt = Encoding.UTF8.GetBytes(strEncryptString); #region 分段加密 int bufferSize = (privateRsa.KeySize / 8) - 11; byte[] buffer = new byte[bufferSize]; byte[] outBytes = null; //分段加密 using (MemoryStream input = new MemoryStream(dataToEncrypt)) using (MemoryStream ouput = new MemoryStream()) { while (true) { int readLine = input.Read(buffer, 0, bufferSize); if (readLine <= 0) { break; } byte[] temp = new byte[readLine]; Array.Copy(buffer, 0, temp, 0, readLine); byte[] encrypt = c.DoFinal(temp); ouput.Write(encrypt, 0, encrypt.Length); } outBytes = ouput.ToArray(); } #endregion //byte[] outBytes = c.DoFinal(DataToEncrypt);//加密 string strBase64 = Convert.ToBase64String(outBytes); return strBase64; } /// <summary> /// 用公钥给数据进行RSA解密 /// </summary> /// <param name="xmlPublicKey"> 公钥(XML格式字符串) </param> /// <param name="strDecryptString"> 要解密数据 </param> /// <returns> 解密后的数据 </returns> public static string PublicKeyDecrypt(string xmlPublicKey, string strDecryptString) { //加载公钥 RSACryptoServiceProvider publicRsa = new RSACryptoServiceProvider(); publicRsa.FromXmlString(ReadFile(xmlPublicKey)); RSAParameters rp = publicRsa.ExportParameters(false); //转换密钥 AsymmetricKeyParameter pbk = DotNetUtilities.GetRsaPublicKey(rp); IBufferedCipher c = CipherUtilities.GetCipher("RSA/ECB/PKCS1Padding"); //第一个参数为true表示加密,为false表示解密;第二个参数表示密钥 c.Init(false, pbk); byte[] outBytes = null; byte[] dataToDecrypt = Convert.FromBase64String(strDecryptString); #region 分段解密 int keySize = publicRsa.KeySize / 8; byte[] buffer = new byte[keySize]; using (MemoryStream input = new MemoryStream(dataToDecrypt)) using (MemoryStream output = new MemoryStream()) { while (true) { int readLine = input.Read(buffer, 0, keySize); if (readLine <= 0) { break; } byte[] temp = new byte[readLine]; Array.Copy(buffer, 0, temp, 0, readLine); byte[] decrypt = c.DoFinal(temp); output.Write(decrypt, 0, decrypt.Length); } outBytes = output.ToArray(); } #endregion //byte[] outBytes = c.DoFinal(DataToDecrypt);//解密 string strDec = Encoding.UTF8.GetString(outBytes); return strDec; } /// <summary> /// 使用公钥加密,分段加密 /// </summary> /// <param name="content"></param> /// <param name="privateKeyPath"></param> /// <returns></returns> public static string EncrytByPublic(string publicKeyPath, string strEncryptString) { RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(); rsa.FromXmlString(ReadFile(publicKeyPath)); byte[] originalData = Encoding.UTF8.GetBytes(strEncryptString); if (originalData == null || originalData.Length <= 0) { throw new NotSupportedException(); } if (rsa == null) { throw new ArgumentNullException(); } byte[] encryContent = null; #region 分段加密 int bufferSize = (rsa.KeySize / 8) - 11; byte[] buffer = new byte[bufferSize]; //分段加密 using (MemoryStream input = new MemoryStream(originalData)) using (MemoryStream ouput = new MemoryStream()) { while (true) { int readLine = input.Read(buffer, 0, bufferSize); if (readLine <= 0) { break; } byte[] temp = new byte[readLine]; Array.Copy(buffer, 0, temp, 0, readLine); byte[] encrypt = rsa.Encrypt(temp, false); ouput.Write(encrypt, 0, encrypt.Length); } encryContent = ouput.ToArray(); } #endregion return Convert.ToBase64String(encryContent); } /// <summary> /// 通过私钥解密,分段解密 /// </summary> /// <param name="content"></param> /// <param name="privateKeyPath"></param> /// <returns></returns> public static string DecryptByPrivate(string privateKeyPath, string strDecryptString) { RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(); rsa.FromXmlString(ReadFile(privateKeyPath)); byte[] encryptData = Convert.FromBase64String(strDecryptString); //byte[] dencryContent = rsa.Decrypt(encryptData, false); byte[] dencryContent = null; #region 分段解密 if (encryptData == null || encryptData.Length <= 0) { throw new NotSupportedException(); } int keySize = rsa.KeySize / 8; byte[] buffer = new byte[keySize]; using (MemoryStream input = new MemoryStream(encryptData)) using (MemoryStream output = new MemoryStream()) { while (true) { int readLine = input.Read(buffer, 0, keySize); if (readLine <= 0) { break; } byte[] temp = new byte[readLine]; Array.Copy(buffer, 0, temp, 0, readLine); byte[] decrypt = rsa.Decrypt(temp, false); output.Write(decrypt, 0, decrypt.Length); } dencryContent = output.ToArray(); } #endregion return Encoding.UTF8.GetString(dencryContent); } /// <summary> /// 读取文件 /// </summary> /// <param name="filePath"></param> /// <returns></returns> public static string ReadFile(string filePath) { string content = ""; if (File.Exists(filePath)) { content = File.ReadAllText(filePath); byte[] mybyte = Encoding.UTF8.GetBytes(content); content = Encoding.UTF8.GetString(mybyte); } return content; } /// <summary> /// 将私钥转换成java所用的私钥字符串 /// </summary> /// <param name="privateKeyPath">私钥文件路径</param> /// <returns></returns> public static string RSAPrivateKeyDotNet2Java(string privateKeyPath) { XmlDocument doc = new XmlDocument(); doc.LoadXml(ReadFile(privateKeyPath)); BigInteger m = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("Modulus")[0].InnerText)); BigInteger exp = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("Exponent")[0].InnerText)); BigInteger d = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("D")[0].InnerText)); BigInteger p = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("P")[0].InnerText)); BigInteger q = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("Q")[0].InnerText)); BigInteger dp = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("DP")[0].InnerText)); BigInteger dq = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("DQ")[0].InnerText)); BigInteger qinv = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("InverseQ")[0].InnerText)); RsaPrivateCrtKeyParameters privateKeyParam = new RsaPrivateCrtKeyParameters(m, exp, d, p, q, dp, dq, qinv); PrivateKeyInfo privateKeyInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(privateKeyParam); byte[] serializedPrivateBytes = privateKeyInfo.ToAsn1Object().GetEncoded(); return Convert.ToBase64String(serializedPrivateBytes); } /// <summary> /// 将公钥转换成java所用的公钥字符串 /// </summary> /// <param name="publicKeyPath">公钥路径</param> /// <returns></returns> public static string RSAPublicKeyDotNet2Java(string publicKeyPath) { XmlDocument doc = new XmlDocument(); doc.LoadXml(ReadFile(publicKeyPath)); BigInteger m = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("Modulus")[0].InnerText)); BigInteger p = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("Exponent")[0].InnerText)); RsaKeyParameters pub = new RsaKeyParameters(false, m, p); SubjectPublicKeyInfo publicKeyInfo = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(pub); byte[] serializedPublicBytes = publicKeyInfo.ToAsn1Object().GetDerEncoded(); return Convert.ToBase64String(serializedPublicBytes); } } } |
2、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 |
import java.io.*; import java.util.Base64; public class Base64Utils { /** *//** * 文件读取缓冲区大小 */ private static final int CACHE_SIZE = 1024; /** *//** * <p> * BASE64字符串解码为二进制数据 * </p> * * @param base64 * @return * @throws Exception */ public static byte[] decode(String base64) throws Exception { //return Base64.decode(base64.getBytes()); //Base64.getEncoder().encodeToString("在Java 8中,Base64编码已经成为Java类库的标准。".getBytes("utf-8")); return Base64.getDecoder().decode(base64); } /** *//** * <p> * 二进制数据编码为BASE64字符串 * </p> * * @param bytes * @return * @throws Exception */ public static String encode(byte[] bytes) throws Exception { //return new String(Base64.encode(bytes)); return Base64.getEncoder().encodeToString(bytes); } /** *//** * <p> * 将文件编码为BASE64字符串 * </p> * <p> * 大文件慎用,可能会导致内存溢出 * </p> * * @param filePath 文件绝对路径 * @return * @throws Exception */ public static String encodeFile(String filePath) throws Exception { byte[] bytes = fileToByte(filePath); return encode(bytes); } /** *//** * <p> * BASE64字符串转回文件 * </p> * * @param filePath 文件绝对路径 * @param base64 编码字符串 * @throws Exception */ public static void decodeToFile(String filePath, String base64) throws Exception { byte[] bytes = decode(base64); byteArrayToFile(bytes, filePath); } /** *//** * <p> * 文件转换为二进制数组 * </p> * * @param filePath 文件路径 * @return * @throws Exception */ public static byte[] fileToByte(String filePath) throws Exception { byte[] data = new byte[0]; File file = new File(filePath); if (file.exists()) { FileInputStream in = null; ByteArrayOutputStream out = null; try{ in = new FileInputStream(file); out = new ByteArrayOutputStream(2048); byte[] cache = new byte[CACHE_SIZE]; int nRead = 0; while ((nRead = in.read(cache)) != -1) { out.write(cache, 0, nRead); out.flush(); } data = out.toByteArray(); }catch (Exception e){ e.printStackTrace(); }finally { if (in != null){ in.close(); } if (out != null){ out.close(); } } } return data; } /** *//** * <p> * 二进制数据写文件 * </p> * * @param bytes 二进制数据 * @param filePath 文件生成目录 */ public static void byteArrayToFile(byte[] bytes, String filePath) throws Exception { InputStream in = null; OutputStream out = null; try{ in = new ByteArrayInputStream(bytes); File destFile = new File(filePath); if (!destFile.getParentFile().exists()) { destFile.getParentFile().mkdirs(); } destFile.createNewFile(); out = new FileOutputStream(destFile); byte[] cache = new byte[CACHE_SIZE]; int nRead = 0; while ((nRead = in.read(cache)) != -1) { out.write(cache, 0, nRead); out.flush(); } out.close(); in.close(); }catch (Exception e){ e.printStackTrace(); }finally { if (in != null){ in.close(); } if (out != null){ out.close(); } } } } |
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 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 |
import javax.crypto.Cipher; import java.io.ByteArrayOutputStream; import java.math.BigInteger; import java.security.*; import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPublicKey; import java.security.spec.*; import java.util.Base64; import java.util.HashMap; import java.util.Map; /** * 非对称加密解密 */ public class RSAEncryptProvider { /** * 加密算法RSA */ public static final String KEY_ALGORITHM = "RSA"; /** * 签名算法 */ public static final String SIGNATURE_ALGORITHM = "MD5withRSA"; /** * 获取公钥的key */ private static final String PUBLIC_KEY = "RSAPublicKey"; /** * 获取私钥的key */ private static final String PRIVATE_KEY = "RSAPrivateKey"; /** * RSA最大加密明文大小 */ private static final int MAX_ENCRYPT_BLOCK = 117; /** * RSA最大解密密文大小 */ private static final int MAX_DECRYPT_BLOCK = 128; /** * <p> * 生成密钥对(公钥和私钥) * </p> * * @return * @throws Exception */ public static Map<String, Object> genKeyPair() throws Exception { KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM); keyPairGen.initialize(1024); KeyPair keyPair = keyPairGen.generateKeyPair(); RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic(); RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate(); Map<String, Object> keyMap = new HashMap<String, Object>(2); keyMap.put(PUBLIC_KEY, publicKey); keyMap.put(PRIVATE_KEY, privateKey); return keyMap; } /** * <p> * 用私钥对信息生成数字签名 * </p> * * @param msg 已加密数据 * @param privateKey 私钥(BASE64编码) * * @return * @throws Exception */ public static String sign(String msg, String privateKey) throws Exception { byte[] data = msg.getBytes(); byte[] keyBytes = Base64.getDecoder().decode(privateKey); PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); PrivateKey privateK = keyFactory.generatePrivate(pkcs8KeySpec); Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM); signature.initSign(privateK); signature.update(data); return Base64.getEncoder().encodeToString(signature.sign()); } /** * <p> * 校验数字签名 * </p> * * @param msg 已加密数据 * @param publicKey 公钥(BASE64编码) * @param sign 数字签名 * * @return * @throws Exception * */ public static boolean verify(String msg, String publicKey, String sign) throws Exception { byte[] data = msg.getBytes(); byte[] keyBytes = Base64.getDecoder().decode(publicKey); X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); PublicKey publicK = keyFactory.generatePublic(keySpec); Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM); signature.initVerify(publicK); signature.update(data); return signature.verify(Base64.getDecoder().decode(sign)); } /** * <P> * 私钥解密,进行分片解密,解密大文本 * </p> * * @param encryptedDataStr 已加密数据 * @param privateKey 私钥(BASE64编码) * @return * @throws Exception */ public static byte[] decryptByPrivateKey(byte[] encryptedDataStr, String privateKey) throws Exception { //byte[] encryptedData = Base64.getDecoder().decode(encryptedDataStr); byte[] encryptedData = encryptedDataStr; byte[] keyBytes = Base64.getDecoder().decode(privateKey); PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); Key privateK = keyFactory.generatePrivate(pkcs8KeySpec); Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.DECRYPT_MODE, privateK); int inputLen = encryptedData.length; ByteArrayOutputStream out = new ByteArrayOutputStream(); int offSet = 0; byte[] cache; int i = 0; // 对数据分段解密 while (inputLen - offSet > 0) { if (inputLen - offSet > MAX_DECRYPT_BLOCK) { cache = cipher.doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK); } else { cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet); } out.write(cache, 0, cache.length); i++; offSet = i * MAX_DECRYPT_BLOCK; } byte[] decryptedData = out.toByteArray(); out.close(); //return new String(decryptedData); return decryptedData; } /** * <p> * 公钥解密,进行分片解密,解密大文本 * </p> * * @param encryptedDataStr 已加密数据 * @param publicKey 公钥(BASE64编码) * @return * @throws Exception */ public static byte[] decryptByPublicKey(byte[] encryptedDataStr, String publicKey) throws Exception { //byte[] encryptedData = Base64.getDecoder().decode(encryptedDataStr); byte[] encryptedData = encryptedDataStr; byte[] keyBytes = Base64.getDecoder().decode(publicKey); X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); Key publicK = keyFactory.generatePublic(x509KeySpec); Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.DECRYPT_MODE, publicK); int inputLen = encryptedData.length; ByteArrayOutputStream out = new ByteArrayOutputStream(); int offSet = 0; byte[] cache; int i = 0; // 对数据分段解密 while (inputLen - offSet > 0) { if (inputLen - offSet > MAX_DECRYPT_BLOCK) { cache = cipher.doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK); } else { cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet); } out.write(cache, 0, cache.length); i++; offSet = i * MAX_DECRYPT_BLOCK; } byte[] decryptedData = out.toByteArray(); out.close(); //return new String(decryptedData); return decryptedData; } /** * <p> * 公钥加密,进行分片加密,加密大文本 * </p> * * @param data 源数据 * @param publicKey 公钥(BASE64编码) * @return * @throws Exception */ public static byte[] encryptByPublicKey(byte[] data, String publicKey) throws Exception { byte[] keyBytes = Base64.getDecoder().decode(publicKey); X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); Key publicK = keyFactory.generatePublic(x509KeySpec); // 对数据加密 Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.ENCRYPT_MODE, publicK); int inputLen = data.length; ByteArrayOutputStream out = new ByteArrayOutputStream(); int offSet = 0; byte[] cache; int i = 0; // 对数据分段加密 while (inputLen - offSet > 0) { if (inputLen - offSet > MAX_ENCRYPT_BLOCK) { cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK); } else { cache = cipher.doFinal(data, offSet, inputLen - offSet); } out.write(cache, 0, cache.length); i++; offSet = i * MAX_ENCRYPT_BLOCK; } byte[] encryptedData = out.toByteArray(); out.close(); //String encryptedDataStr = Base64.getEncoder().encodeToString(encryptedData); return encryptedData; } /** * <p> * 私钥加密,进行分片加密,加密大文本 * </p> * * @param data 源数据 * @param privateKey 私钥(BASE64编码) * @return * @throws Exception */ public static byte[] encryptByPrivateKey(byte[] data, String privateKey) throws Exception { byte[] keyBytes = Base64.getDecoder().decode(privateKey); PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); Key privateK = keyFactory.generatePrivate(pkcs8KeySpec); Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.ENCRYPT_MODE, privateK); int inputLen = data.length; ByteArrayOutputStream out = new ByteArrayOutputStream(); int offSet = 0; byte[] cache; int i = 0; // 对数据分段加密 while (inputLen - offSet > 0) { if (inputLen - offSet > MAX_ENCRYPT_BLOCK) { cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK); } else { cache = cipher.doFinal(data, offSet, inputLen - offSet); } out.write(cache, 0, cache.length); i++; offSet = i * MAX_ENCRYPT_BLOCK; } byte[] encryptedData = out.toByteArray(); out.close(); //String encryptedDataStr = Base64.getEncoder().encodeToString(encryptedData); return encryptedData; } /** * <p> * 获取私钥 * </p> * * @param keyMap 密钥对 * @return * @throws Exception */ public static String getPrivateKey(Map<String, Object> keyMap) throws Exception { Key key = (Key) keyMap.get(PRIVATE_KEY); return Base64.getEncoder().encodeToString(key.getEncoded()); } /** * <p> * 获取公钥 * </p> * * @param keyMap 密钥对 * @return * @throws Exception */ public static String getPublicKey(Map<String, Object> keyMap) throws Exception { Key key = (Key) keyMap.get(PUBLIC_KEY); return Base64.getEncoder().encodeToString(key.getEncoded()); } /** * 通过C#的RSACryptoServiceProvider类产生的公钥进行转换成java的公钥 * @param modulus * @param exponent * @return */ public static PublicKey getPublicKey(String modulus, String exponent) { try { byte[] m = Base64Utils.decode(modulus); byte[] e = Base64Utils.decode(exponent); BigInteger b1 = new BigInteger(1,m); BigInteger b2 = new BigInteger(1,e); KeyFactory keyFactory = KeyFactory.getInstance("RSA"); RSAPublicKeySpec keySpec = new RSAPublicKeySpec(b1, b2); return (RSAPublicKey) keyFactory.generatePublic(keySpec); } catch (Exception e) { e.printStackTrace(); return null; } } /** * 通过C#的RSACryptoServiceProvider类产生的私钥进行转换成java的私钥 * @param modulus * @param privateExponent * @return */ public PrivateKey getPrivateKey(String modulus,String privateExponent) throws Exception { BigInteger m = new BigInteger(modulus); BigInteger e = new BigInteger(privateExponent); RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(m,e); KeyFactory keyFactory = KeyFactory.getInstance("RSA"); PrivateKey privateKey = keyFactory.generatePrivate(keySpec); return privateKey; } public static void main(String[] args) throws Exception { //通过C#公钥文件转换的java公钥字符串 String publicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCYyiJ5biYwnsRE2RgqI6rEsmxySuoxRAKBPkxZwBN2+NTb4KNr8JUtaD8Fj+NV1+eEspm8MT519PJRwCxOGxf/qU3CqCnTwxoc3MrN3MwxeQ1FC2wZkEm8y8FZKWd84udULxML+7ao1bCYWeDerd2MBWvKBpEqoG28jY3yY1AGbQIDAQAB"; //通过C#私钥文件转换的java私钥字符串 String privateKey = "MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAJjKInluJjCexETZGCojqsSybHJK6jFEAoE+TFnAE3b41Nvgo2vwlS1oPwWP41XX54SymbwxPnX08lHALE4bF/+pTcKoKdPDGhzcys3czDF5DUULbBmQSbzLwVkpZ3zi51QvEwv7tqjVsJhZ4N6t3YwFa8oGkSqgbbyNjfJjUAZtAgMBAAECgYAZ5PAQymU4ij/TN0PMKH1Rlregayfjr5YJF2jTMSVbXXKdzSWFLqHpryg3JhquOsgnCinZ5jKixR+oUTxxBFB9pcduLPpiQ+91hhebSGoR/09MgqFFg0Qx5/0dAgl0GpFGXPi3B6AM/8IJ6aGtQd/SIyo7LcRU+824kVufo/Z9IQJBAMYQq4lYpJFAKPvfJEstT5v02mHr01h7pNOBYkloQs2ZShTDfXicInzVmDaQ4CXCrTZC7Ud3pJD4my//1a+FelUCQQDFey8gpeqqAnwDd6CgIhCktjvr3OFGrZdazg8A2oHg/77GRichstx19wMYgx5Tb/Ezx+9wWqog0eRgkfAunSO5AkByLBXVnGVw3T1Cw4RWWY40Zlakb55quQtwaHrRueoYPi63/WCMb+RpdW7CtYyf97KFPtssgUk50DUU3DK/dP/pAkAgz8PXz9l6n+kNBm5YzPAo/eJc4RlJDgSs4LnbcXLM+JExDmzoC3jX3M/V3ctHH71a1ihxaY8E3vrsFLNse015AkBV7cm3Z2DU9mJkYLfLR2oT0T5d6RQpGWs8hJlvVFZC6q904+1uRJq8T3zyUHvEeF3xa1C7ONd4Fm/rNf7e1/5F"; //公钥加密 String data = testPublicEncrypt("abc12345555555555554444444444" + "4444444444444444444444444444444444444" + "44444444444444444444444444444444444444" + "44444444444444444444444444444444444444" + "44444444444444444444444444444444444" + "444444444444444444444444444444444444" + "444444444444444444444444444444444444" + "555555555555555555555555555555555" + "5555555555555555555555555555555",publicKey); System.out.println(data); //私钥解密 data = testPrivateDencrypt(data,privateKey); System.out.println(data); //私钥加密 data = testPrivateEncrypt("abc12345555555555554444444444" + "4444444444444444444444444444444444444" + "44444444444444444444444444444444444444" + "44444444444444444444444444444444444444" + "44444444444444444444444444444444444" + "444444444444444444444444444444444444" + "444444444444444444444444444444444444" + "555555555555555555555555555555555" + "5555555555555555555555555555555",privateKey); System.out.println(data); //公钥解密 data = testPublicDecrypt(data,publicKey); System.out.println(data); } /** * 测试公钥加密 * @param content 要加密的字符串 * @return * @throws Exception */ private static String testPublicEncrypt(String content,String publicKey)throws Exception{ byte[] entryData = RSAEncryptProvider.encryptByPublicKey(content.getBytes("UTF-8"), publicKey); return Base64Utils.encode(entryData); } /** * 测试私钥解密 * @param content * @return * @throws Exception */ private static String testPrivateDencrypt(String content,String privateKey)throws Exception{ byte[] dentryData = RSAEncryptProvider.decryptByPrivateKey(Base64Utils.decode(content),privateKey); return new String(dentryData,"UTF-8"); } /** * 测试通过私钥加密 * @param content * @param privateKey * @return * @throws Exception */ private static String testPrivateEncrypt(String content,String privateKey)throws Exception{ byte[] entryData = RSAEncryptProvider.encryptByPrivateKey(content.getBytes("UTF-8"), privateKey); return Base64Utils.encode(entryData); } /** * 测试通过公钥解密 * @param content * @param publicKey * @return * @throws Exception */ private static String testPublicDecrypt(String content,String publicKey)throws Exception{ byte[] dentryData = RSAEncryptProvider.decryptByPublicKey(Base64Utils.decode(content),publicKey); return new String(dentryData,"UTF-8"); } } |
代码下载地址:https://download.csdn.net/download/lengyue2015/10930794 from:https://blog.csdn.net/lengyue2015/article/details/86582177
View Detailswindow监听到打印的beforePrint和afterPrint两个事件,但是无论点击打印还是取消都会触发afterPrint事件,所以只能通过这个事件的触发让用户自己判断是否打印成功,以此来记录数据是否打印或者是打印了几次,以下是打印的方法
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 196 197 198 199 200 201 202 203 204 205 206 207 208 |
// import Vue from "vue"; import { productionPlanPrint } from '@/api/prodPlan' const isDOM = (obj) => { return typeof HTMLElement === 'object' ? obj instanceof HTMLElement : obj && typeof obj === 'object' && obj.nodeType === 1 && typeof obj.nodeName === 'string' } /* const extend = (obj, obj2) => { for (const k in obj2) { if (obj2.hasOwnProperty(k)) obj[k] = obj2[k] } return obj } */ const isInBody = (node) => { return node === document.body ? false : document.body.contains(node) } const wrapperRefDom = (refDom) => { let prevDom = null let currDom = refDom if (!isInBody(currDom)) return currDom while (currDom) { if (prevDom) { const element = currDom.cloneNode(false) element.appendChild(prevDom) prevDom = element } else { prevDom = currDom.cloneNode(true) } currDom = currDom.parentElement } return prevDom } const getStyle = (options) => { let str = '' const styles = document.querySelectorAll('style,link') for (let i = 0; i < styles.length; i++) { str += styles[i].outerHTML } str += '<style>' + (options.noPrint ? options.noPrint : '.no-print') + '{display:none;}</style>' return str } const getHtml = (dom, options) => { const inputs = document.querySelectorAll('input') const textAreas = document.querySelectorAll('textarea') const selects = document.querySelectorAll('select') for (let k = 0; k < inputs.length; k++) { if (inputs[k].type === 'checkbox' || inputs[k].type === 'radio') { if (inputs[k].checked === true) { inputs[k].setAttribute('checked', 'checked') } else { inputs[k].removeAttribute('checked') } } else if (inputs[k].type === 'text') { inputs[k].setAttribute('value', inputs[k].value) } else { inputs[k].setAttribute('value', inputs[k].value) } } for (let k2 = 0; k2 < textAreas.length; k2++) { if (textAreas[k2].type === 'textarea') { textAreas[k2].innerHTML = textAreas[k2].value } } for (let k3 = 0; k3 < selects.length; k3++) { if (selects[k3].type === 'select-one') { const child = selects[k3].children for (const i in child) { if (child[i].tagName === 'OPTION') { if (child[i].selected === true) { child[i].setAttribute('selected', 'selected') } else { child[i].removeAttribute('selected') } } } } } return options.noPrintParent ? dom.outerHTML : wrapperRefDom(dom).outerHTML } // var flag = false const toPrint = (frameWindow, target, id) => { // var beforePrint = function() { // // console.log('beforePrint'); // } // var afterPrint = function() { // flag = true // // console.log('afterPrint') // // target.$confirm('是否打印成功', '提示', { // // confirmButtonText: '成功', // // cancelButtonText: '失败', // // type: 'warning' // // }).then(() => { // // flag = true // // // console.log('ddd',id) // // // productionPlanPrint({ id }).then(res =>{ // // // console.log('rrr', res) // // // if (res.code==200){ // // // target.$message({ // // // type: 'success', // // // message: '打印数据更新成功' // // // }) // // // } // // // }) // // }).catch(() => { // // target.$message({ // // type: 'info', // // message: '未成功打印' // // }) // // }) // // return flag // } // // if (frameWindow.matchMedia) { // 返回一个新的 MediaQueryList 对象,表示指定的媒体查询字符串解析后的结果。 // var mediaQueryList = frameWindow.matchMedia('print') // mediaQueryList.addListener(function(mql) { // // console.log('fff',mql) // if (mql.matches) { // beforePrint() // } else { // afterPrint() // } // }) // } // // window.onbeforeprint = beforePrint; // window.onafterprint = afterPrint; try { setTimeout(function() { frameWindow.focus() try { // var mediaQueryList = frameWindow.matchMedia('print') // mediaQueryList.addListener((mql)=> { // console.log('aaa',mql.matches) // // if (mql.matches) { // // beforePrint(); // // } else { // // afterPrint(); // // } // }) // console.log('打印',!frameWindow.document.execCommand('print', false, null)) if (!frameWindow.document.execCommand('print', false, null)) { frameWindow.print() // console.log('打印1') } } catch (e) { frameWindow.print() // console.log('打印2') } frameWindow.close() }, 10) } catch (err) { console.log('err', err) } } const writeIframe = (content, target, id) => { const iframe = document.createElement('iframe') const f = document.body.appendChild(iframe) iframe.id = 'myIframe' iframe.setAttribute( 'style', 'position:absolute;width:0;height:0;top:-10px;left:-10px;' ) const w = f.contentWindow || f.contentDocument const doc = f.contentDocument || f.contentWindow.document doc.open() doc.write(content) doc.close() iframe.onload = function() { // w.onafterprint = e=>{ // console.log('打印后',e) // } toPrint(w, target, id) setTimeout(function() { document.body.removeChild(iframe) // console.log('iii') }, 100) } return w } const Print = (dom, options, target, id) => { // console.log('ddd',target) options = { ...options, noPrint: '.no-print' } let targetDom if (typeof dom === 'string') { targetDom = document.querySelector(dom) } else { targetDom = isDOM(dom) ? dom : dom.$el } const content = getStyle(options) + getHtml(targetDom, options) const w = writeIframe(content, target, id) // console.log('ddd',flag) return w } export default Print |
调用方法后监听iframe的afterPrint事件
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 |
// 打印BOM清单 printTable(val) { let _this = this // console.log('打印',this.printTableData) // console.log('dd',this.printTableTitle.id) this.isShow = true setTimeout(async() => { const frameWindow = await VabPrint(this.$refs[val], { noPrintParent: true }, this,this.printTableTitle.id) // console.log('dddd',result) // 打印前 var beforePrint = function() { // console.log('beforePrint'); } // 打印后 var afterPrint = function() { // console.log('afterPrint') _this.$confirm('是否打印成功', '提示', { confirmButtonText: '成功', cancelButtonText: '失败', type: 'warning' }).then(() => { // console.log('ddd',id) productionPlanPrint({ id: _this.printTableTitle.id }).then(res => { // console.log('rrr', res) if (res.code==200){ _this.$message({ type: 'success', message: '打印数据更新成功' }) _this.drawer = false _this.handleQuery(_this.pageNum) } }) }).catch(() => { _this.$message({ type: 'info', message: '未成功打印' }) }) } if (frameWindow.matchMedia) { // 返回一个新的 MediaQueryList 对象,表示指定的媒体查询字符串解析后的结果。 var mediaQueryList = frameWindow.matchMedia('print') mediaQueryList.addListener(function(mql) { // console.log('fff',mql) if (mql.matches) { beforePrint() } else { afterPrint() } }) } this.isShow = false }, 10) } |
from:https://blog.csdn.net/soclear_/article/details/127439860
View Details今天利用闲余时间研究了一下Jquery Jqprint插件,使用该Jquery脚本可以轻而易举的实现打印网页指定区域内容的功能: 例子一:
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 |
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>Jquery Jqprint打印控件演示</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <script language="javascript" src="./js/jquery-1.6.2.js"></script> <script language="javascript" src="./js/jquery.jqprint-0.3.js"></script> <style type="text/css"> html,body{margin:auto 15%;padding:0;} p{line-height: 18px;} </style> <script language="javascript"> function print(){ $("#printContainer").jqprint(); } </script> </head> <body> <div id="printContainer"> <center><p style="font-size: 21pt;font-weight: bold;">报任安书</p></center> <p> 太史公牛马走司马迁再拜言。少卿足下:曩者辱赐书,教以慎于接物,推贤进士为务。意气勤勤恳恳,若望仆不相师,而用流俗人之言。仆非敢如是也。请略陈固陋。阙然久不报,幸勿为过。</p> <p> 仆之先人,非有剖符丹书之功,文史星历,近乎卜祝之间,固主上所戏弄,倡优畜之,流俗之所轻也。假令仆伏法受诛,若九牛亡一毛,与蝼蚁何以异?而世又不与能死节者比,特以为智穷罪极,不能自免,卒就死耳。何也?素所自树立使然。人固有一死,或重于泰山,或轻于鸿毛,用之所趋异也。太上不辱先,其次不辱身,其次不辱理色,其次不辱辞令,其次诎体受辱,其次易服受辱,其次关木索、被棰楚受辱,其次剔毛发、婴金铁受辱,其次毁肌肤、断肢体受辱,最下腐刑极矣!传曰:“刑不上大夫。”此言士节不可不勉励也。猛虎处深山,百兽震恐,及在穽槛之中,摇尾而求食,积威约之渐也。故士有画地为牢,势不入;削木为吏,议不对,定计于鲜也。今交手足,受木索,暴肌肤,受榜棰,幽于圜墙之中。当此之时,见狱吏则头枪地,视徒隶则心惕息。何者?积威约之势也。及以至是,言不辱者,所谓强颜耳,曷足贵乎!且西伯,伯也,拘于羑里;李斯,相也,具于五刑;淮阴,王也,受械于陈;彭越、张敖,南向称孤,系狱具罪;绛侯诛诸吕,权倾五伯,囚于请室;魏其,大将也,衣赭衣、关三木;季布为朱家钳奴;灌夫受辱居室。此人皆身至王侯将相,声闻邻国,及罪至罔加,不能引决自裁,在尘埃之中,古今一体,安在其不辱也!此言之,勇怯,势也;强弱,形也。审矣,何足怪乎?且人不能早自裁绳墨之外,已稍陵迟,至于鞭棰之间,乃欲引节,斯不亦远乎!古人所以重施刑于大夫者,殆为此也。</p> <p> 夫人情莫不贪生恶死,念亲戚,顾妻子;至激于义理者不然,乃有所不得已也。今仆不幸,早失父母,无兄弟之亲,独身孤立,少卿视仆于妻子何如哉?且勇者不必死节,怯夫慕义,何处不勉焉!仆虽怯懦,欲苟活,亦颇识去就之分矣,何至自沉溺累绁之辱哉!且夫臧获婢妾,犹能引决,况若仆之不得已乎?所以隐忍苟活,幽于粪土之中而不辞者,恨私心有所不尽,鄙陋没世,而文采不表于后也。</p> <p> 古者富贵而名摩灭,不可胜记,唯倜傥非常之人称焉。盖西伯拘而演《周易》;仲尼厄而作《春秋》;屈原放逐,乃赋《离骚》;左丘失明,厥有《国语》;孙子膑脚,《兵法》修列;不韦迁蜀,世传《吕览》;韩非囚秦,《说难》、《孤愤》;《诗》三百篇,大底圣贤发愤之所为作也。此人皆意有所郁结,不得通其道,故述往事,思来者。乃如左丘无目,孙子断足,终不可用,退而论书策,以舒其愤,思垂空文以自见。</p> <p> 仆窃不逊,近自托于无能之辞,网罗天下放失旧闻,略考其行事,综其终始,稽其成败兴坏之纪。上计轩辕,下至于兹,为十表、本纪十二、书八章、世家三十、列传七十,凡百三十篇。亦欲以究天人之际,通古今之变,成一家之言。草创未就,会遭此祸,惜其不成,是以就极刑而无愠色。仆诚已著此书,藏之名山,传之其人,通邑大都。则仆偿前辱之责,虽万被戮,岂有悔哉!然此可为智者道,难为俗人言也。</p> <p> 且负下未易居,下流多谤议。仆以口语遇遭此祸,重为乡党所笑,以污辱先人,亦何面目复上父母之丘墓乎?虽累百世,垢弥甚耳!是以肠一日而九回,居则忽忽若有所亡,出则不知其所往。每念斯耻,汗未尝不发背沾衣也。身直为闺合之臣,宁得自引深藏于岩穴邪?故且从俗浮沉,与时俯仰,通其狂惑。今少卿乃教以推贤进士,无乃与仆私心剌谬乎?今虽欲自雕琢,曼辞以自饰,无益于俗,不信,适足取辱耳。要之死日,然后是非乃定。书不能悉意,略陈固陋。谨再拜。</p> </div> <center><input type="button" onclick="print()" value="打印文章"/></center> </body> </html> |
例子二:
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 |
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>Jquery Jqprint打印控件演示</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <script language="javascript" src="./js/jquery-1.6.2.js"></script> <script language="javascript" src="./js/jquery.jqprint-0.3.js"></script> <style type="text/css"> html,body{margin:auto 15%;padding:0;} p{line-height: 18px;} </style> <script language="javascript"> function print(){ $("#printContainer").jqprint({ debug: false, //如果是true则可以显示iframe查看效果(iframe默认高和宽都很小,可以再源码中调大),默认是false importCSS: true, //true表示引进原来的页面的css,默认是true。(如果是true,先会找$("link[media=print]"),若没有会去找$("link")中的css文件) printContainer: true, //表示如果原来选择的对象必须被纳入打印(注意:设置为false可能会打破你的CSS规则)。 operaSupport: true//表示如果插件也必须支持歌opera浏览器,在这种情况下,它提供了建立一个临时的打印选项卡。默认是true }); } </script> </head> <body> <div id="printContainer"> <center><p style="font-size: 21pt;font-weight: bold;">报任安书</p></center> <p> 太史公牛马走司马迁再拜言。少卿足下:曩者辱赐书,教以慎于接物,推贤进士为务。意气勤勤恳恳,若望仆不相师,而用流俗人之言。仆非敢如是也。请略陈固陋。阙然久不报,幸勿为过。</p> <p> 仆之先人,非有剖符丹书之功,文史星历,近乎卜祝之间,固主上所戏弄,倡优畜之,流俗之所轻也。假令仆伏法受诛,若九牛亡一毛,与蝼蚁何以异?而世又不与能死节者比,特以为智穷罪极,不能自免,卒就死耳。何也?素所自树立使然。人固有一死,或重于泰山,或轻于鸿毛,用之所趋异也。太上不辱先,其次不辱身,其次不辱理色,其次不辱辞令,其次诎体受辱,其次易服受辱,其次关木索、被棰楚受辱,其次剔毛发、婴金铁受辱,其次毁肌肤、断肢体受辱,最下腐刑极矣!传曰:“刑不上大夫。”此言士节不可不勉励也。猛虎处深山,百兽震恐,及在穽槛之中,摇尾而求食,积威约之渐也。故士有画地为牢,势不入;削木为吏,议不对,定计于鲜也。今交手足,受木索,暴肌肤,受榜棰,幽于圜墙之中。当此之时,见狱吏则头枪地,视徒隶则心惕息。何者?积威约之势也。及以至是,言不辱者,所谓强颜耳,曷足贵乎!且西伯,伯也,拘于羑里;李斯,相也,具于五刑;淮阴,王也,受械于陈;彭越、张敖,南向称孤,系狱具罪;绛侯诛诸吕,权倾五伯,囚于请室;魏其,大将也,衣赭衣、关三木;季布为朱家钳奴;灌夫受辱居室。此人皆身至王侯将相,声闻邻国,及罪至罔加,不能引决自裁,在尘埃之中,古今一体,安在其不辱也!此言之,勇怯,势也;强弱,形也。审矣,何足怪乎?且人不能早自裁绳墨之外,已稍陵迟,至于鞭棰之间,乃欲引节,斯不亦远乎!古人所以重施刑于大夫者,殆为此也。</p> <p> 夫人情莫不贪生恶死,念亲戚,顾妻子;至激于义理者不然,乃有所不得已也。今仆不幸,早失父母,无兄弟之亲,独身孤立,少卿视仆于妻子何如哉?且勇者不必死节,怯夫慕义,何处不勉焉!仆虽怯懦,欲苟活,亦颇识去就之分矣,何至自沉溺累绁之辱哉!且夫臧获婢妾,犹能引决,况若仆之不得已乎?所以隐忍苟活,幽于粪土之中而不辞者,恨私心有所不尽,鄙陋没世,而文采不表于后也。</p> <p> 古者富贵而名摩灭,不可胜记,唯倜傥非常之人称焉。盖西伯拘而演《周易》;仲尼厄而作《春秋》;屈原放逐,乃赋《离骚》;左丘失明,厥有《国语》;孙子膑脚,《兵法》修列;不韦迁蜀,世传《吕览》;韩非囚秦,《说难》、《孤愤》;《诗》三百篇,大底圣贤发愤之所为作也。此人皆意有所郁结,不得通其道,故述往事,思来者。乃如左丘无目,孙子断足,终不可用,退而论书策,以舒其愤,思垂空文以自见。</p> <p> 仆窃不逊,近自托于无能之辞,网罗天下放失旧闻,略考其行事,综其终始,稽其成败兴坏之纪。上计轩辕,下至于兹,为十表、本纪十二、书八章、世家三十、列传七十,凡百三十篇。亦欲以究天人之际,通古今之变,成一家之言。草创未就,会遭此祸,惜其不成,是以就极刑而无愠色。仆诚已著此书,藏之名山,传之其人,通邑大都。则仆偿前辱之责,虽万被戮,岂有悔哉!然此可为智者道,难为俗人言也。</p> <p> 且负下未易居,下流多谤议。仆以口语遇遭此祸,重为乡党所笑,以污辱先人,亦何面目复上父母之丘墓乎?虽累百世,垢弥甚耳!是以肠一日而九回,居则忽忽若有所亡,出则不知其所往。每念斯耻,汗未尝不发背沾衣也。身直为闺合之臣,宁得自引深藏于岩穴邪?故且从俗浮沉,与时俯仰,通其狂惑。今少卿乃教以推贤进士,无乃与仆私心剌谬乎?今虽欲自雕琢,曼辞以自饰,无益于俗,不信,适足取辱耳。要之死日,然后是非乃定。书不能悉意,略陈固陋。谨再拜。</p> </div> <center><input type="button" onclick="print()" value="打印文章"/></center> </body> </html> |
from:https://blog.51cto.com/u_16099297/6962748
View Details
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 |
$(function () { //定义打印前事件 var beforePrint = function () { console.log("打印前"); }; //定义打印后事件 var afterPrint = function () { console.log("打印后"); app.post('ba.service.CompanyService', 'updateCompany', { 'companyId': companyId, "autoRegStateCode":"40" }) .then(function (res) { }); } //监听window状态 if (window.matchMedia) { var mediaQueryList = window.matchMedia('print'); //为印添加事件 mediaQueryList.addListener(function (mql) { if (mql.matches) { beforePrint(); } else { afterPrint(); } }); } //打印前事件 window.onbeforeprint = beforePrint; //打印后事件 window.onafterprint = afterPrint; //执行打印 $(".print").click(function () { $(".print").hide() var newstr = document.getElementById("printPage").innerHTML; window.print(); $(".print").show() }) }); |
from:https://codeleading.com/article/96272527602/#google_vignette
View Details使用jdk的反射机制,创建对象的能力, 创建的是代理类的对象。 而不用你创建类文件。不用写java文件。
动态:在程序执行时,调用jdk提供的方法才能创建代理类的对象。
jdk动态代理,必须有接口,目标类必须实现接口, 没有接口时,需要使用cglib动态代理
View DetailsCGLIB(Code Generation Library)是一个开源、高性能、高质量的Code生成类库(代码生成包)。
它可以在运行期扩展Java类与实现Java接口。Hibernate用它实现PO(Persistent Object 持久化对象)字节码的动态生成,Spring AOP用它提供方法的interception(拦截)。
CGLIB的底层是通过使用一个小而快的字节码处理框架ASM,来转换字节码并生成新的类。但不鼓励大家直接使用ASM框架,因为对底层技术要求比较高。
View DetailsAOP的实现方式有两种:
AOP框架在编译阶段,就对目标类进行修改,得到的class文件已经是被修改过的。生成静态的AOP代理类(生成*.class文件已经被改掉了,需要使用特定的编译器)。以AspectJ为代表 —— 静态AOP框架。
AOP框架在运行阶段,动态生成AOP代理(在内存中动态地生成AOP代理类),以实现对目标对象的增强。它不需要特殊的编译器。以Spring AOP为代表。—— 动态AOP框架。
事务简介
前篇介绍了SpringAOP,Spring事务是SpringAOP一个典型的应用。
事务即数据库事务,指同一批次对数据的读写要么全成功,要么全失败,用以保证数据的一致性,是关系统数据库核心功能。编程中通过设置事务手动提交,然后根据情况选择提交事务或者回滚事务。
数据库中事务使用:
BEGIN;#开始事务
update table_name set name=’XXX’ where id=’XXX’;#执行数据库操作
COMMIT; #提交
ROLLBACK;#回滚
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
try { //下面这句必须加,不然报错 MultipartResolver resolver = new CommonsMultipartResolver(hsq.getSession().getServletContext()); MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) hsq; //获取一起跟文件传过来的其他参数值 String id = multipartRequest.getParameter("id"); //获取上传上来的文件 Map<String, MultipartFile> fileMap = multipartRequest.getFileMap(); for (Map.Entry<String, MultipartFile> entry : fileMap.entrySet()) { MultipartFile file = entry.getValue(); String fileName = file.getOriginalFilename(); System.out.println(fileName); String path = "C:\\Users\\user\\Desktop\\" + fileName; file.transferTo(new File(path)); } } catch (Exception e) { e.printStackTrace(); } |
from:https://www.cnblogs.com/sanrenblog/p/15648871.html
View Details