1. import com.alibaba.fastjson.JSON;
    2. import org.apache.commons.logging.Log;
    3. import org.apache.commons.logging.LogFactory;
    4. import javax.tools.JavaCompiler;
    5. import javax.tools.JavaFileObject;
    6. import javax.tools.StandardJavaFileManager;
    7. import javax.tools.ToolProvider;
    8. import java.io.BufferedWriter;
    9. import java.io.File;
    10. import java.io.FileWriter;
    11. import java.io.IOException;
    12. import java.lang.reflect.Method;
    13. import java.util.ArrayList;
    14. import java.util.HashMap;
    15. import java.util.List;
    16. import java.util.Map;
    17. public class ClassUtil {
    18. private static final Log logger = LogFactory.getLog(ClassUtil.class);
    19. private static final JavaCompiler compiler;
    20. static {
    21. compiler = ToolProvider.getSystemJavaCompiler();
    22. }
    23. /**
    24. * 获取java文件路径
    25. *
    26. * @param file
    27. * @return
    28. */
    29. private static String getFilePath(String file) {
    30. int last1 = file.lastIndexOf('/');
    31. int last2 = file.lastIndexOf('\\');
    32. return file.substring(0, Math.max(last1, last2)) + File.separatorChar;
    33. }
    34. /**
    35. * 编译java文件
    36. *
    37. * @param ops 编译参数
    38. * @param files 编译文件
    39. */
    40. private static void javac(List<String> ops, String... files) {
    41. StandardJavaFileManager manager = null;
    42. try {
    43. manager = compiler.getStandardFileManager(null, null, null);
    44. Iterable<? extends JavaFileObject> it = manager.getJavaFileObjects(files);
    45. JavaCompiler.CompilationTask task = compiler.getTask(null, manager, null, ops, null, it);
    46. task.call();
    47. if (logger.isDebugEnabled()) {
    48. for (String file : files)
    49. logger.debug("Compile Java File:" + file);
    50. }
    51. } catch (Exception e) {
    52. logger.error(e);
    53. } finally {
    54. if (manager != null) {
    55. try {
    56. manager.close();
    57. } catch (IOException e) {
    58. e.printStackTrace();
    59. }
    60. }
    61. }
    62. }
    63. /**
    64. * 生成java文件
    65. *
    66. * @param file 文件名
    67. * @param source java代码
    68. * @throws Exception
    69. */
    70. private static void writeJavaFile(String file, String source) throws Exception {
    71. if (logger.isDebugEnabled()) {
    72. logger.debug("Write Java Source Code to:" + file);
    73. }
    74. BufferedWriter bw = null;
    75. try {
    76. File dir = new File(getFilePath(file));
    77. if (!dir.exists())
    78. dir.mkdirs();
    79. bw = new BufferedWriter(new FileWriter(file));
    80. bw.write(source);
    81. bw.flush();
    82. } catch (Exception e) {
    83. throw e;
    84. } finally {
    85. if (bw != null) {
    86. bw.close();
    87. }
    88. }
    89. }
    90. /**
    91. * 加载类
    92. *
    93. * @param name 类名
    94. * @return
    95. */
    96. private static Class<?> load(String name) {
    97. Class<?> cls = null;
    98. ClassLoader classLoader = null;
    99. try {
    100. classLoader = ClassUtil.class.getClassLoader();
    101. cls = classLoader.loadClass(name);
    102. if (logger.isDebugEnabled()) {
    103. logger.debug("Load Class[" + name + "] by " + classLoader);
    104. }
    105. } catch (Exception e) {
    106. logger.error(e);
    107. }
    108. return cls;
    109. }
    110. /**
    111. * 编译代码并加载类
    112. *
    113. * @param filePath java代码路径
    114. * @param source java代码
    115. * @param clsName 类名
    116. * @param ops 编译参数
    117. * @return
    118. */
    119. public static Class<?> loadClass(String filePath, String source, String clsName, List<String> ops) {
    120. try {
    121. writeJavaFile(filePath, source);
    122. javac(ops, filePath);
    123. return load(clsName);
    124. } catch (Exception e) {
    125. logger.error(e);
    126. }
    127. return null;
    128. }
    129. /**
    130. * 调用类方法
    131. *
    132. * @param cls 类
    133. * @param methodName 方法名
    134. * @param paramsCls 方法参数类型
    135. * @param params 方法参数
    136. * @return
    137. */
    138. public static Object invoke(Class<?> cls, String methodName, Class<?>[] paramsCls, Object[] params) {
    139. Object result = null;
    140. try {
    141. Method method = cls.getDeclaredMethod(methodName, paramsCls);
    142. Object obj = cls.newInstance();
    143. result = method.invoke(obj, params);
    144. } catch (Exception e) {
    145. logger.error(e);
    146. }
    147. return result;
    148. }
    149. public static void main(String[] args) {
    150. StringBuilder sb = new StringBuilder();
    151. sb.append("package antu.gxpt.util.encry;\n" +
    152. "\n" +
    153. "import com.alibaba.fastjson.JSON;\n" +
    154. "import com.alibaba.fastjson.JSONObject;\n" +
    155. "\n" +
    156. "import javax.crypto.*;\n" +
    157. "import javax.crypto.spec.DESKeySpec;\n" +
    158. "import java.security.InvalidKeyException;\n" +
    159. "import java.security.NoSuchAlgorithmException;\n" +
    160. "import java.security.spec.InvalidKeySpecException;\n" +
    161. "\n" +
    162. "/**\n" +
    163. " * @author big_song\n" +
    164. " * @date 2022/6/15 14:59\n" +
    165. " * @desc\n" +
    166. " */\n" +
    167. "public class TestEncty {\n" +
    168. " private static final String DES_ALGORITHM = \"DES\";\n" +
    169. "\n" +
    170. " public static void main(String[] args) {\n" +
    171. " try {\n" +
    172. " String encryption = encryption(\"{\\n\" + \"\\t\\\"MsgHeader\\\": {\\n\" + \"\\t\\t\\\"TrnCode\\\": \\\"BDC.9001.001.01\\\",\\n\" + \"\\t\\t\\\"RefId\\\": \\\"20170901AA000001\\\",\\n\" + \"\\t\\t\\\"ReqRefId\\\": \\\"\\\",\\n\" + \"\\t\\t\\\"Token\\\": \\\"\\\",\\n\" + \"\\t\\t\\\"Remark\\\": \\\"\\\"\\n\" + \"\\t},\\n\" + \"\\t\\\"MsgBody\\\": {\\n\" + \"\\t\\t\\\"LoginName\\\": \\\"admin\\\",\\n\" + \"\\t\\t\\\"PassWord\\\": \\\"123456\\\"\\n\" + \"\\t}\\n\" + \"}\", \"u9eGtLIa6e1Ne2iyutOk\");\n" +
    173. " System.out.println(encryption);\n" +
    174. " System.out.println(\"============================\");\n" +
    175. " JSONObject jsonObject = new JSONObject();\n" +
    176. " jsonObject.put(\"content\", encryption);\n" +
    177. " jsonObject.put(\"key\", \"u9eGtLIa6e1Ne2iyutOk\");\n" +
    178. " String decryption = decryption(jsonObject.toString());\n" +
    179. " System.out.println(decryption);\n" +
    180. " } catch (Exception e) {\n" +
    181. " throw new RuntimeException(e);\n" +
    182. " }\n" +
    183. " }\n" +
    184. "\n" +
    185. " /**\n" +
    186. " * DES加密\n" +
    187. " *\n" +
    188. " * @param plainData 原始字符串\n" +
    189. " * @param secretKey 加密密钥\n" +
    190. " * @return 加密后的字符串\n" +
    191. " * @throws Exception\n" +
    192. " */\n" +
    193. " public static String encryption(String plainData, String secretKey) throws Exception {\n" +
    194. "\n" +
    195. " Cipher cipher = null;\n" +
    196. " try {\n" +
    197. " cipher = Cipher.getInstance(DES_ALGORITHM);\n" +
    198. " cipher.init(Cipher.ENCRYPT_MODE, generateKey(secretKey));\n" +
    199. "\n" +
    200. " } catch (NoSuchAlgorithmException e) {\n" +
    201. " e.printStackTrace();\n" +
    202. " } catch (NoSuchPaddingException e) {\n" +
    203. " e.printStackTrace();\n" +
    204. " } catch (InvalidKeyException e) {\n" +
    205. "\n" +
    206. " }\n" +
    207. "\n" +
    208. " try {\n" +
    209. " // 为了防止解密时报javax.crypto.IllegalBlockSizeException: Input length must\n" +
    210. " // be multiple of 8 when decrypting with padded cipher异常,\n" +
    211. " // 不能把加密后的字节数组直接转换成字符串\n" +
    212. " byte[] buf = cipher.doFinal(plainData.getBytes());\n" +
    213. " return Base64Util.encryptBASE64(buf);\n" +
    214. " } catch (IllegalBlockSizeException e) {\n" +
    215. " e.printStackTrace();\n" +
    216. " throw new Exception(\"IllegalBlockSizeException\", e);\n" +
    217. " } catch (BadPaddingException e) {\n" +
    218. " e.printStackTrace();\n" +
    219. " throw new Exception(\"BadPaddingException\", e);\n" +
    220. " }\n" +
    221. "\n" +
    222. " }\n" +
    223. "\n" +
    224. "\n" +
    225. " /**\n" +
    226. " * DES解密\n" +
    227. " *\n" +
    228. " * @return 原始字符串\n" +
    229. " * @throws Exception\n" +
    230. " */\n" +
    231. " public static String decryption(String params) throws Exception {\n" +
    232. " JSONObject jsonObject = JSON.parseObject(params);\n" +
    233. " // 密码字符串\n" +
    234. " String secretData = jsonObject.getString(\"content\");\n" +
    235. " // 解密密钥\n" +
    236. " String secretKey = jsonObject.getString(\"key\");\n" +
    237. " Cipher cipher = null;\n" +
    238. " try {\n" +
    239. " cipher = Cipher.getInstance(DES_ALGORITHM);\n" +
    240. " cipher.init(Cipher.DECRYPT_MODE, generateKey(secretKey));\n" +
    241. "\n" +
    242. " } catch (NoSuchAlgorithmException e) {\n" +
    243. " e.printStackTrace();\n" +
    244. " throw new Exception(\"NoSuchAlgorithmException\", e);\n" +
    245. " } catch (NoSuchPaddingException e) {\n" +
    246. " e.printStackTrace();\n" +
    247. " throw new Exception(\"NoSuchPaddingException\", e);\n" +
    248. " } catch (InvalidKeyException e) {\n" +
    249. " e.printStackTrace();\n" +
    250. " throw new Exception(\"InvalidKeyException\", e);\n" +
    251. " }\n" +
    252. "\n" +
    253. " try {\n" +
    254. " byte[] buf = cipher.doFinal(Base64Util.decryBASE64(secretData));\n" +
    255. " return new String(buf);\n" +
    256. "\n" +
    257. " } catch (IllegalBlockSizeException e) {\n" +
    258. " e.printStackTrace();\n" +
    259. " throw new Exception(\"IllegalBlockSizeException\", e);\n" +
    260. " } catch (BadPaddingException e) {\n" +
    261. " e.printStackTrace();\n" +
    262. " throw new Exception(\"BadPaddingException\", e);\n" +
    263. " }\n" +
    264. " }\n" +
    265. "\n" +
    266. " /**\n" +
    267. " * 获得秘密密钥\n" +
    268. " *\n" +
    269. " * @param secretKey\n" +
    270. " * @return\n" +
    271. " * @throws NoSuchAlgorithmException\n" +
    272. " * @throws InvalidKeySpecException\n" +
    273. " * @throws InvalidKeyException\n" +
    274. " */\n" +
    275. " private static SecretKey generateKey(String secretKey)\n" +
    276. " throws NoSuchAlgorithmException, InvalidKeySpecException, InvalidKeyException {\n" +
    277. " SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(DES_ALGORITHM);\n" +
    278. " DESKeySpec keySpec = new DESKeySpec(secretKey.getBytes());\n" +
    279. " keyFactory.generateSecret(keySpec);\n" +
    280. " return keyFactory.generateSecret(keySpec);\n" +
    281. " }\n" +
    282. "}\n");
    283. //设置编译参数
    284. ArrayList<String> ops = new ArrayList<>();
    285. ops.add("-Xlint:unchecked");
    286. //编译代码,返回class
    287. Class<?> cls = ClassUtil.loadClass("/antu/gxpt/util/encry//TestEncty.java", sb.toString(), "antu.gxpt.util.encry.TestEncty", ops);
    288. //准备测试数据
    289. Map<String, String> data = new HashMap<>();
    290. data.put("content", "FcZPxffiRxP4SOBbgmrRS7tXjobATegwfJETTA+xbmmJxEHf0zssu1H+BlMKpqYIuVAghbg/VDRo\n" +
    291. "cZeppZijFTJJJcYn/wJEYD8isvuPSgaDNF70AGVCFjZv/YR3QWkFF9SRL7tk5ILv1OeLnzdB4DEM\n" +
    292. "VwSg8nygUwLmuR5K+/U0jSjHYWWByLSGDrpeUl9h1/IOIlx5OdG7k3abiAMGxpPf/nAnfrsnh3vA\n" +
    293. "tEKI0Y5X6XKW64qei+3vmXo5/sO5Xdpazc72qT0=");
    294. data.put("key", "u9eGtLIa6e1Ne2iyutOk");
    295. //执行测试方法
    296. Object result = ClassUtil.invoke(cls, "decryption", new Class[]{String.class}, new Object[]{JSON.toJSONString(data)});
    297. //输出结果
    298. System.out.println(data);
    299. System.out.println("(30*f1+20*f2+50*f3)/100 = " + result);
    300. }
    301. }