ligb2006 发表于 2013-1-23 02:23:45

关于在后台实现前台表单的格式验证设计(Annotation+spring AOP)

关于在后台实现前台表单的格式验证:
因为对于一个web工程来说,安全是比较重要的,view中实现的js验证,对于一个hacker或者说是一个专业的破坏者来说是不会起到任何作用的,最直接的,它可以完全的自编浏览器,跳过js的验证,丢入n多不合规则的数据,那带来的安全隐患时巨大的,如何在后台实现完美的验证,而不必要写太多的代码是极其重要的。
1.思路结构图
http://dl.iteye.com/upload/attachment/171249/80c7b693-2d7b-3a66-92f6-d3c05416c1ff.gif
2.源码实现
Annotation
package com.test.main;import java.lang.annotation.Documented;import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;@Target(ElementType.METHOD)@Retention(RetentionPolicy.RUNTIME)@Documentedpublic @interface AnotationTest {String regExp();String ifTip();}
TestEntity
package com.test.main;import java.util.Date;public class EntityTestTwo {private int sex;private String tel;private Date beginDate;public String getTel() {return tel;}@AnotationTest(regExp="^\\d{11}$",ifTip="手机号码填写错误")public void setTel(String tel) {this.tel = tel;}public Date getBeginDate() {return beginDate;}//@AnotationTest(regExp="^\\d\\d\\d\\d-\\d\\d-\\d\\d$",ifTip="日期填写错误")public void setBeginDate(Date beginDate) {this.beginDate = beginDate;}public int getSex() {return sex;}@AnotationTest(regExp="^.$",ifTip="性别填写错误")public void setSex(int sex) {this.sex = sex;}}
RegExpException
package com.test.main;public class RegExpException extends Exception{public RegExpException(String exceptionDesc){System.out.println(exceptionDesc);}}
SimpleAspect
package com.test.main;          import java.io.IOException;import java.lang.reflect.Method;import java.util.HashMap;import java.util.Map;import java.util.regex.Pattern;import org.aspectj.lang.JoinPoint;import org.aspectj.lang.annotation.AfterReturning;import org.aspectj.lang.annotation.Aspect;import org.aspectj.lang.annotation.Before;import org.aspectj.lang.annotation.Pointcut;   @Aspect   public class SimpleAspect {            @Pointcut("execution(* com.test.main.*.set*(..))")         public void simplePointcut() {}                  @AfterReturning(pointcut="simplePointcut()")         public void simpleAdvice() {             //System.out.println("注入执行");         }         @Before(value="simplePointcut()")    public void puAdvise(JoinPoint joinPoint) throws Exception, IOException{    //      //String className="com.test.main.EntityTest";    //根据request的请求参数,此时应该全部产生    //ServletActionContext.getRequest().getParameterNames();    String className = joinPoint.getSignature().getDeclaringType().getName();    String methodName = joinPoint.getSignature().getName();    String argType = (joinPoint.getSignature().toLongString()).split("\\(").split("\\)");      Map<String,String> org_obj = new HashMap<String,String>();    org_obj.put("int", "java.lang.Integer");    org_obj.put("double", "java.lang.Double");    org_obj.put("float", "java.lang.Float");    org_obj.put("boolean", "java.lang.Boolean");    org_obj.put("char", "java.lang.Character");    org_obj.put("byte", "java.lang.Byte");    org_obj.put("short", "java.lang.Short");    org_obj.put("long", "java.lang.Long");      if(org_obj.containsKey(argType)){    argType = org_obj.get(argType);    }    String propertyValue = joinPoint.getArgs().toString();    Class pointCutClass = Class.forName(className);    Class[] parameterTypes = new Class;      parameterTypes = Class.forName(argType);    Method method=null;    try{    method = pointCutClass.getMethod(methodName,parameterTypes);    }catch(NoSuchMethodException e){    Method[] methods = pointCutClass.getMethods();    for(Method m : methods)    if(m.getName().equals(methodName))    //for(Class c : m.getParameterTypes())    method = m;    }      boolean otherFlag = method.isAnnotationPresent(AnotationTest.class);         //if(otherFlag) set.add(method);         if(otherFlag){      AnotationTest anotationTest = method.getAnnotation(AnotationTest.class);      //传过来的参数值      String regExp = anotationTest.regExp();      String ifTip = anotationTest.ifTip();      boolean bl = Pattern.matches(regExp,propertyValue);      System.out.println(bl);      if(!bl){      //PrintWriter out =         System.out.println(ifTip);      throw new RegExpException("正则匹配抛出异常");      }      }    }}
Test
package com.test.main;          import java.net.URL;import org.slf4j.ILoggerFactory;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;import org.springframework.core.io.ClassPathResource;import ch.qos.logback.classic.LoggerContext;import ch.qos.logback.classic.joran.JoranConfigurator;   public final class Boot {         /**   * @param args   * @throws Exception   */    public static void main(String[] args) throws Exception{         Logger logger = LoggerFactory.getLogger(Boot.class);    //从web.xml读配置      ApplicationContext ctx = new ClassPathXmlApplicationContext("config/applicationContext.xml");            // A a = (A) ctx.getBean("a");            // a.sayHello();             EntityTestTwo a = (EntityTestTwo)ctx.getBean("entityTwo");         //SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-ss");      //a.setBeginDate(new Date());       // a.setSex(222);      a.setTel("1111111111");               //logger.      //String path = System.getProperty("user.dir");      //BasicConfigurator.configure();       // PropertyConfigurator.configure(new ClassPathResource("config/logback.properties").getURL());      // System.out.println(new ClassPathResource("config/logback.properties").getURL());      String logbackCfg = "config/logback.xml";         URL logURL = new ClassPathResource(logbackCfg).getURL();         System.out.println(logURL);      ILoggerFactory loggerFactory = LoggerFactory.getILoggerFactory();         LoggerContext loggerContext = (LoggerContext) loggerFactory;         //loggerContext.reset();         JoranConfigurator configurator = new JoranConfigurator();         configurator.setContext(loggerContext);         configurator.doConfigure(logURL);      logger.debug("dddd");      logger.info("wowowow");      logger.error("yanzhengosss");       // PropertyConfigurator.configure("/config/log4j.properties");               //B b = (B) ctx.getBean("b");             //b.sayHi();                  //      /*String className="com.test.main.EntityTest";      Class test = null;try {test = Class.forName(className);} catch (ClassNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();}      Method[] methods = test.getMethods();      Set<Method> set = new HashSet<Method>();         for(int i=0;i<methods.length;i++)         {         boolean otherFlag = methods.isAnnotationPresent(AnotationTest.class);         if(otherFlag) set.add(methods);       }       for(Method m: set)       {       AnotationTest anotationTest = m.getAnnotation(AnotationTest.class);       System.out.println(anotationTest.regExp());       System.out.println("创建的社区:"+anotationTest.ifTip());      }*/    }          }
执行结果
log4j:WARN No appenders could be found for logger (org.springframework.context.support.ClassPathXmlApplicationContext).log4j:WARN Please initialize the log4j system properly.falseException in thread "main" java.lang.reflect.UndeclaredThrowableExceptionat com.test.main.EntityTestTwo$$EnhancerByCGLIB$$20bb68d6.setTel(<generated>)at com.test.main.Boot.main(Boot.java:32)Caused by: com.test.main.RegExpExceptionat com.test.main.SimpleAspect.puAdvise(SimpleAspect.java:76)at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)at java.lang.reflect.Method.invoke(Unknown Source)手机号码填写错误正则匹配抛出异常at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:627)at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:609)at org.springframework.aop.aspectj.AspectJMethodBeforeAdvice.before(AspectJMethodBeforeAdvice.java:39)at org.springframework.aop.framework.adapter.MethodBeforeAdviceInterceptor.invoke(MethodBeforeAdviceInterceptor.java:49)at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)at org.springframework.aop.framework.adapter.AfterReturningAdviceInterceptor.invoke(AfterReturningAdviceInterceptor.java:50)at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:89)at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:635)... 2 more

由于程序原本设计是基于web工程,所以因为在web工程遭遇500 ERROR时会异常退出,所以在程序中借助PrintWriter对象进行错误输出,当然要用到ajax,在错误输出时页面不会跳转,否则正常执行;注意由于没想到什么好的办法来终止程序执行,这里用抛出异常来处理,因为测试环境为普通的java工程,所以能否在web工程中如理想的运行,暂未作测试,之后会贴入web测试源码和测试结果。
页: [1]
查看完整版本: 关于在后台实现前台表单的格式验证设计(Annotation+spring AOP)