返回顶部

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

一、准备工作

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

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

(2)本地新建Java-project,需要准备一些jar包,比如:AES加密相关的包,BASE64加相关的包,解析XML的包,至于通信相关的类,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.List;
 16 import java.util.Map;
 17 import java.util.Set;
 18 import java.util.Map.Entry;
 19 
 20 import org.dom4j.Attribute;
 21 import org.dom4j.Document;
 22 import org.dom4j.DocumentException;
 23 import org.dom4j.DocumentHelper;
 24 import org.dom4j.Element;
 25 
 26 public class HTTPServerClient implements IHttpClient {    
 27     /**
 28      * 报文上送数据集合
 29      */
 30     private Map<String,Object> sendMap=null;
 31     /**
 32      * 构造器
 33      */
 34     public HTTPServerClient(Map<String,Object> sendMap){
 35         this.sendMap=sendMap;
 36     }
 37     /**
 38      * 获取连接对象
 39      */
 40     public URLConnection getClient(String url) {
 41         URL u=null;
 42         try {
 43              u= new URL(url);
 44         } catch (MalformedURLException e) {
 45             e.printStackTrace();
 46         }
 47         System.out.println("建立["+url+"]链接....");
 48         //获取连接对象
 49         URLConnection uc=null;
 50         try {
 51             uc = u.openConnection();
 52         } catch (IOException e) {
 53             e.printStackTrace();
 54         }
 55         return uc;
 56     }
 57     /**
 58      * 发送报文
 59      */
 60     public boolean sendDataMsg(URLConnection uc,String encygen) {
 61         //打开输出流
 62         uc.setDoOutput(true);
 63         //获取输出流对象
 64         OutputStream raw=null;
 65         OutputStream buffered = null;
 66         OutputStreamWriter out=null;
 67         try {
 68             raw = uc.getOutputStream();
 69             buffered = new BufferedOutputStream(raw);
 70             out = new OutputStreamWriter(buffered, CHARTER_ENCODE);
 71             StringBuffer data=createMsgFormat(sendMap);
 72             System.out.println("发送报文[明文]:"+data);
 73             out.write(encryptMsg(data.toString(),encygen).toString());
 74             System.out.println("发送报文[密文]:"+encryptMsg(data.toString(),encygen).toString());
 75             out.flush();
 76             System.out.println("关闭连接");
 77             out.close();
 78         } catch (IOException e) {
 79             e.printStackTrace();
 80             return false;
 81         }
 82         return true;
 83     }
 84     /**
 85      * 接收报文
 86      */
 87     public StringBuffer receiveDataMsg(URLConnection uc,String deciogen) {
 88         //获取到返回数据的输入流
 89         InputStream is=null;
 90         BufferedReader br=null;
 91         StringBuffer blzRspXml = new StringBuffer();
 92         try {
 93             is = uc.getInputStream();
 94             br = new BufferedReader(new InputStreamReader(is,CHARTER_ENCODE));
 95             String line = "";
 96             System.out.println("获取返回数据:");
 97             while((line = br.readLine()) != null){
 98                 //读取返回数据,分行读取
 99                 //System.out.println(deCioherMsg(line.trim(),deciogen));//解密
100                 System.out.println(line.trim());
101                 blzRspXml.append(line.trim());
102             }
103         } catch (IOException e) {
104             e.printStackTrace();
105         }
106         return blzRspXml;
107     }
108     /**
109      * 加密数据
110      */
111     public StringBuffer encryptMsg(String data,String encygen) {
112         return new StringBuffer(AESUtil.encrypt(data, encygen));
113     }
114     /**
115      * 解析数据
116      */
117     public StringBuffer deCioherMsg(String data,String deciogen) {
118         return new StringBuffer(AESUtil.decrypt(data, deciogen));
119     }
120     
121     /**
122      * 生成送报文:
123      *     上送报文和响应报文都需要约定一种报文格式
124      */
125     private  StringBuffer createMsgFormat(Map<String,Object> dataMap){
126         StringBuffer msg=new StringBuffer();
127         msg.append("<service>");
128         /*msg.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");*/
129         msg.append("<SYS_HEAD>");
130         //存放:业务类型码
131         msg.append("<HEAD_BSNCODE>100001</HEAD_BSNCODE>");
132         msg.append("</SYS_HEAD>");
133         msg.append("<BODY>");
134         //存放:业务数据
135         Set<Entry<String, Object>> set = dataMap.entrySet();
136         Iterator<Entry<String, Object>> it = set.iterator();
137         while (it.hasNext()) {
138             Entry<String, Object> ey = it.next();
139             String key = ey.getKey();
140             String value = (String) ey.getValue();
141             msg.append("<"+key+">"+value+"</"+key+">");
142         }
143         msg.append("</BODY>");
144         msg.append("</service>");
145         return msg;
146     }
147     /**
148      * 解析响应报文:通过dom4j解析xml字符串
149      * @param args
150      */
151     public Map<String,Object> parseRecMsgFormat(String xml){
152         Map<String,Object> recMap =new HashMap<String, Object>();
153         Document doc=null;
154         Element root=null;
155         List<Element> elems=null;
156         List<Element> elems_head=null;
157         List<Element> elems_body=null;
158         try {
159             doc=DocumentHelper.parseText(xml);
160             root=doc.getRootElement();
161             elems=root.elements();
162             for(Element elem:elems){
163                 //开始解析结点
164                 if("SYS_HEAD".equals(elem.getName())){
165                     //检查报文头
166                     elems_head=elem.elements();
167                     for(Element head:elems_head){
168                         if("HEAD_BSNCODE".equals(head.getName())){
169                             recMap.put("HEAD_BSNCODE", head.getText());
170                         }
171                     }
172                 }else if("BODY".equals(elem.getName())){
173                     //检查报文体
174                     elems_body=elem.elements();
175                     for(Element body:elems_body){
176                         recMap.put(body.getName(), body.getText());
177                     }
178                 }
179                 /*List<Attribute> attrs=elem.attributes();
180                 for(Attribute attr:attrs){
181                     //开始解析结点的属性
182                     if("HEAD_BSNCODE".equals(attr.getText())){
183                         System.out.println(elem.getName()+":"+elem.getText());
184                     }
185                 }*/
186             }
187         } catch (DocumentException e) {
188             e.printStackTrace();
189         }
190         return recMap;
191     }
192     public static void main(String[] args) {
193         Map<String,Object> sendMap =new HashMap<String, Object>();
194         sendMap.put("ADMIN", "小风微灵");
195         sendMap.put("PWD", "xfwl123");
196         //System.out.println(createMsgFormat(sendMap));
197     }
198 }

   (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再解密解析响应报文,获取响应数据,从而经行本

地的业务逻辑处理。

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

posted @ 2018-11-08 19:45  小风微灵-彦  阅读(316)  评论(0编辑  收藏  举报
加载中……