田源
2025-04-03 9b4433fddf5b401edb0aace8a404ac733b122702
Source/BladeX-Tool/blade-core-cloud/src/main/java/org/springblade/core/cloud/version/BladeSpringMvcContract.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,101 @@
/*
 *      Copyright (c) 2018-2028, DreamLu All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *
 *  Redistributions of source code must retain the above copyright notice,
 *  this list of conditions and the following disclaimer.
 *  Redistributions in binary form must reproduce the above copyright
 *  notice, this list of conditions and the following disclaimer in the
 *  documentation and/or other materials provided with the distribution.
 *  Neither the name of the dreamlu.net developer nor the names of its
 *  contributors may be used to endorse or promote products derived from
 *  this software without specific prior written permission.
 *  Author: DreamLu å¢æ˜¥æ¢¦ (596392912@qq.com)
 */
package org.springblade.core.cloud.version;
import feign.MethodMetadata;
import org.springblade.core.cloud.annotation.ApiVersion;
import org.springblade.core.cloud.annotation.UrlVersion;
import org.springblade.core.tool.utils.StringPool;
import org.springblade.core.tool.utils.StringUtil;
import org.springframework.cloud.openfeign.AnnotatedParameterProcessor;
import org.springframework.cloud.openfeign.support.SpringMvcContract;
import org.springframework.core.annotation.AnnotatedElementUtils;
import org.springframework.core.convert.ConversionService;
import org.springframework.http.HttpHeaders;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.List;
/**
 * æ”¯æŒ blade-boot çš„ ç‰ˆæœ¬ å¤„理
 *
 * @see org.springblade.core.cloud.annotation.UrlVersion
 * @see org.springblade.core.cloud.annotation.ApiVersion
 * @author L.cm
 */
public class BladeSpringMvcContract extends SpringMvcContract {
   public BladeSpringMvcContract(List<AnnotatedParameterProcessor> annotatedParameterProcessors, ConversionService conversionService) {
      super(annotatedParameterProcessors, conversionService);
   }
   @Override
   protected void processAnnotationOnMethod(MethodMetadata data, Annotation methodAnnotation, Method method) {
      if (RequestMapping.class.isInstance(methodAnnotation) || methodAnnotation.annotationType().isAnnotationPresent(RequestMapping.class)) {
         Class<?> targetType = method.getDeclaringClass();
         // url ä¸Šçš„版本,优先获取方法上的版本
         UrlVersion urlVersion = AnnotatedElementUtils.findMergedAnnotation(method, UrlVersion.class);
         // å†æ¬¡å°è¯•类上的版本
         if (urlVersion == null || StringUtil.isBlank(urlVersion.value())) {
            urlVersion = AnnotatedElementUtils.findMergedAnnotation(targetType, UrlVersion.class);
         }
         if (urlVersion != null && StringUtil.isNotBlank(urlVersion.value())) {
            String versionUrl = "/" + urlVersion.value();
            data.template().uri(versionUrl);
         }
         // æ³¨æ„ï¼šåœ¨çˆ¶ç±»ä¹‹å‰ æ·»åŠ  url版本,在父类之后,处理 Media Types ç‰ˆæœ¬
         super.processAnnotationOnMethod(data, methodAnnotation, method);
         // å¤„理 Media Types ç‰ˆæœ¬ä¿¡æ¯
         ApiVersion apiVersion = AnnotatedElementUtils.findMergedAnnotation(method, ApiVersion.class);
         // å†æ¬¡å°è¯•类上的版本
         if (apiVersion == null || StringUtil.isBlank(apiVersion.value())) {
            apiVersion = AnnotatedElementUtils.findMergedAnnotation(targetType, ApiVersion.class);
         }
         if (apiVersion != null && StringUtil.isNotBlank(apiVersion.value())) {
            BladeMediaType bladeMediaType = new BladeMediaType(apiVersion.value());
            data.template().header(HttpHeaders.ACCEPT, bladeMediaType.toString());
         }
      }
   }
   /**
    * å‚考:https://gist.github.com/rmfish/0ed59a9af6c05157be2a60c9acea2a10
    * @param annotations æ³¨è§£
    * @param paramIndex å‚数索引
    * @return æ˜¯å¦ http æ³¨è§£
    */
   @Override
   protected boolean processAnnotationsOnParameter(MethodMetadata data, Annotation[] annotations, int paramIndex) {
      boolean httpAnnotation = super.processAnnotationsOnParameter(data, annotations, paramIndex);
      // åœ¨ springMvc ä¸­å¦‚果是 Get è¯·æ±‚且参数中是对象 æ²¡æœ‰å£°æ˜Žä¸º@RequestBody åˆ™é»˜è®¤ä¸º Param
      if (!httpAnnotation && StringPool.GET.equals(data.template().method().toUpperCase())) {
         for (Annotation parameterAnnotation : annotations) {
            if (!(parameterAnnotation instanceof RequestBody)) {
               return false;
            }
         }
         data.queryMapIndex(paramIndex);
         return true;
      }
      return httpAnnotation;
   }
}