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


    一、准备工作

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

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

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

    (4)准备相关jar包。

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

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

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

      1 package com.xfwl.filter;
      2 
      3 import java.io.BufferedReader;
      4 import java.io.IOException;
      5 import java.io.PrintWriter;
      6 import java.util.HashMap;
      7 import java.util.Iterator;
      8 import java.util.Map;
      9 import java.util.Set;
     10 import java.util.Map.Entry;
     11 
     12 import javax.servlet.Filter;
     13 import javax.servlet.FilterChain;
     14 import javax.servlet.FilterConfig;
     15 import javax.servlet.ServletException;
     16 import javax.servlet.ServletRequest;
     17 import javax.servlet.ServletResponse;
     18 import javax.servlet.http.HttpServletRequest;
     19 import javax.servlet.http.HttpServletResponse;
     20 
     21 import com.xfwl.tool.SecurityUtil;
     22 /**
     23  * 请求过滤器
     24  * @author xfwl
     25  * 
     26  */
     27 public class RequestFilter implements Filter {
     28 
     29     private FilterConfig config = null; 
     30     @Override
     31     public void destroy() {
     32         System.out.println("销毁...");
     33     }
     34     /**
     35      * 开始过滤操作
     36      */
     37     @Override
     38     public void doFilter(ServletRequest req, ServletResponse resp,FilterChain chain) throws IOException, ServletException {
     39          // 强制类型转换  
     40          HttpServletRequest request = (HttpServletRequest) req;  
     41          HttpServletResponse response = (HttpServletResponse) resp; 
     42          // 获取web.xm设置的编码集,设置到Request、Response中  
     43          request.setCharacterEncoding(config.getInitParameter("charset"));  
     44          response.setContentType(config.getInitParameter("contentType"));  
     45          response.setCharacterEncoding(config.getInitParameter("charset"));
     46          /**
     47           * 解析请求报文
     48           */
     49          System.out.println("执行中...");
     50          String miWen=getRequestBody(request);
     51          if("".equals(miWen)|| miWen==null){
     52              // 将请求转发到目的地  
     53              chain.doFilter(request, response); 
     54          }else{
     55              System.out.println("[密文]"+miWen);
     56              StringBuffer MingWen=SecurityUtil.deCioherMsg(miWen,"lvjun");
     57              System.out.println("[明文]"+MingWen);
     58              Map<String,Object> recMap=SecurityUtil.parseRecMsgFormat(MingWen.toString());
     59              Set<Entry<String, Object>> set = recMap.entrySet();
     60              Iterator<Entry<String, Object>> it = set.iterator();
     61                 System.out.println("----------------------");
     62              while (it.hasNext()) {
     63                  Entry<String, Object> ey = it.next();
     64                  String key = ey.getKey();
     65                  String value = (String) ey.getValue();
     66                  System.out.println(key+":"+value);
     67              }
     68             System.out.println("----------------------");
     69             /**
     70              * 处理数据并生成响应报文并返回
     71              */
     72             Map<String,Object> sendMap =new HashMap<String, Object>();
     73             sendMap.put("RETURN_CODE", "90");
     74             sendMap.put("RETURN_MSG", "交易成功");
     75             StringBuffer sb=SecurityUtil.createMsgFormat(sendMap);
     76             StringBuffer finRespData= SecurityUtil.encryptMsg(sb.toString(), "lvjun");
     77             writeResponse(response,finRespData.toString());
     78          }
     79     }
     80     /**
     81      * 获取请求数据
     82      * @param req
     83      * @return
     84      */
     85     private String getRequestBody(HttpServletRequest req) {
     86         try {
     87             BufferedReader reader = req.getReader();
     88             StringBuffer sb = new StringBuffer();
     89             String line = null;
     90             while ((line = reader.readLine()) != null) {
     91                 sb.append(line);
     92             }
     93             String json = sb.toString();
     94             return json;
     95         } catch (IOException e) {
     96             System.out.println("获取请求报文数据失败!");
     97         }
     98         return "";
     99     }
    100     /**
    101      * 输出响应数据
    102      * @param response
    103      * @param responseString
    104      * @throws IOException
    105      */
    106     private void writeResponse(ServletResponse response, String responseString)
    107             throws IOException {
    108         PrintWriter out = response.getWriter();
    109         out.print(responseString);
    110         out.flush();
    111         out.close();
    112     }
    113     /**
    114      * 初始化配置
    115      */
    116     @Override
    117     public void init(FilterConfig config) throws ServletException {        
    118         this.config = config;  
    119         System.out.println("初始化...");
    120     }
    121 }

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

      1 package com.xfwl.tool;
      2 
      3 import java.util.HashMap;
      4 import java.util.Iterator;
      5 import java.util.List;
      6 import java.util.Map;
      7 import java.util.Map.Entry;
      8 import java.util.Set;
      9 
     10 import org.dom4j.Document;
     11 import org.dom4j.DocumentException;
     12 import org.dom4j.DocumentHelper;
     13 import org.dom4j.Element;
     14 
     15 /**
     16  * 数据安全工具
     17  * @author Jason
     18  *
     19  */
     20 public class SecurityUtil {
     21     /**
     22      * 加密数据
     23      */
     24     public static StringBuffer encryptMsg(String data,String encygen) {
     25         return new StringBuffer(AESUtil.encrypt(data, encygen));
     26     }
     27     /**
     28      * 解析数据
     29      */
     30     public static StringBuffer deCioherMsg(String data,String deciogen) {
     31         return new StringBuffer(AESUtil.decrypt(data, deciogen));
     32     }
     33     /**
     34      * 生成送报文:
     35      *     上送报文和响应报文都需要约定一种报文格式
     36      */
     37     public static StringBuffer createMsgFormat(Map<String,Object> dataMap){
     38         StringBuffer msg=new StringBuffer();
     39         msg.append("<service>");
     40         /*msg.append("<?xml version="1.0" encoding="UTF-8"?>");*/
     41         msg.append("<SYS_HEAD>");
     42         //存放:业务类型码
     43         msg.append("<HEAD_BSNCODE>100001</HEAD_BSNCODE>");
     44         msg.append("</SYS_HEAD>");
     45         msg.append("<BODY>");
     46         //存放:业务数据
     47         Set<Entry<String, Object>> set = dataMap.entrySet();
     48         Iterator<Entry<String, Object>> it = set.iterator();
     49         while (it.hasNext()) {
     50             Entry<String, Object> ey = it.next();
     51             String key = ey.getKey();
     52             String value = (String) ey.getValue();
     53             msg.append("<"+key+">"+value+"</"+key+">");
     54         }
     55         msg.append("</BODY>");
     56         msg.append("</service>");
     57         return msg;
     58     }
     59     /**
     60      * 解析响应报文:通过dom4j解析xml字符串
     61      * @param args
     62      */
     63     public static Map<String,Object> parseRecMsgFormat(String xml){
     64         Map<String,Object> recMap =new HashMap<String, Object>();
     65         Document doc=null;
     66         Element root=null;
     67         List<Element> elems=null;
     68         List<Element> elems_head=null;
     69         List<Element> elems_body=null;
     70         try {
     71             doc=DocumentHelper.parseText(xml);
     72             root=doc.getRootElement();
     73             elems=root.elements();
     74             for(Element elem:elems){
     75                 //开始解析结点的属性
     76                 if("SYS_HEAD".equals(elem.getName())){
     77                     //检查报文头
     78                     elems_head=elem.elements();
     79                     for(Element head:elems_head){
     80                         if("HEAD_BSNCODE".equals(head.getName())){
     81                             recMap.put("HEAD_BSNCODE", head.getText());
     82                         }
     83                     }
     84                 }else if("BODY".equals(elem.getName())){
     85                     //检查报文体
     86                     elems_body=elem.elements();
     87                     for(Element body:elems_body){
     88                         recMap.put(body.getName(), body.getText());
     89                     }
     90                 }
     91                 /*List<Attribute> attrs=elem.attributes();
     92                 for(Attribute attr:attrs){
     93                     //开始解析结点的属性
     94                     if("HEAD_BSNCODE".equals(attr.getText())){
     95                         System.out.println(elem.getName()+":"+elem.getText());
     96                     }
     97                 }*/
     98             }
     99         } catch (DocumentException e) {
    100             e.printStackTrace();
    101         }
    102         return recMap;
    103     }
    104 }

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

     1 <?xml version="1.0" encoding="UTF-8"?>
     2 <web-app version="3.0" 
     3     xmlns="http://java.sun.com/xml/ns/javaee" 
     4     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     5     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
     6     http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
     7   <display-name></display-name>    
     8   <!-- 默认界面 -->
     9       <welcome-file-list>
    10         <welcome-file>index.jsp</welcome-file>
    11       </welcome-file-list>
    12   <!-- 配置过滤器 -->
    13     <filter>  
    14       <filter-name>filter</filter-name>  
    15       <filter-class>com.xfwl.filter.RequestFilter</filter-class>  
    16       <init-param>  
    17           <param-name>charset</param-name>  
    18           <param-value>UTF-8</param-value>  
    19       </init-param>  
    20       <init-param>  
    21           <param-name>contentType</param-name>  
    22           <param-value>text/html;charset=UTF-8</param-value>  
    23       </init-param>  
    24      </filter>  
    25      <filter-mapping>  
    26           <filter-name>filter</filter-name>  
    27           <!-- * 代表截获所有的请求  或指定请求/test.do  /xxx.do -->  
    28           <url-pattern>/*</url-pattern>  
    29       </filter-mapping>
    30 </web-app>

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

      

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

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

      执行结果:

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

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

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

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

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

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

    第一步:导出1

     

    第二步:导出2

    第三步:查看war包

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

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

     

    将Jar包放入war包中

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

    上传war包

    启动服务

     

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

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

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

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

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

     1 /**
     2      * 生成加密秘钥:window系统和Linux系统环境不同,造成加密因子不统一
     3      * @param   password 加密因子
     4      * @return
     5      */
     6     private static SecretKeySpec getSecretKey(final String password) {
     7         //返回生成指定算法密钥生成器的 KeyGenerator 对象
     8         KeyGenerator kg = null;
     9         try {
    10             kg = KeyGenerator.getInstance(KEY_ALGORITHM);
    11             //AES 要求密钥长度为 128
    12             kg.init(128, new SecureRandom(password.getBytes()));
    13             //生成一个密钥
    14             SecretKey secretKey = kg.generateKey();
    15 
    16             return new SecretKeySpec(secretKey.getEncoded(), KEY_ALGORITHM);// 转换为AES专用密钥
    17         } catch (NoSuchAlgorithmException ex) {
    18             Logger.getLogger(AESUtil.class.getName()).log(Level.SEVERE, null, ex);
    19         }
    20         return null;
    21     }

     修改后的代码

     1 /**
     2      * 生成加密秘钥:window系统和Linux系统环境不同,造成加密因子不统一
     3      * @param   password 加密因子
     4      * @return
     5      */
     6     private static SecretKeySpec getSecretKey2(final String password) {
     7         //返回生成指定算法密钥生成器的 KeyGenerator 对象
     8         KeyGenerator kg = null;
     9         SecureRandom random=null;
    10         try {
    11             kg = KeyGenerator.getInstance(KEY_ALGORITHM);
    12             try {
    13                 random=SecureRandom.getInstance("SHA1PRNG","SUN");
    14                 random.setSeed(password.getBytes());
    15                 //AES 要求密钥长度为 128
    16                 kg.init(128,random);
    17                 //生成一个密钥
    18                 SecretKey secretKey = kg.generateKey();
    19                 return new SecretKeySpec(secretKey.getEncoded(), KEY_ALGORITHM);// 转换为AES专用密钥
    20             } catch (NoSuchProviderException e) {
    21                 e.printStackTrace();
    22             }
    23         } catch (NoSuchAlgorithmException ex) {
    24             Logger.getLogger(AESUtil.class.getName()).log(Level.SEVERE, null, ex);
    25         }
    26         return null;
    27     }

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

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

  • 相关阅读:
    3dmax安装、破解与插件安装--以2014为例
    两数求和java(字符串强转int型)
    《大道至简》第一章伪代码(四个小部分)
    咳咳,软工新手读《大道至简》读后感
    一:requests爬虫基础
    爬虫
    Django中ORM系统多表数据操作
    Django中ORM简介与单表数据操作
    Django初识
    jQuery基础
  • 原文地址:https://www.cnblogs.com/newwind/p/9936978.html
Copyright © 2020-2023  润新知