All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.needcoke.coke.web.http.RequestMappingHandler Maven / Gradle / Ivy

package org.needcoke.coke.web.http;

import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.Accessors;
import lombok.extern.slf4j.Slf4j;
import org.needcoke.coke.web.annotation.RequestBody;
import org.needcoke.coke.web.annotation.RequestParam;
import org.needcoke.coke.web.bean.RequestParamItem;
import org.needcoke.coke.web.util.ParameterUtil;
import pers.warren.ioc.core.ApplicationContext;
import pers.warren.ioc.util.ReflectUtil;

/**
 * @author warren
 * @date 2022/4/2
 */
@EqualsAndHashCode(callSuper = true)
@Accessors(chain = true)
@Slf4j
public class RequestMappingHandler extends AbstractHandler {

    private RequestParamItem[] paramItemArr;

    @Setter
    @Getter
    private String invokeBeanName;

    @Getter
    private Method invokeMethod;

    @Setter
    @Getter
    private HttpType httpType;

    private String bodyName;

    private Class bodyClz;

    private Class[] innerTypes;


    private int bodyIndex = -1;

    @Setter
    @Getter
    private HttpContext ctx;

    @Override
    public void handle(HttpContext ctx, ApplicationContext applicationContext) throws Throwable {
        this.ctx = ctx;
        Object[] parameters = getParameters(ctx);
        Object result = invokeMethod.invoke(getBean(applicationContext), parameters);
        ctx.writeJson(result);
    }


    private Object[] getParams(Class[] parameterTypes, String[] parameterNames, Map paramMap) {
        Object[] parameters = new Object[parameterNames.length];
        for (int i = 0; i < parameterNames.length; i++) {
            String[] parameterArr = paramMap.get(parameterNames[i]);
            if (null != parameterArr && parameterArr.length > 0) {
                String param = parameterArr[0];
                Class parameterType = parameterTypes[i];
                Object dstValue = ParameterUtil.getDstValue(param, parameterType);
                parameters[i] = dstValue;
            }
        }
        if (null != paramItemArr && paramItemArr.length > 0) {

            for (int i = 0; i < paramItemArr.length; i++) {
                if (null == paramItemArr[i]) {
                    continue;
                }
                int paramIndex = paramItemArr[i].getParamIndex();
                if (-1 == paramIndex) continue;
                if (parameters[paramIndex] == null) {
                    parameters[paramIndex] = paramItemArr[i].getDefaultValue();
                    if (paramItemArr[i].isRequired() && parameters[paramIndex] == null) {
                        throw new RuntimeException("bean " + invokeBeanName + " 's method " + invokeMethod.getName() + " 's parameter " + paramItemArr[i].getName() + " must have !");
                    }
                }
            }
        }
        if (-1 != bodyIndex && null == parameters[bodyIndex]) {
            String body = "";
            try {
                body = ctx.body();
                parameters[bodyIndex] = JSONUtil.toBean(body, bodyClz);
            } catch (Exception e) {
                try {
                    if (bodyClz.isAssignableFrom(List.class)) {
                        System.out.println(body);
                    }
                    parameters[bodyIndex] = JSONUtil.toList(body, Object.class);
                } catch (Exception a) {
                    throw new RuntimeException("body parse error bean " + invokeBeanName + " 's method " + invokeMethod.getName() + " 's parameter " + bodyName, a);

                }
            }
        }
        return parameters;
    }

    protected String[] getParameterNames(Method method) {
        String[] parameterNames = ReflectUtil.getParameterNames(method);
        Parameter[] parameters = method.getParameters();
        for (int i = 0; i < parameters.length; i++) {
            RequestParam requestParam = parameters[i].getAnnotation(RequestParam.class);
            if (null != requestParam && StrUtil.isNotEmpty(requestParam.value())) {
                parameterNames[i] = requestParam.value();
            }
        }
        return parameterNames;
    }

    public Object getBean(ApplicationContext applicationContext) {
        return applicationContext.getBean(invokeBeanName);
    }

    public Object[] getParameters(HttpContext ctx) {
        Class[] parameterTypes = invokeMethod.getParameterTypes();
        String[] parameterNames = getParameterNames(invokeMethod);
        Map paramMap = ctx.getParamMap();
        return getParams(parameterTypes, parameterNames, paramMap);
    }

    public RequestMappingHandler setInvokeMethod(Method invokeMethod) {
        this.invokeMethod = invokeMethod;
        initRequestParamItemArr(invokeMethod);
        initBodyField(invokeMethod);
        return this;
    }

    protected void initBodyField(Method method) {
        Parameter[] parameters = method.getParameters();
        String[] parameterNames = ReflectUtil.getParameterNames(method);
        for (int i = 0; i < parameters.length; i++) {
            if (null != parameters[i].getAnnotation(RequestBody.class)) {
                bodyClz = parameters[i].getType();
                bodyName = parameterNames[i];
                bodyIndex = i;
            }
        }
    }

    protected void initRequestParamItemArr(Method method) {
        Parameter[] parameters = method.getParameters();
        List requestParamList = Arrays.stream(parameters)
                .filter(p -> null == p.getAnnotation(RequestBody.class)
                ).collect(Collectors.toList());
        String[] parameterNames = ReflectUtil.getParameterNames(method);
        Map mp = new HashMap<>();
        for (int i = 0; i < parameterNames.length; i++) {
            mp.put(parameters[i], parameterNames[i]);
        }
        this.paramItemArr = new RequestParamItem[requestParamList.size()];
        for (int i = 0; i < requestParamList.size(); i++) {
            Parameter parameter = requestParamList.get(i);
            RequestParam annotation = parameter.getAnnotation(RequestParam.class);
//            if (null == annotation) return;
            this.paramItemArr[i] = new RequestParamItem()
                    .setParamIndex(i)
                    .setName(mp.get(parameter))
                    .setRequestParamName(null == annotation ? null : annotation.value())
                    .setRequired(null != annotation && annotation.required())
                    .setRequestParam(null != annotation)
                    .setDefaultValue(null == annotation || StrUtil.isEmpty(annotation.defaultValue()) ? null : ParameterUtil.getDstValue(annotation.defaultValue(), parameter.getType()));
        }
    }


}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy