另一种校验同步报文的实现方式

来源:互联网 发布:光翼学园网络班好吗 编辑:程序博客网 时间:2024/05/09 13:48

另一种校验同步报文的实现方式 其原理都是一样的 从校验配置文件中读取配置项

给校验类对象赋值 取对象中报文字段校验值与报文字段进行校验(字段类型、大小、正则式)

实现方法:
应用启动的时候 web.xml中的
读取校验配置文件 用于同步报文 字段值校验
<listener>
        <listener-class>com.xxxxxx.miss.util.linstener.InitSerListener</listener-class>
</listener>
具体实现:
package com.xxxxxx.miss.util.linstener;

import java.io.File;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

import org.apache.commons.lang.builder.ReflectionToStringBuilder;
import org.apache.log4j.Logger;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import com.xxxxxx.dhm.aaa.commons.util.Utility;
import com.xxxxxx.miss.util.config.CheckField;
import com.xxxxxx.miss.util.config.CheckRulerConfig;
import com.xxxxxx.miss.util.config.FieldRuler;
import com.xxxxxx.miss.util.config.InterRulerConfig;
import com.xxxxxx.miss.util.config.JoinFiledRuler;
import com.xxxxxx.miss.util.config.SerFactory;

/**
 * service层的初始化listener
 * SerListener.java
 * <p>Copyright: <p>
 * <p>Company: xxxxxx</p>
 *  @author    
 *  @version   1.0
 */
public class InitSerListener implements ServletContextListener
{
    Logger logger = Logger.getLogger(InitSerListener.class);

    public void contextDestroyed(ServletContextEvent context)
    {
    }

    public void contextInitialized(ServletContextEvent context)
    {
        // 初始化参数校验配置
        this.initParaCheckConfig(context);
    }

