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

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

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

import com.fasterxml.jackson.databind.ObjectMapper;
import cc.shacocloud.mirage.utils.Utils;
import cc.shacocloud.mirage.web.HttpRequest;
import cc.shacocloud.mirage.web.bind.annotation.FormAttribute;
import cc.shacocloud.mirage.web.bind.annotation.QueryParam;
import io.vertx.core.Future;
import io.vertx.core.MultiMap;
import io.vertx.core.json.jackson.DatabindCodec;
import org.springframework.beans.BeanUtils;
import org.springframework.core.MethodParameter;

import java.util.List;

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

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

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

    * 注意:{@link FormAttribute}注解表示的是表单数据,表单数据是从请求体中获取的, * 按照语义来说它应该被封装在{@link RequestResponseBodyMethodProcessor}中,但是因为该类型的特殊性,所以在这里做的特殊处理。 */ public class QueryParamsAndFormAttributesMethodArgumentResolver extends AbstractNamedValueMethodArgumentResolver { @Override public boolean supportsParameter(MethodParameter parameter) { return parameter.hasParameterAnnotation(QueryParam.class) || parameter.hasParameterAnnotation(FormAttribute.class); } @Override protected NamedValueInfo createNamedValueInfo(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 String resolveStringValue(String value) { return value; } @Override protected Future resolveName(String name, 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() && BeanUtils.isSimpleValueType(parameterType.getComponentType()))) { arg = isQueryParam ? request.queryParams(name) : request.formAttributes(name); } else if (BeanUtils.isSimpleValueType(parameterType)) { arg = isQueryParam ? request.queryParam(name) : request.formAttribute(name); } else { arg = DatabindCodec.mapper().convertValue(isQueryParam ? request.queryParams() : request.formAttributes(), parameterType); } return Future.succeededFuture(arg); } private static class QueryParamsAndFormAttributesNamedValueInfo extends NamedValueInfo { public QueryParamsAndFormAttributesNamedValueInfo(QueryParam annotation) { super(annotation.name(), annotation.required(), annotation.defaultValue()); } public QueryParamsAndFormAttributesNamedValueInfo(FormAttribute annotation) { super(annotation.name(), annotation.required(), annotation.defaultValue()); } } }