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

一、准备工作

(1)创建一个web-project工程,部署本地可正常访问,部署在云服务上可访问。

(2)理解如何在web.xml文件中配置过滤器,和创建一个自定义的过滤器。

(3)懂得如何打war包,和部署云服务上。

(4)准备相关jar包。

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

二、本地Java-Project和本地web-Project交互

(1)创建一个web-project工程,需要注意tomcat、jdk、j2ee的版本。本案例用的是:tomcat7.0、jdk1.7.08、j2ee6,版本不兼容,会导致tomcat无法启动。

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

(2)创建一个请求过滤器。

 package com.xfwl.filter;

 import java.io.BufferedReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry; import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import com.xfwl.tool.SecurityUtil;
/**
* 请求过滤器
* @author xfwl
*
*/
public class RequestFilter implements Filter { private FilterConfig config = null;
@Override
public void destroy() {
System.out.println("销毁...");
}
/**
* 开始过滤操作
*/
@Override
public void doFilter(ServletRequest req, ServletResponse resp,FilterChain chain) throws IOException, ServletException {
// 强制类型转换
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) resp;
// 获取web.xm设置的编码集,设置到Request、Response中
request.setCharacterEncoding(config.getInitParameter("charset"));
response.setContentType(config.getInitParameter("contentType"));
response.setCharacterEncoding(config.getInitParameter("charset"));
/**
* 解析请求报文
*/
System.out.println("执行中...");
String miWen=getRequestBody(request);
if("".equals(miWen)|| miWen==null){
// 将请求转发到目的地
chain.doFilter(request, response);
}else{
System.out.println("[密文]"+miWen);
StringBuffer MingWen=SecurityUtil.deCioherMsg(miWen,"lvjun");
System.out.println("[明文]"+MingWen);
Map<String,Object> recMap=SecurityUtil.parseRecMsgFormat(MingWen.toString());
Set<Entry<String, Object>> set = recMap.entrySet();
Iterator<Entry<String, Object>> it = set.iterator();
System.out.println("----------------------");
while (it.hasNext()) {
Entry<String, Object> ey = it.next();
String key = ey.getKey();
String value = (String) ey.getValue();
System.out.println(key+":"+value);
}
System.out.println("----------------------");
/**
* 处理数据并生成响应报文并返回
*/
Map<String,Object> sendMap =new HashMap<String, Object>();
sendMap.put("RETURN_CODE", "90");
sendMap.put("RETURN_MSG", "交易成功");
StringBuffer sb=SecurityUtil.createMsgFormat(sendMap);
StringBuffer finRespData= SecurityUtil.encryptMsg(sb.toString(), "lvjun");
writeResponse(response,finRespData.toString());
}
}
/**
* 获取请求数据
* @param req
* @return
*/
private String getRequestBody(HttpServletRequest req) {
try {
BufferedReader reader = req.getReader();
StringBuffer sb = new StringBuffer();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line);
}
String json = sb.toString();
return json;
} catch (IOException e) {
System.out.println("获取请求报文数据失败!");
}
return "";
}
/**
* 输出响应数据
* @param response
* @param responseString
* @throws IOException
*/
private void writeResponse(ServletResponse response, String responseString)
throws IOException {
PrintWriter out = response.getWriter();
out.print(responseString);
out.flush();
out.close();
}
/**
* 初始化配置
*/
@Override
public void init(FilterConfig config) throws ServletException {
this.config = config;
System.out.println("初始化...");
}
}

(3)创建一个验证工具类

 package com.xfwl.tool;

 import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set; import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element; /**
* 数据安全工具
* @author Jason
*
*/
public class SecurityUtil {
/**
* 加密数据
*/
public static StringBuffer encryptMsg(String data,String encygen) {
return new StringBuffer(AESUtil.encrypt(data, encygen));
}
/**
* 解析数据
*/
public static StringBuffer deCioherMsg(String data,String deciogen) {
return new StringBuffer(AESUtil.decrypt(data, deciogen));
}
/**
* 生成送报文:
* 上送报文和响应报文都需要约定一种报文格式
*/
public static 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 static 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;
}
}

(4)修改web.xml,配置过滤器

 <?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<display-name></display-name>
<!-- 默认界面 -->
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<!-- 配置过滤器 -->
<filter>
<filter-name>filter</filter-name>
<filter-class>com.xfwl.filter.RequestFilter</filter-class>
<init-param>
<param-name>charset</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>contentType</param-name>
<param-value>text/html;charset=UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>filter</filter-name>
<!-- * 代表截获所有的请求 或指定请求/test.do /xxx.do -->
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>

