自定义任意的ParaGetter

由于项目里有很多json形式的参数,jfinal形参注入并不支持json请求体。想扩展下,发现不修改源代码怎么写都很丑。所以修改了一些源代码

//Para注解增加 自定义paraGetter
public @interface Para {

    /**
     * 不能使用空字符串:
     * 1: 对于 value() 早已用于无 modelName 前缀的场景:action(@Para("")User user)
     * 2: 对于 defaultValue() 可用于指定默认值为空字符串:action(@Para(defaultValue = "")String email)
     */
    String NULL_VALUE = "-NULL VALUE-";

    /**
     * 对应到 HTTP 参数里的参数名称
     */
    String value() default NULL_VALUE;

    /**
     * 默认值
     */
    String defaultValue() default NULL_VALUE;

    /**
     * 可以自定义 paraGetter
     */
   Class<? extends CustomParaGetter> paraGetter() default CustomParaGetter.NullGetter.class;
}
//修改 ParaProcessorBuilder.createParaGetter方法
     if (para != null) {
         // 支持 @Para 注解仅指定 defaultValue 值的用法
         if (!Para.NULL_VALUE.equals(para.value())) {
             parameterName = para.value().trim();
         }

    /*
    defaultValue = para.defaultValue().trim();
    if (defaultValue.isEmpty()) {
       defaultValue = null;
    }*/
             // 空字符串 "" 可以成为默认值,空白字符串与前后有空白字符的文本也可以成为默认值: "  "、" ABC "
         if (!Para.NULL_VALUE.equals(para.defaultValue())) {
             defaultValue = para.defaultValue();
         }
            
         //这一段是我新增的   
         Class<? extends ParaGetter> paraGetter = para.paraGetter();
         if (paraGetter != CustomParaGetter.NullGetter.class) {
             try {
                 Constructor<? extends ParaGetter> constructor = paraGetter.getConstructor(Class.class, String.class, String.class);
                 return constructor.newInstance(typeClass, parameterName, defaultValue);
             } catch (Exception e) {
                 throw new RuntimeException(e.getMessage(), e);
             }
         }
     }
//如果要自定义 ParaGetter 继承这个类
public abstract class CustomParaGetter<T> extends ParaGetter<T> {

    private final Class<T> type;

    public CustomParaGetter(Class<T> type, String parameterName, String defaultValue) {
        super(parameterName, defaultValue);
        this.type = type;
    }


    protected Class<T> getType() {
        return type;
    }


    public static class NullGetter extends CustomParaGetter {

        public NullGetter(Class type, String parameterName, String defaultValue) {
            super(type, parameterName, defaultValue);
        }

        @Override
        protected Object to(String v) {
            return null;
        }

        @Override
        public Object get(Action action, Controller c) {
            return null;
        }
    }
}


如果要自定义 ParaGetter ,需要继承 CustomParaGetter添加自己的实现

//json 
public class JsonParaGetter extends CustomParaGetter {

    public JsonParaGetter(Class type, String parameterName, String defaultValue) {
        super(type, parameterName, defaultValue);
    }


    @Override
    protected Object to(String v) {
        return null;
    }

    @Override
    public Object get(Action action, Controller c) {
        return JsonKit.parse(c.getRawData(), this.getType());
    }
}


最后形参注入时指定 ParaGetter即可

public void index(@Para(paraGetter = JsonParaGetter.class) TestJsonBean user) {
    System.out.println(user);
    renderNull();
}


可以愉快的自定义 ParaGetter 了

评论区

糊搞

2020-08-14 18:02

@Para上能加上checker[]就更好了,什么RequiredChecker、IntChecker、StrChecker、EMailChecker等就能在参数上加上校验了(CheckerFactory ^_^),,,关联参数使用RelativeChecker,复杂的关联检查就由开发人员自定义了。。。

lxhxka

2020-08-14 18:41

@糊搞 参数校验我觉得用Validator也够了

JFinal

2020-08-14 21:30

思路不错,赞一个

热门分享

扫码入社