    // 使用dom4j进行xml的解析
    @SuppressWarnings( { "unchecked", "unchecked" })
    private void initParaCheckConfig(ServletContextEvent context)
    {
        SAXReader saxReader = new SAXReader();
        //读取 web.xml的初始化值
        /**<context-param>                                      <context-param>
            <param-name>dhm-system-name</param-name>              <param-name>checkConfigFilePath</param-name>
            <param-value>portalMS</param-value>                   <param-value>conf/para_check_config.xml</param-value>
        </context-param>                                     </context-param> */
        String checkConfigPath = context.getServletContext().getInitParameter("checkConfigFilePath");
        String aaa_system_name = context.getServletContext().getInitParameter("dhm-system-name");
        //获取校验文件地址 D:\tomcat_portal\bin\portalMS\conf\para_check_config.xml
        String path = Utility.getConfigFullPath(checkConfigPath, aaa_system_name);
        try
        {   //读取para_check_config.xml文件内容
            //文档
            Document document = saxReader.read(new File(path));
            //文档根元素 (content = ArrayList<E>)
            Element root = document.getRootElement();
            //根元素内容
            Iterator iter = root.elementIterator();
            /**
             * public class CheckRulerConfig
            {
                public Map<String, InterRulerConfig> iRuleMap = new ConcurrentHashMap<String, InterRulerConfig>();
            
                public Map<String, InterRulerConfig> getIRuleMap()
                {
                    return iRuleMap;
                }
            }
            
            public class InterRulerConfig
            {
                public Map<String, FieldRuler> fRuleMap = new ConcurrentHashMap<String, FieldRuler>();
            
                public String ref = "";
                
             对于配置文件中的字段   
            public class FieldRuler
            {
                public String id;
                public String regex;
                public String need;
                public String type;
                public String maxLength;
                public JoinFiledRuler joinCheckFiled;
                
            public class JoinFiledRuler
            {
                public Map<String, CheckField> joinCheck;
                
            public class CheckField
            {
                private String refField;
                private String regex;
                private String maxLength;
                
                @Override
                public String toString()
                {
            
                    return ReflectionToStringBuilder.toString(this);
                }
                
            para_check_config.xml:    
             <?xml version="1.0" encoding="UTF-8"?>
                <ruleConfig>
                <!-- 栏目排序同步
                     Synchronize the sequence of columns -->
                    <interface id="interRuler.SyncColumnRankServiceImpl">
                        <field id="RankModList" regex="^\." type="list" need="yes" />
                        <field id="ColumnID" regex="^[0-9]{1,13}$" need="yes" />
                        <field id="Rank" regex="^[1-9][0-9]{0,12}$" need="yes" />
                    </interface>
                </ruleConfig>
           CheckRulerConfig -> InterRulerConfig -> FieldRuler ->JoinFiledRuler->CheckField   
             */
            CheckRulerConfig crc = new CheckRulerConfig();
            Map mc = crc.getIRuleMap();
            while (iter.hasNext())
            {   //获取一个配置项的值 <interface XXX> xxxx</interface> 之间的内容
                Element ie = (Element) iter.next();
                //用于遍历每个 <field  (interface 的子节点<field
                Iterator it = ie.elementIterator();
                InterRulerConfig irc = new InterRulerConfig();
               
                // 如果存在ref项就取出来
                if (ie.attributeValue("ref") != null)
                {
                    irc.setRef(ie.attributeValue("ref"));
                }
                //取出InterRulerConfig 的Map<String, FieldRuler> fRuleMap 给其赋值
                Map mi = irc.getFRuleMap();
                while (it.hasNext())
                {   //每个Field的值 如:<field id="ColumnID" regex="^[0-9]{1,13}$" need="yes" />
                    Element fe = (Element) it.next();
                    FieldRuler fr = new FieldRuler();
                    //给每个FieldRuler赋值
                    fr.setId(fe.attributeValue("id").toLowerCase());
                    fr.setRegex(fe.attributeValue("regex"));
                    fr.setNeed(fe.attributeValue("need"));
                    fr.setType(fe.attributeValue("type"));
                    fr.setMaxLength(fe.attributeValue("maxLength"));
                    
                    //遍历<field id="ColumnID" regex="^[0-9]{1,13}$" need="yes" /> 每个值给CheckField赋值
                    //<field 子节点 如果没有就不需要给CheckField赋值 直接跳过
                    Iterator it1 = fe.elementIterator();
                    while (it1.hasNext())
                    {
                        JoinFiledRuler joinRule = new JoinFiledRuler();
                        Map<String, CheckField> resultMap = new HashMap<String, CheckField>();
                        Element fe1 = (Element) it1.next();
                        buildJoinFiledFuler(fe1, resultMap);
                        joinRule.setJoinCheck(resultMap);
                        fr.setJoinCheckFiled(joinRule);
                    }
                    //FieldRuler 保存到 Map<String, FieldRuler> fRuleMap 中
                    mi.put(fr.getId().toLowerCase(), fr);
                    logger.debug(fr);

                }
                //给CheckRulerConfig的Map<String, InterRulerConfig> iRuleMap 赋值
                mc.put(ie.attributeValue("id"), irc);
            }
            //SerFactory成员赋值
            SerFactory.setCheckConfig(crc);
        }
        catch (Exception e)
        {
            logger.error("load check ruler file failed!", e);
        }

    }

    /**
     * 解析joinCheck元素下值
     * @param fe1
     * @return
     */
    @SuppressWarnings("unchecked")
    private static void buildJoinFiledFuler(Element fe1, Map<String, CheckField> resultMap)
    {

        Iterator it1 = fe1.elementIterator();
        while (it1.hasNext())
        {

            Element fe3 = (Element) it1.next();
            Iterator it2 = fe3.elementIterator();
            while (it2.hasNext())
            {
                CheckField checkField = new CheckField();
                Element fe4 = (Element) it2.next();
                checkField.setRefField(fe4.attributeValue("refField"));
                checkField.setRegex(fe4.attributeValue("regex"));
                checkField.setMaxLength(fe4.attributeValue("maxLength"));
                resultMap.put(fe3.attributeValue("value"), checkField);
            }
        }

    }

}

