Feign进行内部调用时报404、401等问题

检查启动类是否添加feign注解相关注解

启动类需加上@EnableFeignClients、@EnableDiscoveryClient注解
在这里插入图片描述
如果未配置该注解,就不能进行服务发现以及定义feign客户端

401问题分析及解决方案

检查feign配置是否需要授权及数据解析

/**
 * @author huangxiaochneg
 * @description: feign配置
 * @time 2021/7/8 21:22
 */

@Slf4j
@RequiredArgsConstructor
public class FeignConfig implements RequestInterceptor, Decoder {
    private final ObjectMapper objectMapper;

    @Override
    public void apply(RequestTemplate requestTemplate) {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        if (attributes != null) {
            HttpServletRequest request = attributes.getRequest();
            //添加token
            String authorization = request.getHeader("Authorization");
            if(StringUtils.isNotBlank(authorization)){
                requestTemplate.header("Authorization", authorization);
            }
        }
    }


    @Override
    public Object decode(Response response, Type type) throws IOException, FeignException {
        String result = Util.toString(response.body().asReader(StandardCharsets.UTF_8));
        ResponseData baseResponse = objectMapper.readValue(result, ResponseData.class);
        String code = baseResponse.getCode();
        log.debug("feign请求返回数据:{}", JSONObject.toJSONString(baseResponse));
        if (ResponseData.IOT_SUCCESS_CODE.equals(code) || ResponseData.SUCCESS_CODE.equals(code)) {
            return baseResponse;
        } else {

            throw new ResponseException(baseResponse);
        }
    }
}

注意,如果内部调用时报401,说明没有携带token,能带就带,不过有些业务场景确实携带不了token,比如监听Kafka数据,监听后的数据是不会携带token数据的,如果进行业务处理时需要调用其他服务,就会报401,此时我们需要放开接口权限,如下代码图所示

/**
 * @description: 资源服务器配置:此处提供的任何规则都适用于存在承载令牌的情况
 */
@Configuration
@EnableResourceServer
@AllArgsConstructor
@ConditionalOnProperty(value = "oauthModel.type", havingValue = SPRING_SECURITY, matchIfMissing = true)
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {

    private AuthExceptionEntryPoint authExceptionEntryPoint;
    private CustomAccessDeniedHandler customAccessDeniedHandler;
    private PermitAllSecurityConfig permitAllSecurityConfig;


    @Override
    public void configure(ResourceServerSecurityConfigurer resources) {
        resources.resourceId("dfs-service").stateless(true)
                .authenticationEntryPoint(authExceptionEntryPoint)
                .accessDeniedHandler(customAccessDeniedHandler);
    }


    @Override
    public void configure(HttpSecurity http) throws Exception {
        http.apply(permitAllSecurityConfig)
                .and()
                .authorizeRequests()
                .antMatchers(PermitUrl.PERMIT_URL_LIST.toArray(new String[0])).permitAll()
                .anyRequest().authenticated()
                .and()
                .exceptionHandling()
                .authenticationEntryPoint((request, response, authException) -> response.sendError(HttpServletResponse.SC_UNAUTHORIZED))
                .and()
                .csrf().disable()
                .httpBasic();
    }
}

/**
 * @Description: 不需要拦截的地址统一配置
 */
public class PermitUrl {
    public static List<String> PERMIT_URL_LIST = Arrays.asList(
            "/inner/**",
            "/base/func/config/is/open/operation/order",
            "/report/file/preview"
    );
}

404问题分析及解决方案

这个问题困扰了大半天时间,反复确认接口路径是不是正确的,结果发现一点问题都没有,但是还是报404,查阅资料后发现,SpringBoot启动时候,主启动类从当前包开始,向下级包进行扫描,所以如果Controller在主启动类所在包的上级,是不会被扫描进IOC容器并进行自动配置,将主启动类移动到Controller包上级,即可扫描到Controller
Feign进行内部调用时报404、401等问题_第1张图片
比如将inner包移动到com包下,该inner包下的所有类是不会被扫描进IOC容器并进行自动配置的。

你可能感兴趣的:(java,开发语言)