一、后端输入校验
有输入框就有校验,有些校验利用validation-pai.jar的注解就能实现校验,但是有些个性化校验或是拦截自定义非法字符就需要用到自定义注解,不使用注解时,单独校验费时费力,重复代码多,自定义注解能够很好的解决这个办法。
自定义注解类:
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import javax.validation.Constraint;
import javax.validation.Payload;
@Constraint(validatedBy = IllegalCharacterValidator.class) //具体的实现
@Target( { java.lang.annotation.ElementType.METHOD,
java.lang.annotation.ElementType.FIELD })
@Retention(java.lang.annotation.RetentionPolicy.RUNTIME)
@Documented
public @interface IllegalCharacter {
String message() default "输入内容含有非法字符"; //提示信息,可以写死,可以填写国际化的key
String regexp() default "[`~!@#$%^&*+=|{}':;',\\[\\].<>/?~!@#¥%……&*——+|{}【】‘;:”“’。,、?]";
//下面这两个属性必须添加
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
注解类的具体实现:
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class IllegalCharacterValidator implements ConstraintValidator<IllegalCharacter, String> {
private String rege;
/**
* 初始参数,获取注解中length的值
*/
@Override
public void initialize(IllegalCharacter arg0) {
this.rege = arg0.regexp();
}
@Override
public boolean isValid(String str, ConstraintValidatorContext constraintValidatorContext) {
if(str != null){
Pattern pattern = Pattern.compile(rege);
Matcher matcher = pattern.matcher(str);
return !matcher.find();
}else{
return true;
}
// constraintValidatorContext.disableDefaultConstraintViolation();//禁用默认的message的值
// //重新添加错误提示语句
// constraintValidatorContext
// .buildConstraintViolationWithTemplate("字符串不能为空").addConstraintViolation();
// }
// return false;
}
}
具体用法:
//给pojo类的字段加上注解
@IllegalCharacter(message="提示信息",regexp="正则表达式")
private String schoolid;
//给controller类的方法加上注解@Valid
@ResponseBody
@RequestMapping(value="/insertschool",method=RequestMethod.POST)
public String insertschool(@RequestBody @Valid School school, BindingResult result) {
//验证from表单
if (result.hasErrors()){
List<ObjectError> errorList = result.getAllErrors();
for(ObjectError error : errorList){
(error.getDefaultMessage());
return new Response().failure(error.getDefaultMessage());
}
}
/***具体业务***/
return "";
}
二、自定义注解实现权限校验
自定义多个注解实现多角色校验,给每个controller的方法加上权限类注解,根据不同角色能访问不同方法来控制改方法是否需要权限验证,需要权限验证的再判断需要怎样的权限验证。
自定义权限注解类:
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/*
*Target指定注解的目标为方法级
*Retention指定注解可以在运行时被获取(利用反射)
*自定义注解实现AOP拦截验证是否具有管理员权限
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Role {
public abstract URole[] value() default URole.schooladmin;
public enum URole {
superadmin, bankadmin, schooladmin;
}
}
在controller方法上的用法:
//给controller类的方法加上注解@Valid
//给controller类的方法加上权限注解@Role表示此方法只有school权限的人才能访问
@Role(value={URole.schooladmin})
@ResponseBody
@RequestMapping(value="/insertschool",method=RequestMethod.POST)
public String insertschool(@RequestBody @Valid School school, BindingResult result) {
//验证from表单
if (result.hasErrors()){
List<ObjectError> errorList = result.getAllErrors();
for(ObjectError error : errorList){
(error.getDefaultMessage());
return new Response().failure(error.getDefaultMessage());
}
}
//具体业务
return "";
}
AOP切面设计权限实现:
import java.lang.reflect.Method;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.apache.log4j.Logger;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
//由于项目已投产,部分代码不能公布
@Aspect
@Component
public class SecurityAspect {
private Logger logger= Logger.getLogger(SecurityAspect.class);
public Object execute(ProceedingJoinPoint pjp) throws Throwable {
// 从切点上获取目标方法
MethodSignature methodSignature = (MethodSignature) pjp.getSignature();
Method method = methodSignature.getMethod();
boolean rtype = methodSignature.getReturnType().getName().equals("java.lang.String");
// 若目标方法忽略了安全性检查@UnSessionCheck,则直接调用目标方法
if (method.isAnnotationPresent(UnSessionCheck.class)) {
return pjp.proceed();
}
("校验是否登录");
// 调用目标方法
return pjp.proceed();
}
}