总想自己动动手系列·1·本地和外网(Liunx服务器上部署的web项目)按照自定义的报文格式进行交互(一)

一、准备工作

(1)有一台属于自己的云服务器,并成功部署和发布一个web项目(当然,本质上来说Java-Project也没问题),通过外网IP可以正常访问该web项目。

  需要说明的是:任何web项目,只要成功部署后在外网上能访问到即可。本案例注重修改web对请求的监听和过滤的处理(下个版本在弄这个啦!)。

(2)本地新建Java-project,需要准备一些jar包,比如:AES加密相关的包,BASE64加相关的包,至于通信相关的类,JDK的java.io和java.net自带。

 二、Code部分

(1)第一步:首先创建一个接口,先定义好规则(比如:需要用到哪些方法等) 

 1 package com.xfwl.message.serverMsg;
 2 
 3 import java.net.URL;
 4 import java.net.URLConnection;
 5 import java.util.Map;
 6 
 7 /**
 8  * 通讯类接口
 9  * @function  
10  * @author 小风微凉
11  * @time  2018-11-8 下午2:03:39
12  */
13 public interface IHttpClient {
14     /**
15      * 默认编码格式
16      */
17     static final String CHARTER_ENCODE="UTF-8";
18     //创建报文发送对象
19     public URLConnection getClient(String url);
20     //创建发送报文方法
21     public boolean sendDataMsg(URLConnection url,String encygen);
22     //创建接收报文方法
23     public StringBuffer receiveDataMsg(URLConnection url,String encygen);
24     //创建报文加密方法
25     public StringBuffer encryptMsg(String data,String encygen);
26     //创建报文解密方法
27     public StringBuffer deCioherMsg(String data,String encygen);
28 }

 (2)第二步:准备要用到的工具类,比如报文的加密、解密等,下面用到的时AES加密(加解密时都需要加密因子,中间使用了Base64改变编码格式) 

  1 package com.xfwl.message.serverMsg;
  2 
  3 import java.security.NoSuchAlgorithmException;
  4 import java.security.SecureRandom;
  5 import java.util.logging.Level;
  6 import java.util.logging.Logger;
  7 
  8 import javax.crypto.Cipher;
  9 import javax.crypto.KeyGenerator;
 10 import javax.crypto.SecretKey;
 11 import javax.crypto.spec.SecretKeySpec;
 12 import org.apache.commons.codec.binary.Base64;
 13 /**
 14  * AES加密、解密处理工具(加密因子+base64的加解密)
 15  * @function  
 16  * @author 小风微凉
 17  * @time  2018-11-8 下午2:35:15
 18  */
 19 public class AESUtil {
 20     //默认加密秘钥
 21     private static final String KEY_ALGORITHM = "AES";
 22     //默认的加密算法
 23     private static final String DEFAULT_CIPHER_ALGORITHM = "AES/ECB/PKCS5Padding";
 24     /**
 25      * AES 加密操作
 26      *
 27      * @param content 待加密内容
 28      * @param password 加密密码
 29      * @return 返回Base64转码后的加密数据
 30      */
 31     public static String encrypt(String content, String password) {
 32         try {
 33             Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM);// 创建密码器
 34 
 35             byte[] byteContent = content.getBytes("utf-8");
 36 
 37             cipher.init(Cipher.ENCRYPT_MODE, getSecretKey(password));// 初始化为加密模式的密码器
 38 
 39             byte[] result = cipher.doFinal(byteContent);// 加密
 40 
 41             return Base64.encodeBase64String(result);//通过Base64转码返回
 42         } catch (Exception ex) {
 43             Logger.getLogger(AESUtil.class.getName()).log(Level.SEVERE, null, ex);
 44         }
 45 
 46         return null;
 47     }
 48 
 49     /**
 50      * AES 解密操作
 51      *
 52      * @param content 数据
 53      * @param password 加密因子
 54      * @return
 55      */
 56     public static String decrypt(String content, String password) {
 57         try {
 58             //实例化
 59             Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM);
 60 
 61             //使用密钥初始化,设置为解密模式
 62             cipher.init(Cipher.DECRYPT_MODE, getSecretKey(password));
 63 
 64             //执行操作
 65             byte[] result = cipher.doFinal(Base64.decodeBase64(content));
 66 
 67             return new String(result, "utf-8");
 68         } catch (Exception ex) {
 69             Logger.getLogger(AESUtil.class.getName()).log(Level.SEVERE, null, ex);
 70         }
 71         
 72         return null;
 73     }
 74 
 75     /**
 76      * 生成加密秘钥
 77      * @param   password 加密因子
 78      * @return
 79      */
 80     private static SecretKeySpec getSecretKey(final String password) {
 81         //返回生成指定算法密钥生成器的 KeyGenerator 对象
 82         KeyGenerator kg = null;
 83         try {
 84             kg = KeyGenerator.getInstance(KEY_ALGORITHM);
 85             //AES 要求密钥长度为 128
 86             kg.init(128, new SecureRandom(password.getBytes()));
 87             //生成一个密钥
 88             SecretKey secretKey = kg.generateKey();
 89 
 90             return new SecretKeySpec(secretKey.getEncoded(), KEY_ALGORITHM);// 转换为AES专用密钥
 91         } catch (NoSuchAlgorithmException ex) {
 92             Logger.getLogger(AESUtil.class.getName()).log(Level.SEVERE, null, ex);
 93         }
 94         return null;
 95     }
 96     /**
 97      * 测试
 98      * @param args
 99      */