外部模块进入系统的时候 需要执行某方法执行 先进入serviceParaCheckInterceptor类

    <bean id="serviceParaCheckInterceptor"
        class="com.xxxxxx.miss.util.intercaptor.ServiceParaCheckInterceptor">
    </bean>
    
    <bean id="RegexAdvisor"
        class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
        <property name="advice"> <!--执行的类-->
            <ref local="serviceParaCheckInterceptor" />
        </property>
        <property name="patterns"> <!--匹配的方法-->
            <list>
                <value>com.xxxxxx.dhm.portalMS.sync.portalms.service.*\.execute</value>
                <value>com.xxxxxx.dhm.portalMS.sync.service.*\.execute</value>
                <value>com.xxxxxx.dhm.portalMS.sync.action.*\.execute</value>
                <value>com.xxxxxx.dhm.portalMS.sync.cms.*\.execute</value>
                <value>com.xxxxxx.dhm.portalMS.sync.sme.*\.execute</value>
            </list>
        </property>
    </bean>



package com.xxxxxx.miss.util.intercaptor;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.apache.log4j.Logger;

import com.xxxxxx.dhm.aaa.commons.constant.CommonConst;
import com.xxxxxx.dhm.aaa.commons.constant.SerErrorCommonCode;
import com.xxxxxx.dhm.aaa.commons.util.StringUtil;
import com.xxxxxx.miss.util.config.CheckField;
import com.xxxxxx.miss.util.config.CheckRulerConfig;
import com.xxxxxx.miss.util.config.FieldRuler;
import com.xxxxxx.miss.util.config.InterRulerConfig;
import com.xxxxxx.miss.util.config.JoinFiledRuler;
import com.xxxxxx.miss.util.config.SerFactory;
import com.xxxxxx.dhm.common.config.impl.PropertiesFactory;
import com.xxxxxx.dhm.common.uif.vo.IRequestMessageBody;
import com.xxxxxx.dhm.common.uif.vo.MessageBody;
import com.xxxxxx.dhm.common.uif.vo.ReturnMessage;
import com.xxxxxx.dhm.common.uif.vo.cms.CMSMessage;
import com.xxxxxx.dhm.common.uif.vo.cms.cms2iepg.body.IepgAssetRequestBody;

/**
 * 参数较验拦截器 ServiceParaCheckInterceptor.java
 * <p>
 * Copyright: Copyright (c) 2009
 * <p>
 * <p>
 * Company: xxxxxx
 * </p>
 *
 * @author
 * @version 1.0
 */
public class ServiceParaCheckInterceptor implements MethodInterceptor
{
    private final static Logger log = Logger.getLogger(ServiceParaCheckInterceptor.class);

