1 背景
由于安全检测需求,需要对参数进行校验,前端在传字段(不是参数值)时,在dto实体有不存在的参数就对其进行报错返回
2 定义注解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ParameterCheck {
//用于参数比较
Class dto() default Void.class;
}
//在需要校验接口上加上注解,并传入需要比较dto
@ParameterCheck(dto = ConstructionListDto.class)
@PostMapping({"/getConstructionList"})
public ResponseObject<IPage<NewTownConstructionListVo>> getConstructionList(@RequestBody ConstructionListDto dto) {
IPage<NewTownConstructionListVo> vo = newTownConstructionService.getConstructionList(dto);
return new ResponseObject().setData(vo);
}
3 HandlerInterceptor拦截参数
@Slf4j
@Component
public class LoginHandlerInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
Method method = ((HandlerMethod) handler).getMethod();
//判断接口是否加注解
if (method.isAnnotationPresent(ParameterCheck.class) && "POST".equals(request.getMethod())) {
ParameterCheck parameter = method.getAnnotation(ParameterCheck.class);
//获取body请求参数
String body = request.getReader().lines().collect(Collectors.joining(System.lineSeparator()));
try {
//接口合法字段
Object objectOldDto = JSON.parseObject(body, parameter.dto());
//接收前端传入字段
Object objectNewDto = JSON.parseObject(body, Object.class);
//校验是否有多余或者不存在参数参数(可根据自身需求进行改造)
Boolean aBoolean = ObjectUtils.compareFields(objectOldDto, objectNewDto);
if (!aBoolean) {
throw new CustomServiceException(500, "参数异常!!!");
}
} catch (Exception e) {
throw new CustomServiceException(500, "参数异常!!!");
}
}
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
}
public static Boolean compareFields(Object oldObject, Object newObject) {
boolean bool=true;
try {
Map<String,String> mapOld = JSON.parseObject(JSON.toJSONString(oldObject), Map.class);
Map<String,String> mapNew = JSON.parseObject(JSON.toJSONString(newObject), Map.class);
Set<String> stringOld = mapOld.keySet();
Set<String> stringNew = mapNew.keySet();
//已接收字段
for (String string : stringNew) {
//现有字段
Optional<String> first = stringOld.stream().filter(e -> e.equals(string)).findFirst();
if(first.isPresent()){
continue;
}
bool=false;
}
} catch (Exception e) {
e.printStackTrace();
}
return bool;
}
}
4 注意
由于request.getReader() 只能取一次,这边取过了,后续其他功能会受到影响报错,
所以需要对他进行重新赋值 参考这一篇文章
https://blog.csdn.net/liuhao0610/article/details/130368541