一、准备工作

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

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

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

 二、Code部分

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

 package com.xfwl.message.serverMsg;

 import java.net.URL;
import java.net.URLConnection;
import java.util.Map; /**
* 通讯类接口
* @function
* @author 小风微凉
* @time 2018-11-8 下午2:03:39
*/
public interface IHttpClient {
/**
* 默认编码格式
*/
static final String CHARTER_ENCODE="UTF-8";
//创建报文发送对象
public URLConnection getClient(String url);
//创建发送报文方法
public boolean sendDataMsg(URLConnection url,String encygen);
//创建接收报文方法
public StringBuffer receiveDataMsg(URLConnection url,String encygen);
//创建报文加密方法
public StringBuffer encryptMsg(String data,String encygen);
//创建报文解密方法
public StringBuffer deCioherMsg(String data,String encygen);
}

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

 package com.xfwl.message.serverMsg;

 import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.logging.Level;
import java.util.logging.Logger; import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Base64;
/**
* AES加密、解密处理工具(加密因子+base64的加解密)
* @function
* @author 小风微凉
* @time 2018-11-8 下午2:35:15
*/
public class AESUtil {
//默认加密秘钥
private static final String KEY_ALGORITHM = "AES";
//默认的加密算法
private static final String DEFAULT_CIPHER_ALGORITHM = "AES/ECB/PKCS5Padding";
/**
* AES 加密操作
*
* @param content 待加密内容
* @param password 加密密码
* @return 返回Base64转码后的加密数据
*/
public static String encrypt(String content, String password) {
try {
Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM);// 创建密码器 byte[] byteContent = content.getBytes("utf-8"); cipher.init(Cipher.ENCRYPT_MODE, getSecretKey(password));// 初始化为加密模式的密码器 byte[] result = cipher.doFinal(byteContent);// 加密 return Base64.encodeBase64String(result);//通过Base64转码返回
} catch (Exception ex) {
Logger.getLogger(AESUtil.class.getName()).log(Level.SEVERE, null, ex);
} return null;
} /**
* AES 解密操作
*
* @param content 数据
* @param password 加密因子
* @return
*/
public static String decrypt(String content, String password) {
try {
//实例化
Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM); //使用密钥初始化,设置为解密模式
cipher.init(Cipher.DECRYPT_MODE, getSecretKey(password)); //执行操作
byte[] result = cipher.doFinal(Base64.decodeBase64(content)); return new String(result, "utf-8");
} catch (Exception ex) {
Logger.getLogger(AESUtil.class.getName()).log(Level.SEVERE, null, ex);
} return null;
} /**
* 生成加密秘钥
* @param password 加密因子
* @return
*/
private static SecretKeySpec getSecretKey(final String password) {
//返回生成指定算法密钥生成器的 KeyGenerator 对象
KeyGenerator kg = null;
try {
kg = KeyGenerator.getInstance(KEY_ALGORITHM);
//AES 要求密钥长度为 128
kg.init(128, new SecureRandom(password.getBytes()));
//生成一个密钥
SecretKey secretKey = kg.generateKey(); return new SecretKeySpec(secretKey.getEncoded(), KEY_ALGORITHM);// 转换为AES专用密钥
} catch (NoSuchAlgorithmException ex) {
Logger.getLogger(AESUtil.class.getName()).log(Level.SEVERE, null, ex);
}
return null;
}
/**
* 测试
* @param args
*/
public static void main(String[] args) {
String s = "hello,xfwl";
System.out.println("明文(加密前):" + s);
//加密
String s1 = AESUtil.encrypt(s, "xfwl");
System.out.println("加密后:" + s1);
//解密
System.out.println("解密后:"+AESUtil.decrypt(s1, "xfwl"));
}
}

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

 package com.xfwl.message.serverMsg;

 import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry; import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element; public class HTTPServerClient implements IHttpClient {
/**
* 报文上送数据集合
*/
private Map<String,Object> sendMap=null;
/**
* 构造器
*/
public HTTPServerClient(Map<String,Object> sendMap){
this.sendMap=sendMap;
}
/**
* 获取连接对象
*/
public URLConnection getClient(String url) {
URL u=null;
try {
u= new URL(url);
} catch (MalformedURLException e) {
e.printStackTrace();
}
System.out.println("建立["+url+"]链接....");
//获取连接对象
URLConnection uc=null;
try {
uc = u.openConnection();
} catch (IOException e) {
e.printStackTrace();
}
return uc;
}
/**
* 发送报文
*/
public boolean sendDataMsg(URLConnection uc,String encygen) {
//打开输出流
uc.setDoOutput(true);
//获取输出流对象
OutputStream raw=null;
OutputStream buffered = null;
OutputStreamWriter out=null;
try {
raw = uc.getOutputStream();
buffered = new BufferedOutputStream(raw);
out = new OutputStreamWriter(buffered, CHARTER_ENCODE);
StringBuffer data=createMsgFormat(sendMap);
System.out.println("发送报文[明文]:"+data);
out.write(encryptMsg(data.toString(),encygen).toString());
System.out.println("发送报文[密文]:"+encryptMsg(data.toString(),encygen).toString());
out.flush();
System.out.println("关闭连接");
out.close();
} catch (IOException e) {
e.printStackTrace();
return false;
}
return true;
}
/**
* 接收报文
*/
public StringBuffer receiveDataMsg(URLConnection uc,String deciogen) {
//获取到返回数据的输入流
InputStream is=null;
BufferedReader br=null;
StringBuffer blzRspXml = new StringBuffer();
try {
is = uc.getInputStream();
br = new BufferedReader(new InputStreamReader(is,CHARTER_ENCODE));
String line = "";
System.out.println("获取返回数据:");
while((line = br.readLine()) != null){
//读取返回数据,分行读取
//System.out.println(deCioherMsg(line.trim(),deciogen));//解密
System.out.println(line.trim());
blzRspXml.append(line.trim());
}
} catch (IOException e) {
e.printStackTrace();
}
return blzRspXml;
}
/**
* 加密数据
*/
public StringBuffer encryptMsg(String data,String encygen) {
return new StringBuffer(AESUtil.encrypt(data, encygen));
}
/**
* 解析数据
*/
public StringBuffer deCioherMsg(String data,String deciogen) {
return new StringBuffer(AESUtil.decrypt(data, deciogen));
} /**
* 生成送报文:
* 上送报文和响应报文都需要约定一种报文格式
*/
private StringBuffer createMsgFormat(Map<String,Object> dataMap){
StringBuffer msg=new StringBuffer();
msg.append("<service>");
/*msg.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");*/
msg.append("<SYS_HEAD>");
//存放:业务类型码
msg.append("<HEAD_BSNCODE>100001</HEAD_BSNCODE>");
msg.append("</SYS_HEAD>");
msg.append("<BODY>");
//存放:业务数据
Set<Entry<String, Object>> set = dataMap.entrySet();
Iterator<Entry<String, Object>> it = set.iterator();
while (it.hasNext()) {
Entry<String, Object> ey = it.next();
String key = ey.getKey();
String value = (String) ey.getValue();
msg.append("<"+key+">"+value+"</"+key+">");
}
msg.append("</BODY>");
msg.append("</service>");
return msg;
}
/**
* 解析响应报文:通过dom4j解析xml字符串
* @param args
*/
public Map<String,Object> parseRecMsgFormat(String xml){
Map<String,Object> recMap =new HashMap<String, Object>();
Document doc=null;
Element root=null;
List<Element> elems=null;
List<Element> elems_head=null;
List<Element> elems_body=null;
try {
doc=DocumentHelper.parseText(xml);
root=doc.getRootElement();
elems=root.elements();
for(Element elem:elems){
//开始解析结点
if("SYS_HEAD".equals(elem.getName())){
//检查报文头
elems_head=elem.elements();
for(Element head:elems_head){
if("HEAD_BSNCODE".equals(head.getName())){
recMap.put("HEAD_BSNCODE", head.getText());
}
}
}else if("BODY".equals(elem.getName())){
//检查报文体
elems_body=elem.elements();
for(Element body:elems_body){
recMap.put(body.getName(), body.getText());
}
}
/*List<Attribute> attrs=elem.attributes();
for(Attribute attr:attrs){
//开始解析结点的属性
if("HEAD_BSNCODE".equals(attr.getText())){
System.out.println(elem.getName()+":"+elem.getText());
}
}*/
}
} catch (DocumentException e) {
e.printStackTrace();
}
return recMap;
}
public static void main(String[] args) {
Map<String,Object> sendMap =new HashMap<String, Object>();
sendMap.put("ADMIN", "小风微灵");
sendMap.put("PWD", "xfwl123");
//System.out.println(createMsgFormat(sendMap));
}
}

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

 package com.xfwl.message.test;

 import java.net.URLConnection;
