CodeZLei

  博客园 :: 首页 :: 博问 :: 闪存 :: :: 联系 :: 订阅 订阅 :: 管理 ::

处理fegin的自定义的异常

spring boot 2.X.X

import feign.FeignException;
import feign.RetryableException;
import feign.codec.ErrorDecoder;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.context.annotation.Bean;

@Slf4j
public class MicroServiceFeignConfiguration {

    @Bean
    ErrorDecoder defaultErrorDecoder() {
        return (methodKey, response) -> {
            Exception rawFeignException = new ErrorDecoder.Default().decode(methodKey, response);
            if (rawFeignException instanceof RetryableException) {
                return rawFeignException;
            }
            FeignException feignException = (FeignException) rawFeignException;
            if (StringUtils.isBlank(feignException.contentUTF8())) {
                return feignException;
            }
            try {
                String errorBody = feignException.contentUTF8();
                ExceptionHttpBody exceptionHttpBody = JsonUtil.parse(errorBody, ExceptionHttpBody.class);

                if (exceptionHttpBody.getException() != null) {
                    try {
                        Class<?> clazz = Class.forName(exceptionHttpBody.getException());
                        return (Exception) JsonUtil.convertValue(exceptionHttpBody, clazz);
                    } catch (ClassNotFoundException e) {
                        log.warn("class {} not in classpath", exceptionHttpBody.getException());
                    }
                }
            } catch (Exception e) {
                log.warn("Can not decode microservice exception", e);
            }
            return feignException;
        };
    }
}  

springboot 1.x.x

import feign.FeignException
import feign.Response
import feign.RetryableException
import feign.codec.ErrorDecoder
import groovy.util.logging.Slf4j
import org.apache.commons.lang.StringUtils
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration

@Configuration
@Slf4j
class FeignErrorConfig {

    @Bean
    ErrorDecoder feignErrorDecoder() {
        return new ErrorDecoder() {
            @Override
            Exception decode(String methodKey, Response response) {
                Exception rawFeignException = new ErrorDecoder.Default().decode(methodKey, response);
                if (rawFeignException instanceof RetryableException) {
                    return rawFeignException;
                }
                FeignException feignException = (FeignException) rawFeignException;
                if (StringUtils.isBlank(feignException.getMessage())) {
                    return feignException
                }
                try {
                    ExceptionHttpBody exceptionHttpBody = JsonUtil.parse(feignException.getMessage().split('\n')[1], ExceptionHttpBody.class)
                    if (exceptionHttpBody.getException() != null) {
                        try {
                            Class<?> clazz = Class.forName(exceptionHttpBody.getException())
                            return (Exception) JsonUtil.convertValue(exceptionHttpBody, clazz)
                        } catch (ClassNotFoundException e) {
                            log.warn("class {} not in classpath", exceptionHttpBody.getException())
                        }
                    }
                } catch (Exception e) {
                    log.warn("Can not decode microservice exception", e)
                }
                return feignException
            }
        }
    }
}

 

配置请求的处理

mport feign.RequestInterceptor
import feign.RequestTemplate
import groovy.transform.CompileStatic
import org.springframework.beans.factory.annotation.Value
import org.springframework.cloud.netflix.feign.FeignClient
import org.springframework.context.annotation.Bean
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.PathVariable


@FeignClient(name = "xxx", url = '${funding.base-url}', configuration = [FundingClientFeignConfig])
@CompileStatic
interface xxx {


    @GetMapping('/{xxxId}?idType=1')
    P2pLoanDetailResult getLoanDetail(@PathVariable('loanId') String loanId)

    class FundingClientFeignConfig {

        @Bean
        AuthRequestInterceptor authRequestInterceptor(@Value('${funding.token}') String token) {
            return new AuthRequestInterceptor(token)
        }

        class AuthRequestInterceptor implements RequestInterceptor {
            String token

            AuthRequestInterceptor(String token) {
                this.token = token
            }

            @Override
            void apply(RequestTemplate template) {
                template.header('Authorization', "Bearer ${token}")
            }
        }
    }

}

配置

@Configuration
@Slf4j
@CompileStatic
class FeignConfig {
    @Bean
    @ConditionalOnMissingBean
    Retryer feignRetryer() {
        return Retryer.NEVER_RETRY
    }

    @Bean
    @Scope("prototype")
    @ConditionalOnMissingBean
    Feign.Builder feignBuilder(Retryer retryer, @Value("spring.profile") String profile) {
        return Feign.builder().invocationHandlerFactory(new InvocationHandlerFactoryImpl((profile))).retryer(retryer)
    }

    @Bean
    Client feignClient(CachingSpringLoadBalancerFactory cachingFactory, SpringClientFactory clientFactory) {
        return new LoadBalancerFeignClient(new LoggingClient(null, null, { false }), cachingFactory, clientFactory)
    }

    @Bean
    Decoder feignDecoder() {
        MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(JsonUtil.COMMON_OBJECT_MAPPER)
        converter.supportedMediaTypes = [MediaType.ALL, MediaType.APPLICATION_JSON, new MediaType("application", "*+json")]
        ObjectFactory<HttpMessageConverters> objectFactory = { new HttpMessageConverters(converter) }
        return new ResponseEntityDecoder(new SpringDecoder(objectFactory))
    }
}

log

 

posted on 2020-06-22 00:54  CodeZLei  阅读(151)  评论(0编辑  收藏  举报