    @SuppressWarnings("unchecked")
    public Object invoke(MethodInvocation invocation) throws Throwable
    {
        try
        {
            // 取出被拦截方法的参数集
            Object[] args = invocation.getArguments();
            Object o = null;
            if (args[0] instanceof IRequestMessageBody)
            {
                IRequestMessageBody dr = (IRequestMessageBody) args[0];
                // 取出要校验的对象
                o = dr.getReqMsg();
            }
            else if (args[0] instanceof MessageBody)
            {
                o = args[0];
            }
            
            
//            if (o == null && args[0] instanceof IepgAssetRequestBody)
//            {
//                IepgAssetRequestBody dr = (IepgAssetRequestBody) args[0];
//                o = dr.getResourcePackage();
//                if(o == null)
//                {
//                    o= dr.getPackageCode();
//                }
//                if(o == null)
//                {
//                    o= dr.getIepgAssetMessage();
//                }
//            }
            else
            {// 对象格式有误
                log.error(" object format error ");
                ReturnMessage rm = new ReturnMessage();
                rm.setReturnCode(SerErrorCommonCode.UNKNOWN_ERROR);
                return rm;
            }

            Class c = o.getClass();
            
            // 取出接口参数的字段集
            Field[] fa = c.getDeclaredFields();
            
            // 由接口ID取出此接口对应的InterRulerConfig对象
            CheckRulerConfig crc = SerFactory.getCheckConfig();
           
            // 取出接口规则Map
            Map<String, InterRulerConfig> iRuleMap = crc.getIRuleMap();
           
            // 取出被拦截的类名
            Class clazz = invocation.getThis().getClass();
            String rulerName = clazz.getSimpleName();
            String interID = CommonConst.INTER_RULER_PREFIX + rulerName;
           
            // 由接口ID取出接口的校验规则
            InterRulerConfig ir = iRuleMap.get(interID);

            // 如果此接口没有定义校验规则,则不对此接口进行校验
            if (ir == null)
            {
                return invocation.proceed();
            }
           
            // 如果此接口规则引用其他接口的规则进行校验,就取出引用的接口规则
            if (!ir.getRef().equals(""))
            {
                ir = iRuleMap.get(ir.getRef());
            }
           
            // 取出字段校验规则的map
            Map<String, FieldRuler> rulerMap = ir.getFRuleMap();
            for (int i = 0; i < fa.length; i++)
            {
                // 取校验规则
                FieldRuler fr = rulerMap.get(fa[i].getName().toLowerCase());
              
                // 如果此字段没有给出校验规则,则不对此字段进行校验
                if (fr == null)
                {
                    continue;
                }
                Method method = c.getMethod(getMethodName(fa[i].getName()), new Class[0]);
                Object fo = method.invoke(o, new Object[0]);// get方法无参\
               
                // 类里的属性是否为ArrayList类型
                if (fr.getType() != null && fr.getType().equals("list") && null != fo)
                {
                    List tempList = (ArrayList) fo;
                   
                    // 验证List下的元素属性
                    for (int temp = 0; temp < tempList.size(); temp++)
                    {
                        ReturnMessage validataResult = validataChildFiled(tempList.get(temp), rulerMap, o);
                      
                        // 验证失败
                        if (!SerErrorCommonCode.SUCCEED.equals(validataResult.getReturnCode()))
                        {
                            return validataResult;
                        }
                    }
                }
               
                // 验证属性
                ReturnMessage rm = checkField(fa[i].getName().toLowerCase(), rulerMap, fo, o);
                if (!SerErrorCommonCode.SUCCEED.equals(rm.getReturnCode()))
                {
                    return rm;
                }

            }

        }
        catch (Exception e)
        {
            log.error("parameter check failed!", e);
            ReturnMessage rm = new ReturnMessage();
            rm.setReturnCode(SerErrorCommonCode.PARA_CHECK_FAILED);
            rm.setErrorMessage(PropertiesFactory.getValueString(SerErrorCommonCode.PARA_CHECK_FAILED));
            return rm;
        }
        // 如果参数校验通过,则调用被拦截的方法
        return invocation.proceed();

    }

