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

cc.shacocloud.mirage.restful.bind.support.QueryParamsAndFormAttributesMethodArgumentResolver Maven / Gradle / Ivy

package cc.shacocloud.mirage.restful.bind.support;

import cc.shacocloud.mirage.restful.HttpRequest;
import cc.shacocloud.mirage.restful.bind.annotation.FormAttribute;
import cc.shacocloud.mirage.restful.bind.annotation.QueryParam;
import cc.shacocloud.mirage.utils.ClassUtil;
import cc.shacocloud.mirage.utils.MethodParameter;
import cc.shacocloud.mirage.utils.Utils;
import cc.shacocloud.mirage.utils.collection.CollUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.vertx.core.Future;
import io.vertx.core.MultiMap;
import io.vertx.core.json.jackson.DatabindCodec;
import org.jetbrains.annotations.NotNull;

import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * 解析{@link QueryParam}或{@link FormAttribute}注解的方法参数
 * 

* 支持三种方法参数定义类型: *

  • MultiMap类型,即当前类型注解的所有值
  • *
  • List类型|简单类型({@link ClassUtil#isSimpleValueType})数组,即当前类型注解指定名称的所有值
  • *
  • 简单类型({@link ClassUtil#isSimpleValueType}),即当前类型注解指定名称的第一个值
  • *
  • 其他,使用{@link DatabindCodec#mapper()} 的 {@link ObjectMapper#convertValue} 方法序列化
  • *

    * 注意:{@link FormAttribute}注解表示的是表单数据,表单数据是从请求体中获取的, * 按照语义来说它应该被封装在{@link RequestResponseBodyMethodProcessor}中,但是因为该类型的特殊性,所以在这里做的特殊处理。 */ public class QueryParamsAndFormAttributesMethodArgumentResolver extends AbstractNamedValueMethodArgumentResolver { private final ObjectMapper objectMapper; public QueryParamsAndFormAttributesMethodArgumentResolver(ObjectMapper objectMapper) { this.objectMapper = objectMapper; } @Override public boolean supportsParameter(@NotNull MethodParameter parameter) { return parameter.hasParameterAnnotation(QueryParam.class) || parameter.hasParameterAnnotation(FormAttribute.class); } @Override protected NamedValueInfo createNamedValueInfo(@NotNull MethodParameter parameter) { QueryParam queryParam = parameter.getParameterAnnotation(QueryParam.class); if (queryParam != null) return new QueryParamsAndFormAttributesNamedValueInfo(queryParam); FormAttribute formAttribute = parameter.getParameterAnnotation(FormAttribute.class); if (formAttribute != null) return new QueryParamsAndFormAttributesNamedValueInfo(formAttribute); throw new IllegalStateException("不支持处理当前方法,请先执行 supportsParameter 方法进行判断:" + Utils.methodDescription(parameter.getDeclaringClass(), parameter.getMethod())); } @Override protected Future resolveName(String name, @NotNull MethodParameter parameter, HttpRequest request) { Object arg; Class parameterType = parameter.getParameterType(); boolean isQueryParam = parameter.hasParameterAnnotation(QueryParam.class); // 多部分参数 if (MultiMap.class.isAssignableFrom(parameterType)) { arg = isQueryParam ? request.queryParams() : request.formAttributes(); } // 列表 或者 集合 else if (List.class.isAssignableFrom(parameterType) || (parameterType.isArray() && ClassUtil.isSimpleValueType(parameterType.getComponentType()))) { arg = isQueryParam ? request.queryParams(name) : request.formAttributes(name); } // 简单类型 else if (ClassUtil.isSimpleValueType(parameterType)) { arg = isQueryParam ? request.queryParam(name) : request.formAttribute(name); } // 其他类型 else { MultiMap multiMap = isQueryParam ? request.queryParams() : request.formAttributes(); Iterator> iterator = multiMap.iterator(); Map params = new HashMap<>(); while (iterator.hasNext()) { String key = iterator.next().getKey(); List values = multiMap.getAll(key); if (CollUtil.isNotEmpty(values)) { params.put(key, values.size() == 1 ? values.get(0) : values); } } arg = objectMapper.convertValue(params, parameterType); } return Future.succeededFuture(arg); } private static class QueryParamsAndFormAttributesNamedValueInfo extends NamedValueInfo { public QueryParamsAndFormAttributesNamedValueInfo(@NotNull QueryParam annotation) { super(annotation.name(), annotation.required(), annotation.defaultValue()); } public QueryParamsAndFormAttributesNamedValueInfo(@NotNull FormAttribute annotation) { super(annotation.name(), annotation.required(), annotation.defaultValue()); } } }