*eclipse默认tomcat下是自动完成编译;而Intellij Idea默认tomcat下不是自动完成编译,从如下开始设置: 进入“settings”,如下图找到“compiler”,选中如图框选选项 勾选“Build project automatically”,保存即可。 from:https://www.cnblogs.com/zdb292034/p/8047267.html
View Details第一步在我们的电脑上打开IntelliJ IDEA,点击File->Settings,如下图所示: 第二步进去Settings之后,点击 Compiler,如下图所示: 第三步勾选“Build project automatically”,点击OK,如下图所示: 第四步按“ctrl+alt+shift+/”键,选择Registry ,如下图所示: 第五步勾选“compiler.automake.allow.when.app.running”,保存之后,进行重启IntelliJ IDEA就完成了,如下图所示: from:https://jingyan.baidu.com/article/ca2d939d5b0c05eb6d31ce77.html
View Details前言 最近由于项目需求,服务端由c#编写,客户端由java编写。通信数据使用RSA非对称加密。但是java和c#生成的密钥格式是不一样的,所以需要转换格式才可以正常使用。网上搜到使用java进行格式转换的代码(如:http://blog.csdn.net/road2010/article/details/40071881 ),本文将给出一种c#的实现方法。 密钥格式 java密钥格式如下: 私钥: MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAKSZSSEdPhv77O5ocnLNGXeQ21qJDArC1+yId+9/pY5bXkZk5vCB49EpfMwNukLv6AJqofThZPNOs1t015fdEYIUnkIc2QVxRwa0xTeFP6N8D4WQXRWs4fNG27JK5kP45s+9KlJtx5hs7G97aMczehIWpHaO6j9inOmjlU8l62KZAgMBAAECgYEAmK3TRtMwRJb33OGnn9OeFumYfy92qxi3X6Hq1o6qDBW2qkd4bImfv+ni6AinyOVuaadt2Y+lq4dKGcCVJzoZvPm1VKxD2y7xKa8/vEbPRiRTt0qnPq9T7UJkpDsiXf/zOMfWdjc3uA1bPnQ65RWHSJ7zAE+Gd7xnyCE5MEyijLECQQDVYqQWDqOVLZ5lJUuIfUIrhv26GvuoTX8v60+opCz4/Mdfh6JlefICVD6SAaYvufXBHVFY26JicNlR62ZOiBoNAkEAxXhsuEnNJNQcQHEVTPZoulbMbTV1VZIDQ1zjG8fvu8sv6IBYcR5+EsC8n3/6RkW8/iCJDzxE++VHzhoSQSoDvQJBAM6/63J/rpndAIrJ7vyJOPLJsc9/U3SH2gMJAT7KC9UXvuldlsixtf3xuEpplKbLjEUXbfklnZm586a+6XqPvoUCQDFotltOLARBBmihYuEE7qNhQHk63QbyJ9rdDP5Qgo2Mg4o7QuXa6VSr4QZPsUGQBX/YiDLFs8ULU3IgV9zyNEkCQADAYR8DctYzg0eBGdcOrDA5Szc62pYrS2wk89wUxyL4FyDL3omkVMKvtu5tccy7Xht2ikJZRqefZ3dS7ASm8/4= 公钥: MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCkmUkhHT4b++zuaHJyzRl3kNtaiQwKwtfsiHfvf6WOW15GZObwgePRKXzMDbpC7+gCaqH04WTzTrNbdNeX3RGCFJ5CHNkFcUcGtMU3hT+jfA+FkF0VrOHzRtuySuZD+ObPvSpSbceYbOxve2jHM3oSFqR2juo/Ypzpo5VPJetimQIDAQAB .NET密钥格式如下: 私钥:
1 2 3 4 5 6 7 8 9 10 |
<RSAKeyValue> <Modulus>pJlJIR0+G/vs7mhycs0Zd5DbWokMCsLX7Ih373+ljlteRmTm8IHj0Sl8zA26Qu/oAmqh9OFk806zW3TXl90RghSeQhzZBXFHBrTFN4U/o3wPhZBdFazh80bbskrmQ/jmz70qUm3HmGzsb3toxzN6Ehakdo7qP2Kc6aOVTyXrYpk=</Modulus> <Exponent>AQAB</Exponent> <P>1WKkFg6jlS2eZSVLiH1CK4b9uhr7qE1/L+tPqKQs+PzHX4eiZXnyAlQ+kgGmL7n1wR1RWNuiYnDZUetmTogaDQ==</P> <Q>xXhsuEnNJNQcQHEVTPZoulbMbTV1VZIDQ1zjG8fvu8sv6IBYcR5+EsC8n3/6RkW8/iCJDzxE++VHzhoSQSoDvQ==</Q> <DP>zr/rcn+umd0Aisnu/Ik48smxz39TdIfaAwkBPsoL1Re+6V2WyLG1/fG4SmmUpsuMRRdt+SWdmbnzpr7peo++hQ==</DP> <DQ>MWi2W04sBEEGaKFi4QTuo2FAeTrdBvIn2t0M/lCCjYyDijtC5drpVKvhBk+xQZAFf9iIMsWzxQtTciBX3PI0SQ==</DQ> <InverseQ>wGEfA3LWM4NHgRnXDqwwOUs3OtqWK0tsJPPcFMci+Bcgy96JpFTCr7bubXHMu14bdopCWUann2d3UuwEpvP+</InverseQ> <D>mK3TRtMwRJb33OGnn9OeFumYfy92qxi3X6Hq1o6qDBW2qkd4bImfv+ni6AinyOVuaadt2Y+lq4dKGcCVJzoZvPm1VKxD2y7xKa8/vEbPRiRTt0qnPq9T7UJkpDsiXf/zOMfWdjc3uA1bPnQ65RWHSJ7zAE+Gd7xnyCE5MEyijLE=</D> </RSAKeyValue> |
公钥:
1 2 3 4 |
<RSAKeyValue> <Modulus>pJlJIR0+G/vs7mhycs0Zd5DbWokMCsLX7Ih373+ljlteRmTm8IHj0Sl8zA26Qu/oAmqh9OFk806zW3TXl90RghSeQhzZBXFHBrTFN4U/o3wPhZBdFazh80bbskrmQ/jmz70qUm3HmGzsb3toxzN6Ehakdo7qP2Kc6aOVTyXrYpk=</Modulus> <Exponent>AQAB</Exponent> </RSAKeyValue> |
转换实现代码(c#) 格式转换要用到一个开源加密库Bouncy Castle Crypto APIs,官网地址: http://www.bouncycastle.org/csharp/ 具体实现代码如下:
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 |
using System; using System.Xml; using Org.BouncyCastle.Asn1.Pkcs; using Org.BouncyCastle.Asn1.X509; using Org.BouncyCastle.Crypto.Parameters; using Org.BouncyCastle.Math; using Org.BouncyCastle.Pkcs; using Org.BouncyCastle.Security; using Org.BouncyCastle.X509; /// <summary> /// RSA密钥格式转换 /// </summary> public class RSAKeyConvert { /// <summary> /// RSA私钥格式转换,java->.net /// </summary> /// <param name="privateKey">java生成的RSA私钥</param> /// <returns></returns> public static string RSAPrivateKeyJava2DotNet(string privateKey) { RsaPrivateCrtKeyParameters privateKeyParam = (RsaPrivateCrtKeyParameters)PrivateKeyFactory.CreateKey(Convert.FromBase64String(privateKey)); return string.Format("<RSAKeyValue><Modulus>{0}</Modulus><Exponent>{1}</Exponent><P>{2}</P><Q>{3}</Q><DP>{4}</DP><DQ>{5}</DQ><InverseQ>{6}</InverseQ><D>{7}</D></RSAKeyValue>", Convert.ToBase64String(privateKeyParam.Modulus.ToByteArrayUnsigned()), Convert.ToBase64String(privateKeyParam.PublicExponent.ToByteArrayUnsigned()), Convert.ToBase64String(privateKeyParam.P.ToByteArrayUnsigned()), Convert.ToBase64String(privateKeyParam.Q.ToByteArrayUnsigned()), Convert.ToBase64String(privateKeyParam.DP.ToByteArrayUnsigned()), Convert.ToBase64String(privateKeyParam.DQ.ToByteArrayUnsigned()), Convert.ToBase64String(privateKeyParam.QInv.ToByteArrayUnsigned()), Convert.ToBase64String(privateKeyParam.Exponent.ToByteArrayUnsigned())); } /// <summary> /// RSA私钥格式转换,.net->java /// </summary> /// <param name="privateKey">.net生成的私钥</param> /// <returns></returns> public static string RSAPrivateKeyDotNet2Java(string privateKey) { XmlDocument doc = new XmlDocument(); doc.LoadXml(privateKey); 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> /// RSA公钥格式转换,java->.net /// </summary> /// <param name="publicKey">java生成的公钥</param> /// <returns></returns> public static string RSAPublicKeyJava2DotNet(string publicKey) { RsaKeyParameters publicKeyParam = (RsaKeyParameters)PublicKeyFactory.CreateKey(Convert.FromBase64String(publicKey)); return string.Format("<RSAKeyValue><Modulus>{0}</Modulus><Exponent>{1}</Exponent></RSAKeyValue>", Convert.ToBase64String(publicKeyParam.Modulus.ToByteArrayUnsigned()), Convert.ToBase64String(publicKeyParam.Exponent.ToByteArrayUnsigned())); } /// <summary> /// RSA公钥格式转换,.net->java /// </summary> /// <param name="publicKey">.net生成的公钥</param> /// <returns></returns> public static string RSAPublicKeyDotNet2Java(string publicKey) { XmlDocument doc = new XmlDocument(); doc.LoadXml(publicKey); 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); } } |
from:https://www.cnblogs.com/datous/p/RSAKeyConvert.html
View Details之前发了一篇"TripleDes的加解密Java、C#、php通用代码",后面又有项目用到了Rsa加解密,还是在不同系统之间进行交互,Rsa在不同语言的密钥格式不一样,所以过程中主要还是密钥转换问题,为方便密钥转换,写了一个XML和PEM格式的密钥转换工具,文章后面会提供密钥转换工具的下载地址,通过搜索参考和研究终于搞定了在Java、C#和Php都可以通用的加解密代码,整理了Rsa的加解密代码做个记录,以后可以参考,大家应该都知道Rsa算法,这里就不说明了,直接看代码(代码主要是公钥加密私钥解密,密文统一进行base64编码,密钥长度为2048): 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 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 |
package com.w3cnet.leetcode.utils; import java.io.BufferedReader; import java.io.ByteArrayOutputStream; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.security.*; import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPublicKey; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import java.util.HashMap; import java.util.Map; import javax.crypto.Cipher; import org.apache.commons.codec.binary.Base64; public class RsaUtil { /** * 加密算法 */ public static final String ALGORITHM = "RSA"; /** * 填充方式 */ public static final String PADDING_FORMAT = "RSA/ECB/PKCS1Padding"; /** * 明文块最大值 */ private static final int MAX_ENCRYPT_BLOCK = 245; /** * 密文块最大值 */ private static final int MAX_DECRYPT_BLOCK = 256; /** * 加密 * @param text 明文 * @param publicKey 公钥 * @param charset 字符编码 * @return 加密后的字符串(base64) * @throws Exception */ public static String encrypt(String text, String publicKey, String charset) throws Exception { byte[] data = text.getBytes(charset); byte[] keyBytes = Base64.decodeBase64(publicKey); X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM); Key publicK = keyFactory.generatePublic(x509KeySpec); // 对数据加密 Cipher cipher = Cipher.getInstance(PADDING_FORMAT); cipher.init(Cipher.ENCRYPT_MODE, publicK); int length = data.length; ByteArrayOutputStream out = new ByteArrayOutputStream(); int offSet = 0; byte[] cache; int i = 0; // 对数据分段加密 while (length - offSet > 0) { int len = length - offSet > MAX_ENCRYPT_BLOCK ? MAX_ENCRYPT_BLOCK : length - offSet; cache = cipher.doFinal(data, offSet, len); out.write(cache, 0, cache.length); i++; offSet = i * MAX_ENCRYPT_BLOCK; } byte[] cipherBytes = out.toByteArray(); out.close(); return Base64.encodeBase64String(cipherBytes); } /** * 私钥解密 * @param ciphertext 密文(base64) * @param privateKey 私钥 * @param charset 字符编码 * @return * @throws Exception */ public static String decrypt(String ciphertext, String privateKey, String charset) throws Exception { byte[] data = Base64.decodeBase64(ciphertext); byte[] keyBytes = Base64.decodeBase64(privateKey); PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM); Key privateK = keyFactory.generatePrivate(pkcs8KeySpec); Cipher cipher = Cipher.getInstance(PADDING_FORMAT); cipher.init(Cipher.DECRYPT_MODE, privateK); int length = data.length; ByteArrayOutputStream out = new ByteArrayOutputStream(); int offSet = 0; byte[] cache; int i = 0; while (length - offSet > 0) { int len = length - offSet > MAX_DECRYPT_BLOCK ? MAX_DECRYPT_BLOCK : length - offSet; cache = cipher.doFinal(data, offSet, len); out.write(cache, 0, cache.length); i++; offSet = i * MAX_DECRYPT_BLOCK; } byte[] textBytes = out.toByteArray(); out.close(); return new String(textBytes, charset); } /** * 从文件中加载密钥字符串 * @return 是否成功 * @throws Exception */ public static String loadKeyString(String keyFile){ String keyString=""; InputStream in=null; BufferedReader br=null; try { in=RSACryptoUtil.class.getResourceAsStream("/"+keyFile); br= new BufferedReader(new InputStreamReader(in)); String readLine= null; StringBuilder sb= new StringBuilder(); while((readLine= br.readLine())!=null){ if(readLine.charAt(0)=='-'){ continue; }else{ sb.append(readLine); sb.append('\r'); } } keyString=sb.toString(); } catch (IOException e) { } catch (Exception e) { }finally{ if(br!=null){ try { br.close(); } catch (IOException e) { } } if(in!=null){ try { in.close(); } catch (IOException e) { } } } return keyString; } /** * 从文件中加载密钥字符串 根据文件路径加载 * @return 是否成功 * @throws Exception */ public static String loadKeyStringByPath(String keyFile){ String keyString=""; InputStream in=null; BufferedReader br=null; try { in = new FileInputStream(keyFile); br= new BufferedReader(new InputStreamReader(in)); String readLine= null; StringBuilder sb= new StringBuilder(); while((readLine= br.readLine())!=null){ if(readLine.charAt(0)=='-'){ continue; }else{ sb.append(readLine); sb.append('\r'); } } keyString=sb.toString(); } catch (IOException e) { System.out.println(e.getMessage()); } catch (Exception e) { System.out.println(e.getMessage()); }finally{ if(br!=null){ try { br.close(); } catch (IOException e) { } } if(in!=null){ try { in.close(); } catch (IOException e) { } } } return keyString; } public static void main(String[] args) throws Exception { String publicKey = RSAUtils.loadKeyStringByPath("D:/sso_public_key_test.pem"); System.out.println(RSACryptoUtil.encrypt("123", publicKey, "utf-8")); } } |
C#版本:
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 |
public class RsaUtil { /// <summary> /// 加密 /// </summary> /// <param name="text">明文</param> /// <param name="publicKey">公钥</param> /// <returns>密文</returns> public static string Encrypt(string text, string publicKey) { var bytes = Encoding.UTF8.GetBytes(text); var length = bytes.Length; // rsa实例 var rsa = new RSACryptoServiceProvider(); rsa.FromXmlString(publicKey); var blockSize = (rsa.KeySize / 8) - 11; 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(temp, 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); } } |
PHP版本:
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 |
<?php #私钥 $private_key = '-----BEGIN PRIVATE KEY----- MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQCocmvQIWD2L9TW N1uKpLONwHcdy2oaKoW1CtI8PB+S+UjdEuLl3usWEuh3ZgLYloPyD9553SJFn7an fOplHITBqASOIXt9pi0CkahUPgwCPj4Dke5cT3fsp2i243/FX3afzrcf7FfTrEv/ LT22wF3csqrGt/UhqMcmpWIpPaL8edoCwGRBhghzEWaRwPZ2x5RPg+9qTSy0M7QG u+8EwYDnNkGGuuIwzNxklclic9Unp96eVp33vOP/LNvz90OcuqGQQcABh+e2ttv6 VzqlRcD1GRhxqkT3erXmgbQAVm6JQHArK1Up10No+lth1tri5TGcL0BEF7PetDIj jYh+aCLpAgMBAAECggEAPjFI1yaLyzmrxo/Xz5+x36NxF2IUQabziP1+09iK+9Po cB9aAO9GMvc2N2dFo7wm6Uesp6fa0IQAh2RakoxuA6ZKUEPSeXjSY4Ft+fSSsH1U njLSI+j/aTQCOIxUj4YIoUZMXJABeVjDEmscvw3VWffpj8c5zXyoUv9696kXNUoa uHOuphe1UNc3ghFIpWK+7ScxkPB6KtmAFwD4LSbT9OwhPozavBqouQvhLt1bXO8C ycKq4f1Pzhtt3sq3BRsPwqGhWt1NK95upKQuDnk1kJHjNzScH1FZxhsBHLxwOJ6E M7HP5Ywh78umusaNPVLMM6+YVWbENg+WZZcXd/XspQKBgQDRIhIukY7m7fRBH0CP mHi20gUmn7HzXgLxlbcU5n2PMDHHOg8D+Nmz1MnYPRQNwqxJdH8HOk8YQDC2uA+h BpyCpvPbp6y6SnZw8bhqiNfSHBjEftmg7lUU5xzBiBo6SyCyLkWD2xa/O8Vyh6ut /G1mQpNNJWWt5b+g5c4i0/fIhwKBgQDOMjGcLS8zHnZ30ZsWUS39iZ5TZXPCldTl Q9JB5PnB4CajYmQEdw3n9C6mOO42b+3M04mmqo1r0HiNyA9lZQQNsM3KqG+ngGvE 0DM1cAyuz3Fi3XTIhAbRyXXyVbqBp5Yh2/O2lvrsInusJrimDRgwglquu2GsdVrj +++b2DFFDwKBgQCkfXLlk/FdK44xZn5mM1vHGBubDIJv0+Lm14Yf90aMyDBu7fh/ fEznSBfWb/wE8riGMg3zxmYNwfdO0Cji04torB4kB5cxE35jSYxupuFxzk2gx9Eu 5iafgUQ56G4QqaS24PQmSL10fnPHqHRdLa1ygCzRwfdettVpnTbsZ+J9owKBgQDF o2Tb3o9sPxmsdVNiy8L6TstcAlU3wOfELQK+uFwQ0eoXFvrpMLg6iVmhZ9YkhZp4 hpZdEwLkwXib5ZOkS3PcL4jBZDtJYRVrG2jKIrF1aU60RbJnc+0ZbjHIaxWOqvSD VdE/RW4TomXKN38rYke6T2feLatMY1wQRG6BgXKQTwKBgQDKfK9Xuqzx+WI4AohT EwKrQEZUMD+6DTESHHG9As4zMJ9zU+6iPpM4Gw4CzfJZHhPP4dD+TC9NcvvR+GC9 UkwxmZrvP1+6KNFp0DZNk6M9wPZuYM/E63Vy0sFEA+/gFp4vQh8k7N8n/n7DhR3v kLuPdicfsKcz0thxzyDjv6oR2g== -----END PRIVATE KEY-----'; #公钥 $public_key = '-----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqHJr0CFg9i/U1jdbiqSz jcB3HctqGiqFtQrSPDwfkvlI3RLi5d7rFhLod2YC2JaD8g/eed0iRZ+2p3zqZRyE wagEjiF7faYtApGoVD4MAj4+A5HuXE937KdotuN/xV92n863H+xX06xL/y09tsBd 3LKqxrf1IajHJqViKT2i/HnaAsBkQYYIcxFmkcD2dseUT4Pvak0stDO0BrvvBMGA 5zZBhrriMMzcZJXJYnPVJ6fenlad97zj/yzb8/dDnLqhkEHAAYfntrbb+lc6pUXA 9RkYcapE93q15oG0AFZuiUBwKytVKddDaPpbYdba4uUxnC9ARBez3rQyI42Ifmgi 6QIDAQAB -----END PUBLIC KEY-----'; $pi_key = openssl_pkey_get_private($private_key); $pu_key = openssl_pkey_get_public($public_key); #公钥加密数据 rsa+base64 $data = "hello world!"; openssl_public_encrypt($data,$encrypted,$pu_key); $base64_encrypted = base64_encode($encrypted); echo $base64_encrypted."\n"; #私钥解密数据 openssl_private_decrypt(base64_decode($base64_encrypted),$decrypted_data,$pi_key); echo $decrypted_data; ?> |
Rsa加解密C#和Java、php使用的密钥格式不一样,这里提供一个密钥转换工具:Rsa密钥转换工具v2.0 参考 https://www.cnblogs.com/jaamy/p/6118814.html
View Details一个类可以实现多个接口,但却只能继承最多一个抽象类。 抽象类可以包含具体的方法;接口的所有方法都是抽象的。 抽象类可以声明和使用字段;接口则不能,但可以创建静态的final常量。 抽象类中的方法可以是public、protected、private或者默认的pagckage;接口的方法都是public。 抽象类可以定义构造函数;接口不能。
View Details
1 2 3 4 5 6 7 8 |
@Test public void testHello() throws Exception { mockMvc.perform(MockMvcRequestBuilders.get("/hello").accept(MediaType.APPLICATION_JSON)) .andExpect(status().isOk()) .andExpect(content().string(equalTo("Hello World!"))); } |
是因为静态导入的原因,只要导入:
1 2 3 |
import static org.hamcrest.Matchers.equalTo; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; |
然后就OK了。 from:https://blog.csdn.net/qq_21549989/article/details/78873229
View Detailshttp://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd"> <!-- 把后面的3.x去掉 --> ——————— 作者:大道至简_lyon 来源:CSDN 原文:https://blog.csdn.net/a5601564/article/details/51585232 版权声明:本文为博主原创文章,转载请附上博文链接!
View Details服务治理可以说是微服务架构中最为核心和基础的模块,它主要用来实现各个微服务实例的自动化注册和发现。 Spring Cloud Eureka是Spring Cloud Netflix 微服务套件的一部分,主要负责完成微服务架构中的服务治理功能。 本文通过简单的小例子来分享下如何通过Eureka进行服务治理: 搭建服务注册中心 注册服务提供者 服务发现和消费 ==========我是华丽的分割线======================== 一、搭建服务注册中心 先列出完整目录结构: 搭建过程如下: 创建maven工程:eureka(具体实现略) 修改pom文件,引入依赖
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 |
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.sam</groupId> <artifactId>eureka</artifactId> <version>0.0.1-SNAPSHOT</version> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.1.RELEASE</version> </parent> <properties> <javaVersion>1.8</javaVersion> </properties> <!-- 使用dependencyManagement进行版本管理 --> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Camden.SR6</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <!-- 引入eureka server依赖 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka-server</artifactId> </dependency> </dependencies> </project> |
创建启动类
1 2 3 4 5 6 7 8 9 10 11 12 13 |
/** * * @EnableEurekaServer * 用来指定该项目为Eureka的服务注册中心 */ @EnableEurekaServer @SpringBootApplication public class EurekaApp { public static void main(String[] args) { SpringApplication.run(EurekaApp.class, args); } } |
配置application.properties文件
1 2 3 4 5 6 7 8 9 10 11 12 |
#设置tomcat服务端口号 server.port=1111 #设置服务名称 spring.application.name=eureka-service eureka.instance.hostname=localhost #注册中心不需要注册自己 eureka.client.register-with-eureka=false #注册中心不需要去发现服务 eureka.client.fetch-registry=false #设置服务注册中心的URL eureka.client.serviceUrl.defaultZone=http://${eureka.instance.hostname}:${server.port}/eureka |
启动服务并访问,我们会看到这样的画面: 二、注册服务提供者 先列出完整目录结构: 搭建过程如下: 创建maven工程:hello-service(具体实现略) 修改pom文件,引入依赖
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 |
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.sam</groupId> <artifactId>hello-service</artifactId> <version>0.0.1-SNAPSHOT</version> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.1.RELEASE</version> </parent> <properties> <javaVersion>1.8</javaVersion> </properties> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Camden.SR6</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <!-- 引入eureka 客户端依赖 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> </dependency> </dependencies> </project> |
创建启动类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
/*** * * @EnableDiscoveryClient * 让服务使用eureka服务器 * 实现服务注册和发现 * */ @EnableDiscoveryClient @SpringBootApplication public class HelloApp { public static void main(String[] args) { SpringApplication.run(HelloApp.class, args); } } |
创建controller
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
@RestController public class HelloController { Logger logger = LoggerFactory.getLogger(HelloController.class); @Autowired DiscoveryClient discoveryClient; @RequestMapping("/hello") public String hello() { ServiceInstance instance = discoveryClient.getLocalServiceInstance(); //打印服务的服务id logger.info("*********" + instance.getServiceId()); return "hello,this is hello-service"; } } |
配置application.properties文件
1 2 3 4 5 |
server.port=9090 #设置服务名 spring.application.name=hello-service #设置服务注册中心的URL,本服务要向该服务注册中心注册自己 eureka.client.serviceUrl.defaultZone=http://localhost:1111/eureka |
启动并测试 )启动后再hello-service的控制台会有这种字样(xxx代表你的PC名)
1 |
Registered instance HELLO-SERVICE/xxx:hello-service:9090 with status UP (replication=false) |
eureka的控制台会打印出如下字样(xxx代表你的PC名)
1 |
Registered instance HELLO-SERVICE/xxx:hello-service:9090 with status UP (replication=false) |
)再次访问localhost:1111,会发现有服务注册到注册中心了 三、服务发现和消费 完整目录结构如下: 搭建过程: 创建maven工程(具体实现略) 修改pom文件,引入依赖
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 |
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.sam</groupId> <artifactId>hello-consumer</artifactId> <version>0.0.1-SNAPSHOT</version> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.1.RELEASE</version> </parent> <properties> <javaVersion>1.8</javaVersion> </properties> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Camden.SR6</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <!-- 引入eureka 客户端依赖 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> </dependency> <!-- 引入ribbon 依赖 ,用来实现负载均衡,我们这里只是使用,先不作其他介绍--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-ribbon</artifactId> </dependency> </dependencies> </project> 这里比hello-service服务提供者,多了ribbon的依赖 |
创建启动类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
@EnableDiscoveryClient @SpringBootApplication public class ConsumerApp { //@Bean 应用在方法上,用来将方法返回值设为为bean @Bean @LoadBalanced //@LoadBalanced实现负载均衡 public RestTemplate restTemplate() { return new RestTemplate(); } public static void main(String[] args) { SpringApplication.run(ConsumerApp.class, args); } } |
1 |
这里也要用到@EnableDiscoveryClient, 让服务使用eureka服务器, 实现服务注册和发现 |
创建controller
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
@RestController public class ConsumerController { //这里注入的restTemplate就是在com.sam.ConsumerApp中通过@Bean配置的实例 @Autowired RestTemplate restTemplate; @RequestMapping("/hello-consumer") public String helloConsumer() { //调用hello-service服务,注意这里用的是服务名,而不是具体的ip+port restTemplate.getForObject("http://hello-service/hello", String.class); return "hello consumer finish !!!"; } } |
配置application.properties文件
1 2 3 4 5 6 7 |
server.port=9999 spring.application.name=hello-consumer eureka.client.serviceUrl.defaultZone=http://localhost:1111/eureka #这里的配置项目和服务提供者hello-service一样 |
启动,测试 )启动eureka。为了展示负责均衡的效果,我们的hello-service启动两个服务,启动两个服务的具体步骤如下 以上是hello-service1的启动步骤,端口号为9090;同样方法设置hello-service2,端口号为9091(具体实现略)。 )启动hello-consumer )再次访问http://localhost:1111/,会发现有2个hello-service服务(端口号一个是9090,一个是9091),1个hello-consume服务 ) 多次访问http://localhost:9999/hello-consumer,会发现hello-service1和hello-service2会轮流被调用(已经实现了负责均衡),可以通过两者的控制台打印内容确认(还记得我们在hello-service的controller中有个loggerlogger.info("*********" + instance.getServiceId());吗?对,就是这个打印) 四、总结 以上实例实现了基本的服务治理: 通过spring-cloud-starter-eureka-server和@EnableEurekaServer实现服务注册中心 通过spring-cloud-starter-eureka和@EnableDiscoveryClient使用并注册到服务注册中心 通过spring-cloud-starter-eureka和@EnableDiscoveryClient使用注册中心并发现服务,通过spring-cloud-starter-ribbon来实现负载均衡消费服务 PS:这里说明下,我用的IDE是Spring Tool Suite,是spring定制版的eclipse,方便我们使用spring进行开发,有兴趣的朋友可以自行百度了解下。 from:https://www.cnblogs.com/sam-uncle/p/8954401.html
View DetailsEureka是Netflix开发的服务发现框架,本身是一个基于REST的服务,主要用于定位运行在AWS域中的中间层服务,以达到负载均衡和中间层服务故障转移的目的。SpringCloud将它集成在其子项目spring-cloud-netflix中,以实现SpringCloud的服务发现功能。 Eureka包含两个组件:Eureka Server和Eureka Client。 Eureka Server提供服务注册服务,各个节点启动后,会在Eureka Server中进行注册,这样EurekaServer中的服务注册表中将会存储所有可用服务节点的信息,服务节点的信息可以在界面中直观的看到。 Eureka Client是一个java客户端,用于简化与Eureka Server的交互,客户端同时也就是一个内置的、使用轮询(round-robin)负载算法的负载均衡器。 在应用启动后,将会向Eureka Server发送心跳,默认周期为30秒,如果Eureka Server在多个心跳周期内没有接收到某个节点的心跳,Eureka Server将会从服务注册表中把这个服务节点移除(默认90秒)。 Eureka Server之间通过复制的方式完成数据的同步,Eureka还提供了客户端缓存机制,即使所有的Eureka Server都挂掉,客户端依然可以利用缓存中的信息消费其他服务的API。综上,Eureka通过心跳检查、客户端缓存等机制,确保了系统的高可用性、灵活性和可伸缩性。 from:https://baike.baidu.com/item/Eureka/22402835?fr=aladdin
View Details出现的错误一: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sqlSessionFactory' defined in class path resource [applicationContext.xml]: Invocation of init method failed; nested exception is org.springframework.core.NestedIOException: Failed to parse config resource: class path resource [mybatis-config.xml]; nested exception is org.apache.ibatis.builder.BuilderException: Error parsing SQL Mapper Configuration. Cause: java.lang.ClassCastException: com.github.pagehelper.PageHelper cannot be cast to org.apache.ibatis.plugin.Interceptor at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1628) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:555) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483) at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:742) at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:867) at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:543) at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:443) at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:325) at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:107) at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:5017) at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5531) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150) at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:901) at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:877) at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:652) at org.apache.catalina.startup.HostConfig.deployDirectory(HostConfig.java:1263) at org.apache.catalina.startup.HostConfig$DeployDirectory.run(HostConfig.java:1948) at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471) at java.util.concurrent.FutureTask.run(FutureTask.java:262) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) at java.lang.Thread.run(Thread.java:745) Caused by: org.springframework.core.NestedIOException: Failed to parse config resource: class path resource [mybatis-config.xml]; nested exception is org.apache.ibatis.builder.BuilderException: Error parsing SQL Mapper Configuration. Cause: java.lang.ClassCastException: com.github.pagehelper.PageHelper cannot be cast to org.apache.ibatis.plugin.Interceptor at org.mybatis.spring.SqlSessionFactoryBean.buildSqlSessionFactory(SqlSessionFactoryBean.java:500) at org.mybatis.spring.SqlSessionFactoryBean.afterPropertiesSet(SqlSessionFactoryBean.java:380) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1687) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1624) … 25 more Caused by: org.apache.ibatis.builder.BuilderException: Error parsing SQL Mapper Configuration. Cause: java.lang.ClassCastException: com.github.pagehelper.PageHelper cannot be cast to org.apache.ibatis.plugin.Interceptor at org.apache.ibatis.builder.xml.XMLConfigBuilder.parseConfiguration(XMLConfigBuilder.java:121) at org.apache.ibatis.builder.xml.XMLConfigBuilder.parse(XMLConfigBuilder.java:99) at org.mybatis.spring.SqlSessionFactoryBean.buildSqlSessionFactory(SqlSessionFactoryBean.java:494) … 28 more Caused by: java.lang.ClassCastException: com.github.pagehelper.PageHelper cannot be cast to org.apache.ibatis.plugin.Interceptor at org.apache.ibatis.builder.xml.XMLConfigBuilder.pluginElement(XMLConfigBuilder.java:183) at org.apache.ibatis.builder.xml.XMLConfigBuilder.parseConfiguration(XMLConfigBuilder.java:110) … 30 more 十月 09, 2017 10:25:39 上午 org.apache.catalina.core.StandardContext listenerStart 严重: Exception sending context initialized event to listener instance of class org.springframework.web.context.ContextLoaderListener org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sqlSessionFactory' defined in class path resource [applicationContext.xml]: Invocation of init method failed; nested exception is org.springframework.core.NestedIOException: Failed to parse config resource: class path resource [mybatis-config.xml]; nested exception is org.apache.ibatis.builder.BuilderException: Error parsing SQL Mapper Configuration. Cause: java.lang.ClassCastException: com.github.pagehelper.PageHelper cannot be cast to org.apache.ibatis.plugin.Interceptor at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1628) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:555) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483) at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:742) at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:867) at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:543) at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:443) at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:325) at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:107) at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:5017) at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5531) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150) at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:901) at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:877) at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:652) at org.apache.catalina.startup.HostConfig.deployDirectory(HostConfig.java:1263) at org.apache.catalina.startup.HostConfig$DeployDirectory.run(HostConfig.java:1948) at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471) at java.util.concurrent.FutureTask.run(FutureTask.java:262) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) at java.lang.Thread.run(Thread.java:745) Caused by: org.springframework.core.NestedIOException: Failed to parse config resource: class path resource [mybatis-config.xml]; nested exception is org.apache.ibatis.builder.BuilderException: Error parsing SQL Mapper Configuration. Cause: java.lang.ClassCastException: com.github.pagehelper.PageHelper cannot be cast to org.apache.ibatis.plugin.Interceptor at org.mybatis.spring.SqlSessionFactoryBean.buildSqlSessionFactory(SqlSessionFactoryBean.java:500) at org.mybatis.spring.SqlSessionFactoryBean.afterPropertiesSet(SqlSessionFactoryBean.java:380) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1687) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1624) … 25 more Caused by: org.apache.ibatis.builder.BuilderException: Error parsing SQL Mapper Configuration. Cause: java.lang.ClassCastException: com.github.pagehelper.PageHelper cannot be cast to org.apache.ibatis.plugin.Interceptor at org.apache.ibatis.builder.xml.XMLConfigBuilder.parseConfiguration(XMLConfigBuilder.java:121) […]
View Details