(5)部署项目并在本地启动tomcat服务

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

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

(6)在执行本系列的上一篇中所创建的java-project项目

 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:8080/ServerClientPro/index.jsp");
//URLConnection uc=client.getClient("http://127.0.0.1:8080/ServerClientPro/test.do");
client.sendDataMsg(uc,"lvjun");
client.receiveDataMsg(uc,"lvjun");
//解析响应报文
String recXml="<service><SYS_HEAD><HEAD_BSNCODE>100001</HEAD_BSNCODE></SYS_HEAD><BODY><ADMIN>小风微灵</ADMIN><PWD>xfwl123</PWD></BODY></service>";
client.parseRecMsgFormat(recXml); }
}

执行结果:

 建立[http://localhost:8080/ServerClientPro/index.jsp]链接....
发送报文[明文]:<service><SYS_HEAD><HEAD_BSNCODE>100001</HEAD_BSNCODE></SYS_HEAD><BODY><ADMIN>小风微灵</ADMIN><PWD>xfwl123</PWD></BODY></service>
发送报文[密文]:oT+IL24P52UJmNyxUWrImyA+HhFpfM6Ho0WBdwD0iH9vhyhwzMZBNXw+9AyMbWQQinmwA5j+vEzV
lSSrCiaQEqEuBtP+x+E8Scuzf8hoY6AkHP7la1/HLPjuCJ7qi7QumwZGDcqHayMZGeVO8hk2aAlR
KASYGnQaoJNhoiEiu4dpkBIYBXbcrjcKy5xPnSEM 关闭连接
获取返回数据:
oT+IL24P52UJmNyxUWrImyA+HhFpfM6Ho0WBdwD0iH9vhyhwzMZBNXw+9AyMbWQQinmwA5j+vEzV
lSSrCiaQEnBNbuW52YU4s2iCWx4LO5EYsUx2UfggGP559kQneTznDU9bAM4mmzpBA1PwxHti9M00
mkV4+RbTzZl9RpPbjp057Q4Yu9CrA5uxImbr1TOBM6m1cUhDCZAAppCGuAR2KQ==
[密文]oT+IL24P52UJmNyxUWrImyA+HhFpfM6Ho0WBdwD0iH9vhyhwzMZBNXw+9AyMbWQQinmwA5j+vEzVlSSrCiaQEnBNbuW52YU4s2iCWx4LO5EYsUx2UfggGP559kQneTznDU9bAM4mmzpBA1PwxHti9M00mkV4+RbTzZl9RpPbjp057Q4Yu9CrA5uxImbr1TOBM6m1cUhDCZAAppCGuAR2KQ==
[明文]<service><SYS_HEAD><HEAD_BSNCODE>100001</HEAD_BSNCODE></SYS_HEAD><BODY><RETURN_MSG>交易成功</RETURN_MSG><RETURN_CODE>90</RETURN_CODE></BODY></service>
----------------------
RETURN_MSG:交易成功
RETURN_CODE:90
HEAD_BSNCODE:100001
----------------------

(7)观察本地web-project项目控制台打印的内容

 执行中...
[密文]oT+IL24P52UJmNyxUWrImyA+HhFpfM6Ho0WBdwD0iH9vhyhwzMZBNXw+9AyMbWQQinmwA5j+vEzVlSSrCiaQEqEuBtP+x+E8Scuzf8hoY6AkHP7la1/HLPjuCJ7qi7QumwZGDcqHayMZGeVO8hk2aAlRKASYGnQaoJNhoiEiu4dpkBIYBXbcrjcKy5xPnSEM
[明文]<service><SYS_HEAD><HEAD_BSNCODE>100001</HEAD_BSNCODE></SYS_HEAD><BODY><ADMIN>小风微灵</ADMIN><PWD>xfwl123</PWD></BODY></service>
----------------------
PWD:xfwl123
ADMIN:小风微灵
HEAD_BSNCODE:100001
----------------------

从上面的打印内容可以得知,web服务器接收到了本期上送的报文,并成功解析处理和作出响应,并且本地java-project也接收到了这种响应。

三、本地Java-Project和云服务器上部署的web-Project交互

(1)将本地的web-project打war包

第一步:导出1

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

第二步:导出2

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

第三步:查看war包

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

由于此时的war包中,并没有j2ee相关的jar包,所以需要找到手动放入到war包中

第四步:找到J2EE相关的Jar包,注意J2EE版本

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

将Jar包放入war包中

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

第四步:将该war包上传到云服务上tomcat下的webapps目录下,启动服务

上传war包

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

启动服务

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

第五步:本地java-project发出请求报文

 建立[http://47.105.58.153:8080/ServerClientPro/index.jsp]链接....
发送报文[明文]:<service><SYS_HEAD><HEAD_BSNCODE>100001</HEAD_BSNCODE></SYS_HEAD><BODY><ADMIN>小风微灵</ADMIN><PWD>xfwl123</PWD></BODY></service>
发送报文[密文]:oT+IL24P52UJmNyxUWrImyA+HhFpfM6Ho0WBdwD0iH9vhyhwzMZBNXw+9AyMbWQQinmwA5j+vEzV
lSSrCiaQEqEuBtP+x+E8Scuzf8hoY6AkHP7la1/HLPjuCJ7qi7QumwZGDcqHayMZGeVO8hk2aAlR
KASYGnQaoJNhoiEiu4dpkBIYBXbcrjcKy5xPnSEM 关闭连接
获取返回数据:
oT+IL24P52UJmNyxUWrImyA+HhFpfM6Ho0WBdwD0iH9vhyhwzMZBNXw+9AyMbWQQinmwA5j+vEzV
lSSrCiaQEnBNbuW52YU4s2iCWx4LO5EYsUx2UfggGP559kQneTznDU9bAM4mmzpBA1PwxHti9M00
mkV4+RbTzZl9RpPbjp057Q4Yu9CrA5uxImbr1TOBM6m1cUhDCZAAppCGuAR2KQ==
[密文]oT+IL24P52UJmNyxUWrImyA+HhFpfM6Ho0WBdwD0iH9vhyhwzMZBNXw+9AyMbWQQinmwA5j+vEzVlSSrCiaQEnBNbuW52YU4s2iCWx4LO5EYsUx2UfggGP559kQneTznDU9bAM4mmzpBA1PwxHti9M00mkV4+RbTzZl9RpPbjp057Q4Yu9CrA5uxImbr1TOBM6m1cUhDCZAAppCGuAR2KQ==
[明文]<service><SYS_HEAD><HEAD_BSNCODE>100001</HEAD_BSNCODE></SYS_HEAD><BODY><RETURN_MSG>交易成功</RETURN_MSG><RETURN_CODE>90</RETURN_CODE></BODY></service>
----------------------
RETURN_MSG:交易成功
RETURN_CODE:90
HEAD_BSNCODE:100001
----------------------

第六步:查看云服务上的tomcat日志

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

从上面的日志中,可以看出,服务器是接收到了请求报文,但是却抛出了加密因子数据异常,经过分析和找度娘,知道了原因,是AES获取生成随机加密因子时候,Window系统与Liunx系统的不同造成的。

造成这一现象的代码块是:

 /**
* 生成加密秘钥:window系统和Linux系统环境不同,造成加密因子不统一
* @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;
}

修改后的代码

 /**
* 生成加密秘钥:window系统和Linux系统环境不同,造成加密因子不统一
* @param password 加密因子
* @return
*/
private static SecretKeySpec getSecretKey2(final String password) {
//返回生成指定算法密钥生成器的 KeyGenerator 对象
KeyGenerator kg = null;
SecureRandom random=null;
try {
kg = KeyGenerator.getInstance(KEY_ALGORITHM);
try {
random=SecureRandom.getInstance("SHA1PRNG","SUN");
random.setSeed(password.getBytes());
//AES 要求密钥长度为 128
kg.init(128,random);
//生成一个密钥
SecretKey secretKey = kg.generateKey();
return new SecretKeySpec(secretKey.getEncoded(), KEY_ALGORITHM);// 转换为AES专用密钥
} catch (NoSuchProviderException e) {
e.printStackTrace();
}
} catch (NoSuchAlgorithmException ex) {
Logger.getLogger(AESUtil.class.getName()).log(Level.SEVERE, null, ex);
}
return null;
}

代码调整后,重新执行,查看日志有如下:

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

可见,Window系统和Linux系统造成加密因子的差异性得到了解决。

上一篇:Linux下RocketMQ环境的配置


下一篇:SQL Server 全文搜索 配置、查询初体验