100     public static void main(String[] args) {
101         String s = "hello,xfwl";
102         System.out.println("明文(加密前):" + s);
103         //加密
104         String s1 = AESUtil.encrypt(s, "xfwl");
105         System.out.println("加密后:" + s1);
106         //解密
107         System.out.println("解密后:"+AESUtil.decrypt(s1, "xfwl"));
108     }
109 }

 (3)第三步:开始实现步骤一中定义的规则  

  1 package com.xfwl.message.serverMsg;
  2 
  3 import java.io.BufferedOutputStream;
  4 import java.io.BufferedReader;
  5 import java.io.IOException;
  6 import java.io.InputStream;
  7 import java.io.InputStreamReader;
  8 import java.io.OutputStream;
  9 import java.io.OutputStreamWriter;
 10 import java.net.MalformedURLException;
 11 import java.net.URL;
 12 import java.net.URLConnection;
 13 import java.util.HashMap;
 14 import java.util.Iterator;
 15 import java.util.Map;
 16 import java.util.Set;
 17 import java.util.Map.Entry;
 18 
 19 public class HTTPServerClient implements IHttpClient {    
 20     /**
 21      * 报文上送数据集合
 22      */
 23     private Map<String,Object> sendMap=null;
 24     /**
 25      * 构造器
 26      */
 27     public HTTPServerClient(Map<String,Object> sendMap){
 28         this.sendMap=sendMap;
 29     }
 30     /**
 31      * 获取连接对象
 32      */
 33     public URLConnection getClient(String url) {
 34         URL u=null;
 35         try {
 36              u= new URL(url);
 37         } catch (MalformedURLException e) {
 38             e.printStackTrace();
 39         }
 40         System.out.println("建立["+url+"]链接....");
 41         //获取连接对象
 42         URLConnection uc=null;
 43         try {
 44             uc = u.openConnection();
 45         } catch (IOException e) {
 46             e.printStackTrace();
 47         }
 48         return uc;
 49     }
 50     /**
 51      * 发送报文
 52      */
 53     public boolean sendDataMsg(URLConnection uc,String encygen) {
 54         //打开输出流
 55         uc.setDoOutput(true);
 56         //获取输出流对象
 57         OutputStream raw=null;
 58         OutputStream buffered = null;
 59         OutputStreamWriter out=null;
 60         try {
 61             raw = uc.getOutputStream();
 62             buffered = new BufferedOutputStream(raw);
 63             out = new OutputStreamWriter(buffered, CHARTER_ENCODE);
 64             StringBuffer data=createMsgFormat(sendMap);
 65             System.out.println("发送报文:"+data);
 66             out.write(encryptMsg(data.toString(),encygen).toString());
 67             out.flush();
 68             System.out.println("关闭连接");
 69             out.close();
 70         } catch (IOException e) {
 71             e.printStackTrace();
 72             return false;
 73         }
 74         return true;
 75     }
 76     /**
 77      * 接收报文
 78      */
 79     public StringBuffer receiveDataMsg(URLConnection uc,String deciogen) {
 80         //获取到返回数据的输入流
 81         InputStream is=null;
 82         BufferedReader br=null;
 83         StringBuffer blzRspXml = new StringBuffer();
 84         try {
 85             is = uc.getInputStream();
 86             br = new BufferedReader(new InputStreamReader(is,CHARTER_ENCODE));
 87             String line = "";
 88             System.out.println("获取返回数据:");
 89             while((line = br.readLine()) != null){
 90                 //读取返回数据,分行读取
 91                 //System.out.println(deCioherMsg(line.trim(),deciogen));//解密
 92                 System.out.println(line.trim());
 93                 blzRspXml.append(line.trim());
 94             }
 95         } catch (IOException e) {
 96             e.printStackTrace();
 97         }
 98         return blzRspXml;
 99     }
100     /**
101      * 加密数据
102      */
103     public StringBuffer encryptMsg(String data,String encygen) {
104         return new StringBuffer(AESUtil.encrypt(data, encygen));
105     }
106     /**
107      * 解析数据
108      */
109     public StringBuffer deCioherMsg(String data,String deciogen) {
110         return new StringBuffer(AESUtil.decrypt(data, deciogen));
111     }
112     
113     /**
114      * 生成送报文:
115      *     上送报文和响应报文都需要约定一种报文格式
116      */
117     private  StringBuffer createMsgFormat(Map<String,Object> dataMap){
118         StringBuffer msg=new StringBuffer();
119         msg.append("<service>");
120         msg.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
121         msg.append("<SYS_HEAD>");
122         //存放:业务类型码
123         msg.append("<HEAD_BSNCODE>100001</HEAD_BSNCODE>");
124         msg.append("</SYS_HEAD>");
125         msg.append("<BODY>");
126         //存放:业务数据
127         Set<Entry<String, Object>> set = dataMap.entrySet();
128         Iterator<Entry<String, Object>> it = set.iterator();
129         while (it.hasNext()) {
130             Entry<String, Object> ey = it.next();
131             String key = ey.getKey();
132             String value = (String) ey.getValue();
133             msg.append("<"+key+">"+value+"</"+key+">");
134         }
135         msg.append("</BODY>");
136         msg.append("</service>");
137         return msg;
138     }
139     /**
140      * 解析响应报文:
141      * @param args
142      */
143     private StringBuffer parseRecMsgFormat(String data){
144         //...待续...
145         
146         
147         
148         return null;
149     }
150     public static void main(String[] args) {
151         Map<String,Object> sendMap =new HashMap<String, Object>();
152         sendMap.put("ADMIN", "小风微灵");
153         sendMap.put("PWD", "xfwl123");
154         //System.out.println(createMsgFormat(sendMap));
155     }
156 }

  (4)第四步:开始测试一下

 1 package com.xfwl.message.test;
 2 
 3 import java.net.URLConnection;
 4 import java.util.HashMap;
 5 import java.util.Map;
 6 
 7 import com.xfwl.message.serverMsg.HTTPServerClient;
 8 
 9 public class TestAction3 {
10     public static void main(String[] args) {
11         Map<String,Object> sendMap =new HashMap<String, Object>();
12         sendMap.put("ADMIN", "小风微灵");
13         sendMap.put("PWD", "xfwl123");
14         
15         HTTPServerClient client=new HTTPServerClient(sendMap);
16         URLConnection uc=client.getClient("http://47.105.58.153:3000");
17         client.sendDataMsg(uc,"lvjun");
18         client.receiveDataMsg(uc,"lvjun");
19     }
20 }

  看一下测试结果:

 1 建立[http://47.105.58.153:3000]链接....
 2 发送报文[明文]:<service><?xml version="1.0" encoding="UTF-8"?><SYS_HEAD><HEAD_BSNCODE>100001</HEAD_BSNCODE></SYS_HEAD><BODY><ADMIN>小风微灵</ADMIN><PWD>xfwl123</PWD></BODY></service>
 3 发送报文[密文]:UCr7pP6rDXPVlZzhcTRD20JHzoQSI7/Tb82YL6m6O25tD37RE6lW062yoRvdAv4eWxKWT2shrt97
 4 t2ZN+kjNVqkhLRaEw96yr1arAWtxri0pX0W3LYXw0Gw4LoTWsPb09a0JRv5p35Dt0QICN/Ve0+mP
 5 ayN+jCSFE3DKk5xusgSzua3adfnEdELhxbR33+CL09yI+Rc8In2NjYrsg24kkM29dJaWSRGm+ahn
 6 26OUQnI=
 7 
 8 关闭连接
 9 获取返回数据:
10 {"status":"1","msg":"未登录!","result":""}

  三、接下来准备要做的事情

  从上面的测试结果来看,已经成功完成了第一步,即将本地的请求(用自定义的报文格式处理请求数据)发送到云服务器上部署的web工程服务上,接下来要做的就是在web工程上动手,监听这类请求,根据约定的加密因子和

报文规则,解密和解析析xml报文,获取其中的请求数据,经行业务逻辑处理后按照约定的加密方式和报文规则,生成对应的响应报文,返回给本地的Java-Project,本地Java-Project再解密解析响应报文,获取响应数据,从而经行本

地的业务逻辑处理。

     一步步来吧,只要脚步不停下,就是在进步...... 

猜你喜欢

转载自www.cnblogs.com/newwind/p/9931476.html