import java.util.HashMap;
import java.util.Map; import com.xfwl.message.serverMsg.HTTPServerClient; public class TestAction3 {
public static void main(String[] args) {
Map<String,Object> sendMap =new HashMap<String, Object>();
sendMap.put("ADMIN", "小风微灵");
sendMap.put("PWD", "xfwl123"); HTTPServerClient client=new HTTPServerClient(sendMap);
URLConnection uc=client.getClient("http://47.105.58.153:3000");
client.sendDataMsg(uc,"lvjun");
client.receiveDataMsg(uc,"lvjun");
}
}

看一下测试结果:

 建立[http://47.105.58.153:3000]链接....
发送报文[明文]:<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>
发送报文[密文]:UCr7pP6rDXPVlZzhcTRD20JHzoQSI7/Tb82YL6m6O25tD37RE6lW062yoRvdAv4eWxKWT2shrt97
t2ZN+kjNVqkhLRaEw96yr1arAWtxri0pX0W3LYXw0Gw4LoTWsPb09a0JRv5p35Dt0QICN/Ve0+mP
ayN+jCSFE3DKk5xusgSzua3adfnEdELhxbR33+CL09yI+Rc8In2NjYrsg24kkM29dJaWSRGm+ahn
26OUQnI= 关闭连接
获取返回数据:
{"status":"1","msg":"未登录!","result":""}

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

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

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

地的业务逻辑处理。

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

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

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

    一.准备工作 (1)创建一个web-project工程,部署本地可正常访问,部署在云服务上可访问. (2)理解如何在web.xml文件中配置过滤器,和创建一个自定义的过滤器. (3)懂得如何打war包 ...

  2. 总想自己动动手系列·3·微信公众号和外网服务交互之通过TOKEN验证(准备篇·1)

    一.准备工作 (1)准备一个微信公众号(对私的订阅号或者对公的服务号). (2)准备一台部署了web应用,并且已经发布出去的Linux服务器(需要说明的是:微信公众号强烈建议使用80端口,使用其他自定 ...

  3. 使用Docker在服务器上部署Ubuntu,本地传文件到docker

    使用Docker在服务器上部署Ubuntu,本地传文件到docker 作者:王佳乐 目录 安装Docker 安装Docker 全部安装流程: 登录服务器 ssh username@ip 检查是否已经安 ...

  4. 【Python】【辅助程序】练手小程序:记录外网动态IP地址

    练手小程序 程序作用:对IP实时记录: 1.定时获取外网IP,存储在本地文件中: 编写思路: 1)收集获取外网的API接口       http://bbs.125.la/thread-1383897 ...

  5. 使用natapp本地映射外网服务

    官网:https://natapp.cn/ 软件很好用,这对于前端工程师来说,有了这个工具就很爽了,当你的领导或者不在你公司内网范围内的人,想要看你的页面效果,就很简单了. 详细的不用更多介绍,直接去 ...

  6. ***git 本地提交后如果让服务器上的GIT 自动更新拉取

    Q: 最近配了个服务器,用的GIT,本地提交后服务器必须再拉取一下才能更新出来..求个提交后自动更新的方法 A: 最佳工具 git hook post-update.sample 改名为post-up ...

  7. video视频在本地可以播放,在服务器上不可以播放

    今天遇到一个比较坑的问题,视频在本地可以播放,然后放到服务器上面就播放不了,原因是因为服务器上面不支持mp4的播放,下面看解决办法.1.首先进入IIS(Internet Information Ser ...

  8. 从云主机上下载文件到本地+获取外网地址(linux & Windows)

    云主机上下载有集中方法,腾讯论坛有一遍文章:向云服务器上传下载文件方法汇总 货比三家,最终还是选择了rsync 下载代码如下 rsync ubuntu@123.207.251.217:/var/www ...

  9. SQLServer怎样把本地数据导入到远程服务器上(转载)

    平常用到mssql时间比较少,总是过一段时间就忘记应该怎么操作了.当要做mssq把本地数据导入到远程服务器的时候,就去网上搜索很久都没有图解的,所以今天自己收集一下免得下次又到处去找.希望对自己,同时 ...

随机推荐

  1. HDU3530【STL/单调队列/RMQ】

    题目链接[http://acm.hdu.edu.cn/showproblem.php?pid=3530] 题意:输入n,m,k;n代表n个点,在这n(n<100000)个点中找到最长的连续子序列 ...

  2. 【BZOJ 2555】 2555: SubString (SAM+LCT)

    2555: SubString Time Limit: 30 Sec  Memory Limit: 512 MBSubmit: 2548  Solved: 762 Description 懒得写背景了 ...

  3. Opencv学习笔记1:安装opencv和VS2015并进行环境配置

    用了Opencv一段时间了,简单记录一下opencv在vs2015下的配置. 第一部分:OpenCV3.2.0的下载 OpenCV官方下载地址: https://opencv.org/releases ...

  4. NOIP2017 D2T3列队

    这题我改了三天,考场上部分分暴力拿了50,考完试发现与正解很接近只是没写出来. 对于每一行和最后一列建n+1颗线段树,维护前缀和. 复杂度qlogn 假如你移动一个坐标为(x,y)的人,你要将第x行线 ...

  5. dcoker常用命令

    记录一下常用的命令 docker run -t -i  xxxx /bin/bash 运行容器的交互会话shell docker start xxxx 启动容器 docker stop xxxx 停止 ...

  6. 不思议迷宫:逆向后的放置play

    前言 前置准备 目标分析 逆向加密逻辑 定位sign与key 解密luac 反编译luajit的bytecode 开启上帝模式 前言     看了fatezero的<阴阳师:一个非酋的逆向旅程& ...

  7. c# -- Form1_Load()不被执行的三个解决方法

    我的第一个c#练习程序,果然又出现问题了...在Form1_Load() not work.估计我的人品又出现问题了. 下面实现的功能很简单,就是声明一个label1然后,把它初始化赋值为hello, ...

  8. python开发_difflib字符串比较

    在python的difflib中 HtmlDiff:比较后以html方法展示 我们比较的是字符串: 'hello world!' 和 'hElLO Wor2d!' 具体代码: from difflib ...

  9. HDU 5653 Bomber Man wants to bomb an Array. dp

    Bomber Man wants to bomb an Array. 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5653 Description ...

  10. svn 服务器搭建及使用 三

    SVN服务器搭建和使用(三) 接下来,试试用TortoiseSVN修改文件,添加文件,删除文件,以及如何解决冲突等. 添加文件 在检出的工作副本中添加一个Readme.txt文本文件,这时候这个文本文 ...