Java讀取Eclipse和Tomcat下的properties配置文件屬性工具類:java
package www.codepeople.cn.test.utils; import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.util.Iterator; import java.util.Map; import java.util.Properties; import org.apache.log4j.Logger; /** * @ClassName: PropertiesUtil * @Description: Java讀取Eclipse和Tomcat下的properties配置文件屬性工具類 * @author 劉仁 * @date 2017年6月5日 上午11:52:58 */ public class PropertiesUtil{ private static Properties properties = new Properties(); private static String propertyName = "appWebPlatformConfig_test.properties"; public final static String FILE_SEP = System.getProperty("file.separator");//文件分隔符(在 UNIX 系統中是「/」) private final static Logger LOGGER = Logger.getLogger(PropertiesUtil.class); public synchronized static Properties getProperties(){ return System.getProperties(); } /** * 獲得一個配置參數 * @param key * @return */ public static String getProperty(String key){ return getProperties().getProperty(key); } /** * 獲得一個配置參數 * @param key * @return */ public static int getIntProperty(String key){ return Integer.valueOf(getProperties().getProperty(key)); } /** * 獲得一個配置參數 * @param key * @param defaultValue * @return */ public static String getProperty(String key,String defaultValue){ return getProperties().getProperty(key,defaultValue); } /** * 添加或更新一個配置參數 * @param key * @param value */ public static void putProperty(String key , String value){ getProperties().put(key, value); } public static String getServerPath(){//獲取服務的路徑 String path = null; File file = new File("."); try { path = file.getCanonicalPath()+FILE_SEP; } catch (IOException e) { LOGGER.error("Get Server Path error:" + e.toString()); } //LOGGER.info("Get Server Path *********** " + path); return path; } public static String getPropertyPath(String fileName){ return getServerPath()+fileName; } public static String getPropertyPath(){ String path = System.getProperty("user.dir")+FILE_SEP+"config"+FILE_SEP+propertyName; LOGGER.info(path); return propertyName; } @SuppressWarnings("rawtypes") public static String getPropertyValue(String key){ String value = null; PropertiesMapping propertiesInstance = PropertiesMapping.getInstance(); try{ if(propertiesInstance.isEmpty()){ InputStream in = PropertiesUtil.class.getClassLoader().getResourceAsStream(getPropertyPath());//包內配置文件 // String path = System.getProperty("user.dir")+FILE_SEP+propertyName;//包外配置文件,在bin目錄和主目錄,貌似兩個位置都須要更新 // InputStream in = new BufferedInputStream(new FileInputStream(path)); properties.load(in); Iterator iterator = properties.entrySet().iterator(); while (iterator.hasNext()) { Map.Entry entry = (Map.Entry) iterator.next(); Object key1 = entry.getKey(); Object val = entry.getValue(); propertiesInstance.put(String.valueOf(key1), String.valueOf(val)); } if(propertiesInstance.containsKey(key)){ value = propertiesInstance.get(key); }else{ value = properties.getProperty(key); } }else{ value = PropertiesMapping.getInstance().get(key); } }catch (FileNotFoundException e) { LOGGER.error("properties file not found:" + e.toString()); }catch (IOException e) { LOGGER.error("Load properties file error:" + e.toString()); }catch(Exception e){ LOGGER.error("Load properties file error:" + e.toString()); } return value; } }
SoapUtil解析工具類和須要引入的方法算法
package www.codepeople.cn.test.utils; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.InputStream; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.UUID; import javax.xml.soap.MessageFactory; import javax.xml.soap.SOAPConnection; import javax.xml.soap.SOAPConnectionFactory; import javax.xml.soap.SOAPMessage; import javax.xml.soap.SOAPPart; import javax.xml.transform.Source; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerFactory; import javax.xml.transform.stream.StreamResult; import javax.xml.transform.stream.StreamSource; import org.apache.log4j.Logger; import com.alibaba.fastjson.JSON; /** * * @ClassName: SoapUtil * @Description: SoapUtil解析 * @date 2017年6月5日 上午11:56:00 */ public class SoapUtil { private static Logger logger = Logger.getLogger(SoapUtil.class); /** * @param serviceName * @param transactionID * @param data * @return */ public String SoapWebService(String serviceName,String esbName,String sysId,String data) { data = "{\"SOO\":" + data + "}"; logger.info("SoapWebService服務調用入參:serviceName="+serviceName); logger.info("SoapWebService服務調用入參:esbName="+esbName); logger.info("SoapWebService服務調用入參:sysId="+sysId); logger.info("SoapWebService服務調用入參:data="+data); try { //建立鏈接 SOAPConnectionFactory soapConnFactory = SOAPConnectionFactory .newInstance(); SOAPConnection connection = soapConnFactory.createConnection(); //建立實際的消息 MessageFactory messageFactory = MessageFactory.newInstance(); SOAPMessage message = messageFactory.createMessage(); //建立消息的部分對象 SOAPPart soapPart = message.getSOAPPart(); //獲取發送報文 String xml = req(serviceName,sysId,data); logger.info("SoapWebService發送報文:xml="+xml); InputStream fileInputStream = new ByteArrayInputStream(xml.getBytes("UTF-8")); StreamSource preppedMsgSrc = new StreamSource(fileInputStream,"UTF-8"); //填充消息 soapPart.setContent(preppedMsgSrc); //保存消息 message.saveChanges(); //青牛測試環境地址 String destination = "http://172.16.100.1:8020"+esbName; //發送消息 SOAPMessage reply = connection.call(message, destination); TransformerFactory transformerFactory = TransformerFactory .newInstance(); Transformer transformer = (Transformer) transformerFactory.newTransformer(); ByteArrayOutputStream myOutStr = new ByteArrayOutputStream(); if(reply!=null){ //提取的回覆內容 Source sourceContent = reply.getSOAPPart().getContent(); //爲轉換設置輸出 StreamResult result = new StreamResult(System.out); result.setOutputStream(myOutStr); transformer.transform(sourceContent,result); } String msg = myOutStr.toString("UTF-8").trim(); logger.info("SoapWebService出參完整報文:msg="+msg); connection.close(); return rsp(msg); } catch (Exception e) { System.out.println(e.getMessage()); return ""; } } /** * 發送報文 * @param serviceName 服務名稱 * @param transactionID 流水號 * @param data 拼接報文 * @return xml報文 */ public static String req(String ServiceCode,String sysId,String data){ SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMddHHmmss"); String ReqTime = formatter.format(new Date()); String encryptValue = signatureInfo(data); Map<String, String> headMap = new HashMap<String, String>(); headMap.put("TransactionID", UUID.randomUUID().toString()); headMap.put("ReqTime", ReqTime); headMap.put("SignatureInfo", encryptValue); headMap.put("ServiceCode", ServiceCode); headMap.put("SYS_ID", sysId); String val = null; try { val = JSON.toJSONString(headMap); } catch (Exception e) { e.printStackTrace(); } String xml = "<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:SOAP-ENC=\"http://schemas.xmlsoap.org/soap/encoding/\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:ns1=\"http://www.tydic.com/\">" + "<SOAP-ENV:Header/><SOAP-ENV:Body><Business>{" + "\"TcpCont\":" + val + ",\"SvcCont\":" + data + "}</Business></SOAP-ENV:Body></SOAP-ENV:Envelope>"; return xml; } /** * 返回報文 * @param serviceName 服務名稱 * @param transactionID 流水號 * @param data 拼接報文 * @return xml報文 */ public static String rsp(String data){ RSAEncrypt rsaEncrypt = new RSAEncrypt(); String repValue = data.substring(data.indexOf("<Business>")+10, data.indexOf("</Business>")); repValue = repValue.replaceAll("'", "\""); logger.info(repValue); Map<String, Map<String, Object>> maps = null; try { maps = JSON.parseObject(repValue,Map.class); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } Map<String, Object> TcpContMap = (Map<String, Object>) maps.get("TcpCont"); Map<String, Object> SvcCont = (Map<String, Object>) maps.get("SvcCont"); String content = SvcCont.toString() ; logger.info(content); String SignatureInfo = (String) TcpContMap.get("SignatureInfo"); String decValue = rsaEncrypt.dec(SignatureInfo); logger.info(decValue); String encValue = rsaEncrypt.MD5(content); logger.info(encValue); if(decValue.equals(encValue)){ return content; }else{ return "認證失敗"; } } /** * 消息體認證 * @param json 前臺拼接的報文 * @return 認證密文 */ public static String signatureInfo(String json) { RSAEncrypt rsaEncrypt = new RSAEncrypt(); String encryptValue= null; try { String code = rsaEncrypt.MD5(json); //把MD5加密內容經過私鑰認證 encryptValue = rsaEncrypt.enc(code); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } return encryptValue; } public static void main(String[] args) { List list = new ArrayList(); Map<String, Object> data=new HashMap<String, Object>(); data.put("CHANNEL_CODE", "01"); data.put("EXT_SYSTEM", "10002"); data.put("CUST_NAME", "黃先生"); data.put("SERVICE_NBR", "13001211111"); data.put("PWD", "e10adc3949ba59abbe56e057f20f883e"); Map<String, Object> type=new HashMap<String, Object>(); type.put("TYPE", "SAVE_CUST_REQ"); List<Map<String,Object>> soo=new ArrayList<Map<String, Object>>(); soo.add(new HashMap()); soo.get(0).put("CUST", data); soo.get(0).put("PUB_REQ", type); Map<String, Object> data1=new HashMap<String, Object>(); data1.put("CHANNEL_CODE", "01"); data1.put("EXT_SYSTEM", "10002"); data1.put("CUST_NAME", "黃先生"); data1.put("SERVICE_NBR", "13001211111"); data1.put("PWD", "e10adc3949ba59abbe56e057f20f883e"); Map<String, Object> type1=new HashMap<String, Object>(); type1.put("TYPE", "SAVE_CUST_REQ"); soo.add(new HashMap()); soo.get(1).put("CUST", data); soo.get(1).put("PUB_REQ", type); String reqJson; String ll = null; try { ll = JSON.toJSONString(soo); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } SoapUtil soapUilt = new SoapUtil(); String rspJson = soapUilt.SoapWebService("/ServiceBus/custView/cust/custReg002", "/esb/Register", "108", ll); logger.info("SoapWebService服務調用報文體出參:rspJson="+rspJson); } }
package www.codepeople.cn.test.utils; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.UnsupportedEncodingException; import java.security.InvalidKeyException; import java.security.KeyFactory; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPublicKey; import java.security.spec.InvalidKeySpecException; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; import javax.crypto.NoSuchPaddingException; import org.bouncycastle.jce.provider.BouncyCastleProvider; import sun.misc.BASE64Decoder; public class RSAEncrypt { private static final String privatePath = "\\pem\\108\\rsa_private_key.pem"; private static final String publicPath = "\\pem\\108\\rsa_public_key.pem"; // private static final String privatePath = "\\pem\\2\\rsa_private_key.pem"; // // private static final String publicPath = "\\pem\\1\\rsa_public_key.pem"; /** * 私鑰 */ private RSAPrivateKey privateKey; /** * 公鑰 */ private RSAPublicKey publicKey; /** * 字節數據轉字符串專用集合 */ private static final char[] HEX_CHAR= {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; /** * 獲取私鑰 * @return 當前的私鑰對象 */ public RSAPrivateKey getPrivateKey() { return privateKey; } /** * 獲取公鑰 * @return 當前的公鑰對象 */ public RSAPublicKey getPublicKey() { return publicKey; } /** * 從文件中輸入流中加載公鑰 * @param in 公鑰輸入流 * @throws Exception 加載公鑰時產生的異常 */ public void loadPublicKey(InputStream in) throws Exception{ try { BufferedReader 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'); } } loadPublicKey(sb.toString()); } catch (IOException e) { throw new Exception("公鑰數據流讀取錯誤"); } catch (NullPointerException e) { throw new Exception("公鑰輸入流爲空"); } } /** * 從字符串中加載公鑰 * @param publicKeyStr 公鑰數據字符串 * @throws Exception 加載公鑰時產生的異常 */ public void loadPublicKey(String publicKeyStr) throws Exception{ try { BASE64Decoder base64Decoder= new BASE64Decoder(); byte[] buffer= base64Decoder.decodeBuffer(publicKeyStr); KeyFactory keyFactory= KeyFactory.getInstance("RSA"); X509EncodedKeySpec keySpec= new X509EncodedKeySpec(buffer); this.publicKey= (RSAPublicKey) keyFactory.generatePublic(keySpec); } catch (NoSuchAlgorithmException e) { throw new Exception("無此算法"); } catch (InvalidKeySpecException e) { throw new Exception("公鑰非法"); } catch (IOException e) { throw new Exception("公鑰數據內容讀取錯誤"); } catch (NullPointerException e) { throw new Exception("公鑰數據爲空"); } } /** * 從文件中加載私鑰 * @param keyFileName 私鑰文件名 * @return 是否成功 * @throws Exception */ public void loadPrivateKey(InputStream in) throws Exception{ try { BufferedReader 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'); } } loadPrivateKey(sb.toString()); } catch (IOException e) { throw new Exception("私鑰數據讀取錯誤"); } catch (NullPointerException e) { throw new Exception("私鑰輸入流爲空"); } } public void loadPrivateKey(String privateKeyStr) throws Exception{ try { BASE64Decoder base64Decoder= new BASE64Decoder(); byte[] buffer= base64Decoder.decodeBuffer(privateKeyStr); PKCS8EncodedKeySpec keySpec= new PKCS8EncodedKeySpec(buffer); KeyFactory keyFactory= KeyFactory.getInstance("RSA"); this.privateKey= (RSAPrivateKey) keyFactory.generatePrivate(keySpec); } catch (NoSuchAlgorithmException e) { throw new Exception("無此算法"); } catch (InvalidKeySpecException e) { throw new Exception("私鑰非法"); } catch (IOException e) { throw new Exception("私鑰數據內容讀取錯誤"); } catch (NullPointerException e) { throw new Exception("私鑰數據爲空"); } } /** * 加密過程 * @param privateKey 私鑰 * @param plainTextData 明文數據 * @return * @throws Exception 加密過程當中的異常信息 */ public byte[] encrypt(RSAPrivateKey privateKey, byte[] plainTextData) throws Exception{ if(privateKey== null){ throw new Exception("加密私鑰爲空, 請設置"); } Cipher cipher= null; try { cipher= Cipher.getInstance("RSA/ECB/PKCS1Padding", new BouncyCastleProvider()); cipher.init(Cipher.ENCRYPT_MODE, privateKey); byte[] output= cipher.doFinal(plainTextData); return output; } catch (NoSuchAlgorithmException e) { throw new Exception("無此加密算法"); } catch (NoSuchPaddingException e) { e.printStackTrace(); return null; }catch (InvalidKeyException e) { throw new Exception("加密公鑰非法,請檢查"); } catch (IllegalBlockSizeException e) { throw new Exception("明文長度非法"); } catch (BadPaddingException e) { throw new Exception("明文數據已損壞"); } } /** * 解密過程 * @param publicKey 公鑰 * @param cipherData 密文數據 * @return 明文 * @throws Exception 解密過程當中的異常信息 */ public byte[] decrypt(RSAPublicKey publicKey, byte[] cipherData) throws Exception{ if (publicKey== null){ throw new Exception("解密公鑰爲空, 請設置"); } Cipher cipher= null; try { cipher= Cipher.getInstance("RSA/ECB/PKCS1Padding", new BouncyCastleProvider()); cipher.init(Cipher.DECRYPT_MODE, publicKey); byte[] output= cipher.doFinal(cipherData); return output; } catch (NoSuchAlgorithmException e) { throw new Exception("無此解密算法"); } catch (NoSuchPaddingException e) { e.printStackTrace(); return null; }catch (InvalidKeyException e) { throw new Exception("解密私鑰非法,請檢查"); } catch (IllegalBlockSizeException e) { throw new Exception("密文長度非法"); } catch (BadPaddingException e) { throw new Exception("密文數據已損壞"); } } /** * 字節數據轉十六進制字符串 * @param data 輸入數據 * @return 十六進制內容 */ public static String byteArrayToString(byte[] data){ StringBuilder stringBuilder= new StringBuilder(); for (int i=0; i<data.length; i++){ //取出字節的高四位 做爲索引獲得相應的十六進制標識符 注意無符號右移 stringBuilder.append(HEX_CHAR[(data[i] & 0xf0)>>> 4]); //取出字節的低四位 做爲索引獲得相應的十六進制標識符 stringBuilder.append(HEX_CHAR[(data[i] & 0x0f)]); if (i<data.length-1){ stringBuilder.append(' '); } } return stringBuilder.toString(); } public static String byte2hex(byte[] b) { String hs = ""; String stmp = ""; for (int n = 0; n < b.length; n++) { stmp = (java.lang.Integer.toHexString(b[n] & 0XFF)); if (stmp.length() == 1) hs = hs + "0" + stmp; else hs = hs + stmp; } return hs.toUpperCase(); } public static byte[] hexStringToByte(String hex) { int len = (hex.length() / 2); byte[] result = new byte[len]; char[] achar = hex.toCharArray(); for (int i = 0; i < len; i++) { int pos = i * 2; result[i] = (byte) (toByte(achar[pos]) << 4 | toByte(achar[pos + 1])); } return result; } private static byte toByte(char c) { byte b = (byte) "0123456789ABCDEF".indexOf(c); return b; } /** * 私鑰加密 */ public String enc(String code){ RSAEncrypt rsaEncrypt= new RSAEncrypt(); String encryptValue = null; try { // String relativelyPath=System.getProperty("user.dir"); // File file = new File(relativelyPath+privatePath); InputStream is = RSAEncrypt.class.getClassLoader().getResourceAsStream("hh/pem/rsa_private_key.pem"); //File file = new File("src/main/resources/hh/pem/rsa_private_key.pem"); //FileInputStream fis = new FileInputStream(is); rsaEncrypt.loadPrivateKey(is); byte[] cipher = rsaEncrypt.encrypt(rsaEncrypt.getPrivateKey(), code.getBytes()); encryptValue = byte2hex(cipher); } catch (Exception e) { System.err.println(e.getMessage()); System.err.println("加載私鑰失敗"); } return encryptValue; } /** * 公鑰解密 */ public String dec(String signatureInfo){ RSAEncrypt rsaEncrypt= new RSAEncrypt(); String Text = null; try { // String relativelyPath=System.getProperty("user.dir"); // File file = new File(relativelyPath+publicPath); InputStream is = RSAEncrypt.class.getClassLoader().getResourceAsStream("hh/pem/rsa_public_key.pem"); //File file = new File("src/main/resources/hh/pem/rsa_public_key.pem"); //FileInputStream fis = new FileInputStream(file); rsaEncrypt.loadPublicKey(is); byte[] decCipher = hexStringToByte(signatureInfo); byte[] plainText = rsaEncrypt.decrypt(rsaEncrypt.getPublicKey(), decCipher); //Text = new String(RSAEncrypt.byte2hex(plainText)); Text = new String(plainText); } catch (Exception e) { System.err.println(e.getMessage()); System.err.println("加載公鑰失敗"); } return Text; } /** * MD5加密 * @param val 明文 * @return 密文 */ public String MD5(String val){ MessageDigest md5 = null; try { md5 = MessageDigest.getInstance("MD5"); } catch (NoSuchAlgorithmException e) { // TODO Auto-generated catch block e.printStackTrace(); } try { md5.update(val.getBytes("UTF-8")); } catch (UnsupportedEncodingException e) { /** TODO Auto-generated catch block */ e.printStackTrace(); } String code = RSAEncrypt.byte2hex(md5.digest()); return code; } public static void main(String[] args){ RSAEncrypt rsaEncrypt = new RSAEncrypt(); //加載私鑰 try { File file = new File("D:/work/SaleWeb/pem/2/rsa_private_key.pem"); FileInputStream fis = new FileInputStream(file); rsaEncrypt.loadPrivateKey(fis);// RSAEncrypt.class.getResourceAsStream("/configuration.properties")); } catch (Exception e1) { // TODO Auto-generated catch block e1.printStackTrace(); } //加載公鑰 try { File file = new File("D:/work/SaleWeb/pem/2/rsa_public_key.pem"); FileInputStream fis = new FileInputStream(file); rsaEncrypt.loadPublicKey(fis); System.out.println("加載公鑰成功"); } catch (Exception e) { System.err.println(e.getMessage()); System.err.println("加載公鑰失敗"); } //測試字符串 String encryptStr= "{\"SOO\":[{\"CUST_LOGIN\":{\"EXT_SYSTEM\":\"111111\",\"LOGIN_NBR\":\"18108611556\",\"LOGIN_TYPE\":\"1\",\"PWD\":\"123456\",\"SEL_IN_ORG_ID\":\"01\"},\"PUB_REQ\":{\"TYPE\":\"Example\"}}]}"; try { String code = rsaEncrypt.MD5(encryptStr); System.out.println("MD5加密:"+code); //加密 byte[] cipher = rsaEncrypt.encrypt(rsaEncrypt.getPrivateKey(), code.getBytes()); System.out.println("私鑰加密:"+RSAEncrypt.byte2hex(cipher)); //解密 //String dec = "C3C1B2C330325EE1FBE7C938B7D563BB1E2BCC2287658C9B79BDC656188DD4836FB84CA7157837E6726B7D3375AAF9A04FD391FB790F7A33ED5F738709BECAD388BE8E60EA3F3A454B78C3D8C92B499A9711E0F14F8FD85BD08F7335986C04F779B62B19B28B744B2D676F66D7A3BBB720F1FFA1E4AB968CFADD5A293FA48483"; String dec = "1BC4A127E12A10E6563408330C119E2138E419311229086100147CAD8B9171477BBB11010F86352318F09EF55750DEB3EA8886DE090DE3A81A7D1B2F786814A04AFD81EA2B1C8588F44F3ED2CC06BA02079FDB497FCC29CB05838EC568666F6CE692102D8B17E4722EC0289203B2D7B169F35D51DE83F0F689E6B42CC1F054A3"; byte[] decCipher = hexStringToByte(dec); byte[] plainText = rsaEncrypt.decrypt(rsaEncrypt.getPublicKey(), decCipher); System.out.println("公鑰解密:"+new String(plainText)); } catch (Exception e) { System.err.println(e.getMessage()); } } }
以及所需的pom.xml文件apache
<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/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>HelloWorld</groupId> <artifactId>SayHello</artifactId> <packaging>war</packaging> <version>0.0.1-SNAPSHOT</version> <name>SayHello Maven Webapp</name> <url>http://maven.apache.org</url> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>3.8.1</version> <scope>test</scope> </dependency> <!-- https://mvnrepository.com/artifact/log4j/log4j --> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency> <!-- https://mvnrepository.com/artifact/com.alibaba/fastjson --> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.31</version> </dependency> <!-- https://mvnrepository.com/artifact/org.bouncycastle/bcprov-jdk15on --> <dependency> <groupId>org.bouncycastle</groupId> <artifactId>bcprov-jdk15on</artifactId> <version>1.57</version> </dependency> </dependencies> <build> <finalName>SayHello</finalName> </build> </project>