    /**
     * 根据校验规则对属性值进行检查
     *
     * @param lowerCaseValue
     * @param rulerMap
     * @param fo
     * @return
     * @throws NoSuchMethodException
     * @throws SecurityException
     * @throws InvocationTargetException
     * @throws IllegalAccessException
     * @throws IllegalArgumentException
     */
    private ReturnMessage checkField(String lowerCaseValue, Map<String, FieldRuler> rulerMap, Object fo, Object o)
            throws SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException,
            InvocationTargetException
    {
        ReturnMessage rm = new ReturnMessage();
        rm.setReturnCode(SerErrorCommonCode.SUCCEED);
        FieldRuler fr = rulerMap.get(lowerCaseValue);
        // 如果此字段没有给出校验规则,则不对此字段进行校验
        if (fr == null)
        {
            return rm;
        }
        // 如果要校验的字段值为空,而校验规则规定其是必选项,则返回校验失败
        if (fo == null || fo.toString().equals(""))
        {
            if (fr.getNeed().equalsIgnoreCase(CommonConst.YES))
            {

                rm.setReturnCode(SerErrorCommonCode.PARA_CHECK_FAILED);
                rm.setErrorMessage(PropertiesFactory.getValueString(SerErrorCommonCode.PARA_CHECK_FAILED)
                        + CommonConst.ERROR_DESC + fr.getId());
                return rm;
            }
            else
            {
                return rm;
            }

        }
        rm = null;
        return this.checkValidate(fr, fo, o);

    }

    /**
     * 迭代验证ArrayList元素属性
     *
     * @param object
     * @param rulerMap
     * @return
     * @throws SecurityException
     * @throws NoSuchMethodException
     * @throws IllegalArgumentException
     * @throws IllegalAccessException
     * @throws InvocationTargetException
     */
    @SuppressWarnings("unchecked")
    private ReturnMessage validataChildFiled(Object object, Map<String, FieldRuler> rulerMap, Object o)
            throws SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException,
            InvocationTargetException
    {
        ReturnMessage rm = new ReturnMessage();
        rm.setReturnCode(SerErrorCommonCode.SUCCEED);
        Object tempObj = object;
        Field[] fields = object.getClass().getDeclaredFields();
        for (int i = 0; i < fields.length; i++)
        {
            // 取校验规则
            FieldRuler fr = rulerMap.get(fields[i].getName().toLowerCase());
            // 如果此字段没有给出校验规则,则不对此字段进行校验
            if (fr == null)
            {
                continue;
            }
            Method method = object.getClass().getMethod(getMethodName(fields[i].getName()), new Class[0]);
            // 通过get方法,获取属性值
            Object fo = method.invoke(tempObj, new Object[0]);
            // 如果子元素属性是集合类型,则继续验证集合中的数据
            if (fr.getType() != null && fr.getType().equals("list") && null != fo)
            {
                List tempList = (ArrayList) fo;
                object = null;
                tempObj = null;
                // 递归进行验证
                for (int temp = 0; temp < tempList.size(); temp++)
                {
                    rm = null;
                    validataChildFiled(tempList.get(temp), rulerMap, tempObj);

                }

            }
            // 验证属性
            rm = checkField(fields[i].getName().toLowerCase(), rulerMap, fo, tempObj);
            if (!SerErrorCommonCode.SUCCEED.equals(rm.getReturnCode()))
            {
                return rm;
            }

        }

        return rm;

    }

    /**
     * 对特定字段的值进行校验
     *
     * @param fr
     * @param value
     * @return
     * @throws NoSuchMethodException
     * @throws SecurityException
     * @throws InvocationTargetException
     * @throws IllegalAccessException
     * @throws IllegalArgumentException
     */
    @SuppressWarnings("unchecked")
    private ReturnMessage checkValidate(FieldRuler fr, Object value, Object o) throws SecurityException,
            NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException
    {
        ReturnMessage rm = new ReturnMessage();

        if (fr.getType() != null && fr.getType().equals("list") && null != value)
        {
            List tempList = (ArrayList) value;
            if (tempList.isEmpty() && fr.getNeed().equals("yes"))
            {
                rm.setReturnCode(SerErrorCommonCode.PARA_CHECK_FAILED);
                rm.setErrorMessage(PropertiesFactory.getValueString(SerErrorCommonCode.PARA_CHECK_FAILED)
                        + " ,field name is :" + fr.getId());
            }
            else
            {
                rm.setReturnCode(SerErrorCommonCode.SUCCEED);
            }
            return rm;
        }
        Pattern p = Pattern.compile(fr.getRegex());
        Matcher m = p.matcher(value.toString());
        // 规则校验 长度校验
        if (!m.matches() || !validateDBAllowMaxLength(fr.getMaxLength(), value.toString()))
        {
            rm.setReturnCode(SerErrorCommonCode.PARA_CHECK_FAILED);
            rm.setErrorMessage(PropertiesFactory.getValueString(SerErrorCommonCode.PARA_CHECK_FAILED)
                    + " ,filed name is :" + fr.getId());
            return rm;

        }
        return validataJoinFiledRuler(rm, fr, value, o);
    }

