自定义getBean方法

解决接口参数命名规则为下划线,getBean无法获取值(只能获取首字母小写的驼峰)。

import com.jfinal.core.Injector;
import com.jfinal.core.converter.TypeConverter;
import com.jfinal.kit.StrKit;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Map;

public class InjectorHelper {
    private static <T> T createInstance(Class<T> objClass) {
        try {
            return objClass.newInstance();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public static <T> T getBean(Class<T> beanClass, HttpServletRequest request) {
        return (T) Injector.injectBean(beanClass, request, false);
    }

    public static <T> T getBean(Class<T> beanClass, HttpServletRequest request, boolean skipConvertError) {
        return (T) InjectorHelper.injectBean(beanClass, "", request, skipConvertError);
    }

    public static <T> T getBean(Class<T> beanClass, String beanName, HttpServletRequest request) {
        return (T) InjectorHelper.injectBean(beanClass, beanName, request, false);
    }

    public static <T> T getBean(Class<T> beanClass, String beanName, HttpServletRequest request, boolean skipConvertError) {
        return (T) InjectorHelper.injectBean(beanClass, beanName, request, skipConvertError);
    }

    public static final <T> T injectBean(Class<T> beanClass, String beanName, HttpServletRequest request, boolean skipConvertError) {
        Object bean = createInstance(beanClass);
        String modelNameAndDot = StrKit.notBlank(beanName) ? beanName + "." : null;
        TypeConverter converter = TypeConverter.me();
        Map<String, String[]> parasMap = request.getParameterMap();
        Method[] methods = beanClass.getMethods();
        for (Method method : methods) {
            String methodName = method.getName();
            if (methodName.startsWith("set") == false || methodName.length() <= 3) {    // only setter method
                continue;
            }
            Class<?>[] types = method.getParameterTypes();
            if (types.length != 1) {                        // only one parameter
                continue;
            }

            String attrName = convert(methodName.substring(3));
            String paraName = modelNameAndDot != null ? modelNameAndDot + attrName : attrName;
            if (parasMap.containsKey(paraName)) {
                try {
                    String paraValue = request.getParameter(paraName);
                    Object value = paraValue != null ? converter.convert(types[0], paraValue) : null;
                    method.invoke(bean, value);
                } catch (Exception e) {
                    if (skipConvertError == false) {
                        throw new RuntimeException(e);
                    }
                }
            }
        }

        return (T) bean;
    }

    private static boolean toUpperCase = false;
    public static String convert(String key) {
        if (key instanceof String) {
            String property = null;
            String alias = null;
            if (((String) key).indexOf(".") > -1) {
                String[] properties = ((String) key).split("\\\\.");
                alias = properties[0];
                property = properties[1];
            } else {
                property = ((String) key);
            }
            StringBuilder buf = new StringBuilder(property);
            for (int i = 1; i < buf.length() - 1; i++) {
                if (Character.isLowerCase(buf.charAt(i - 1)) && Character.isUpperCase(buf.charAt(i))
                        && Character.isLowerCase(buf.charAt(i + 1))) {
                    buf.insert(i++, '_');
                }
            }
            return (alias != null ? alias + "." : "")
                    + (toUpperCase ? buf.toString().toUpperCase() : buf.toString().toLowerCase());
        }
        return key;
    }
}


评论区

JFinal

2019-05-08 15:57

在使用的时候是不是引入一个 BaseController extends Controller,在 BaseController 中覆盖掉 getBean 方法?

dubingxin

2019-05-08 16:01

@JFinal 也是可以的,提供一个思路,更希望官方提供更好的解决方案,毕竟大多接口参数都是用下划线。

热门分享

扫码入社