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

关于在后台实现前台表单的格式验证:
因为对于一个web工程来说,安全是比较重要的,view中实现的js验证,对于一个hacker或者说是一个专业的破坏者来说是不会起到任何作用的,最直接的,它可以完全的自编浏览器,跳过js的验证,丢入n多不合规则的数据,那带来的安全隐患时巨大的,如何在后台实现完美的验证,而不必要写太多的代码是极其重要的。
1.思路结构图
关于在后台实现前台表单的格式验证设计(Annotation+spring AOP)_第1张图片
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)
@Documented
public @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("\\(")[1].split("\\)")[0];
    	
    	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()[0].toString();
    	Class pointCutClass = Class.forName(className);
    	Class[] parameterTypes = new Class[1];
    	
    	parameterTypes[0] = 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 block
			e.printStackTrace();
		}
        Method[] methods = test.getMethods();
        Set<Method> set = new HashSet<Method>(); 
        for(int i=0;i<methods.length;i++) 
        { 
        	boolean otherFlag = methods[i].isAnnotationPresent(AnotationTest.class); 
        	if(otherFlag) set.add(methods[i]); 
      	} 
      	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.
false
Exception in thread "main" java.lang.reflect.UndeclaredThrowableException
	at com.test.main.EntityTestTwo$$EnhancerByCGLIB$$20bb68d6.setTel(<generated>)
	at com.test.main.Boot.main(Boot.java:32)
Caused by: com.test.main.RegExpException
	at 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测试源码和测试结果。

你可能感兴趣的:(java,spring,AOP,Web,Ajax)