    /**
     *  级联校验
     *  举例说明:
     *  <field id="ProdOfferingCode" regex="^\w{1,20}$" need="yes">
     *  <joinCheck>
     *    <attribute  value="1" >
     *         <checkFile refField="region"  regex="^\w{1,20}$"/>
     *    </attribute>    
     *  </joinCheck>    
     *          当ProdOfferingCode的值为1时,    region的值必须满足regex 的校验规则
     *        
     * @param rm
     * @param fr
     * @param value
     * @param o
     * @throws SecurityException
     * @throws NoSuchMethodException
     * @throws IllegalArgumentException
     * @throws IllegalAccessException
     * @throws InvocationTargetException
     */
    @SuppressWarnings("unchecked")
    private ReturnMessage validataJoinFiledRuler(ReturnMessage rm, FieldRuler fr, Object value, Object o)
            throws SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException,
            InvocationTargetException
    {
        // 默认返回成功
        rm.setReturnCode(SerErrorCommonCode.SUCCEED);
        // 级联校验(基于本属性对其他属性进行校验)
        if (fr.getJoinCheckFiled() == null)
        {

            return rm;
        }
        Map<String, CheckField> checkMAp = fr.getJoinCheckFiled().getJoinCheck();
        if (checkMAp == null || !checkMAp.containsKey(value))
        {
            return rm;
        }
        JoinFiledRuler joinFiledRuler = fr.getJoinCheckFiled();
        Map<String, CheckField> map = joinFiledRuler.getJoinCheck();
        CheckField checkField = map.get(value);
        Class c = o.getClass();
        Method method = c.getMethod(getMethodName(checkField.getRefField()), new Class[0]);
        Object fo = method.invoke(o, new Object[0]);// get方法无参\
        String checkStr = "";
        if (fo != null)
        {
            checkStr =fo.toString();
        }
        Pattern p = Pattern.compile(checkField.getRegex());
        Matcher m = p.matcher(checkStr);
        // 规则校验 长度校验
        if (!m.matches() || !validateDBAllowMaxLength(checkField.getMaxLength(), checkStr))
        {
            rm.setReturnCode(SerErrorCommonCode.PARA_CHECK_FAILED);
            rm.setErrorMessage(PropertiesFactory.getValueString(SerErrorCommonCode.PARA_CHECK_FAILED)
                    + " ,filed name is :" + checkField.getRefField());

        }
        return rm;

    }

    /**
     * 验证DB允许的长度值
     *
     * @param length
     * @param value
     * @return
     */
    private boolean validateDBAllowMaxLength(String length, String value)
    {
        // length为null,则不需要验证
        if (null == length)
        {
            return true;
        }
        // 值的长度大于DB允许的长度时
        if (Integer.parseInt(length) < StringUtil.getLengthInOracle(value))
        {
            return false;
        }
        return true;
    }

    public static String getMethodName(String name)
    {
        return "get" + firstLetterToUpperCase(name);
    }

    /**
     * 首字母小写变大写
     */
    public static String firstLetterToUpperCase(String name)
    {
        if (name == null || name.length() == 0)
        {
            return name;
        }
        char[] chars = name.toCharArray();
        chars[0] = Character.toUpperCase(chars[0]);
        return new String(chars);
    }

}



0 0
原创粉丝点击