另一种校验同步报文的实现方式 其原理都是一样的 从校验配置文件中读取配置项
给校验类对象赋值 取对象中报文字段校验值与报文字段进行校验(字段类型、大小、正则式)
实现方法:应用启动的时候 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);
}
}