一、准备工作

(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. 表白 代码 韩梦飞沙-画心.html

    韩梦飞沙  韩亚飞  313134555@qq.com  yue31313  han_meng_fei_sha 韩梦飞沙-画心.html <!DOCTYPE html> <html& ...

  2. ArrayList源码阅读----JDK1.8

    //定义一个默认的长度10 private static final int DEFAULT_CAPACITY = 10; //定义空的数组 private static final Object[] ...

  3. 安装myeclipse的常见问题

    1.破解myeclipse网站:  https://jingyan.baidu.com/article/acf728fd49519ff8e410a361.html 

  4. Two PWM outputs from MCU combine to form a monotonic 16-bits DAC

    http://www.edn.com/design/analog/4329365/Combine-two-8-bit-outputs-to-make-one-16-bit-DAC

  5. [Win32]创建模态窗口

    http://www.cnblogs.com/zplutor/archive/2011/02/20/1958973.html 在Win32编程中,如果要显示一个模态窗口,一般是先创建对话框模板,然后使 ...

  6. Spring自动扫描组件

    通常情况下,声明所有的Bean类或组件的XML bean配置文件,这样Spring容器可以检测并注册Bean类或组件. 其实,Spring是能够自动扫描,检测和预定义的项目包并实例化bean,不再有繁 ...

  7. win8升级8.1提示卸载sentinel runtime drivers

    Win8升级8.1时提示需卸载sentinel runtime drivers的解决方法 第一步:打开sentinelcustomer.safenet-inc.com/sentineldownload ...

  8. 【资料】wod旗帜,纹章

    物品 徽章 旗帜 掉落地点 备注 火焰纹章 法师与怪物 火焰魔法.魔法攻防 雄鹰纹章 受诅咒的遗迹 弩系相关 盗贼纹章 捉迷藏 偷袭.匕首.割喉.近攻防 守夜人的纹章 酒馆里平静的一天 钝器.双打.旋 ...

  9. 【IntellJ IDEA】idea上所有代码都报错了

    可能会碰到蓝屏,内存溢出重启idea等特殊情况. 重新打开idea后发现原本的代码全都报错了 正确的解决方法: 方法很简单 执行idea工具栏上下面的菜单: File -> Invalidate ...

  10. Javascript:前端利器 之 JSDuck

    背景 文档的重要性不言而喻,对于像Javascript这种的动态语言来说就更重要了,目前流行的JDoc工具挺多的,最好的当属JSDuck,可是JSDuck在Windows下的安装非常麻烦,这里就写下来 ...