以前controller传参喜欢使用map,觉得不用定义对象、能随便添加参数很方便,后来觉得这些方便会造成其他方面的不方便。。。
1、会导致参数不明确,自己当时用起来没问题,过段时间想知道都传了什么参数就要翻代码了。
2、会导致很多调试工具不好用。如RestfulToolkit。原因如上,你不知道都有什么参数。
3、会使很多工作更复杂,比如参数验证。
如果使用map,你需要if if if if。。。
if(xxx == xxx){
return "xxx";
}
而要是使用对象传参,则只需在类属性上加注解就行,如:
@NotNull(message = "传入的姓名为null,请传值")
@NotEmpty(message ="传入的姓名为空字符串,请传值")
@Length(min =11, max =11, message ="传入的姓名长度有误,必须为3位")
private String name;
还能自己定义注解用:
//定义注解
@Documented
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Mapping
public @interface Class1 {
ControllerMethodEnum type();
}
//定义切面
@Aspect
@Component
public class AspectClass {
//切入点
@Pointcut("@annotation(定义的注解包路径)")
public void pointCut() {
}
@Around("pointCut()")
public Object around(ProceedingJoinPoint pjp) throws Throwable {
//获取 @Class1 注解的方法的参数列表(如果要用map传参,可以将校验的参数在此处取出来放在切面类中校验,避免代码杂乱)
Object[] args = pjp.getArgs();
//获取 @Class1 注解的对象信息
Signature signature = pjp.getSignature();
//获取 @Class1 注解的方法
Method targetMethod = ((MethodSignature) signature).getMethod();
//获取 @Class1 注解信息
Class1 class1 = targetMethod.getAnnotation(Class1.class);
// 获取@Class1 注解的type参数值
ControllerMethodEnum value = class1.type();
switch (value) {
case 使用注解定义的type值1:
//处理逻辑
@TODO
......
break;
case 使用注解定义的type值2:
//处理逻辑
@TODO
......
break;
}
}
}
//使用
@Class1 (type = "xx")
public xxx xxx;
同时在controller参数中加 @Valid 开启验证。
要是嫌弃注解验证返回参数太过复杂,还可以自己定义一个异常类:
@ControllerAdvice
@ResponseBody
public class GlobalExceptionInterceptor{
@ExceptionHandler(value =Exception.class)
public String exceptionHandler(HttpServletRequest request,Exception e){
String failMsg = null;
if(e instanceof MethodArgumentNotValidException){
// 拿到参数校验具体异常信息提示
failMsg = ((MethodArgumentNotValidException) e).getBindingResult().getFieldError().getDefaultMessage();
}
return failMsg;
}
}
所以,传map方便扩展,前期省事,后期维护、写文档麻烦。传对象前期定义对象、扩展麻烦。为了接口文档、参数校验好写一点,还是选择前期多做点工作,传对象吧。