You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot应用无法从.env读取API密钥,请求报错如何修复?

解决APILayer货币兑换API调用的两个核心问题

一、API密钥读取失败(始终使用default-key)

问题原因

  1. Spring Boot 2.4+版本默认不会自动加载.env文件,导致配置未被读取;
  2. Constants类使用静态变量结合@Value注入,存在初始化顺序问题,容易导致注入值未生效。

解决方案

1. 确保.env文件被正确加载

  • 在项目的pom.xml(Maven)或build.gradle(Gradle)中添加spring-boot-starter-cloud-context依赖,让Spring自动识别.env文件;
  • 或者在Spring Boot主启动类上添加@PropertySource("classpath:.env")注解,手动指定加载.env配置(注意.env需放在src/main/resources目录下)。

2. 重构配置读取逻辑(推荐)

弃用静态变量的方式,改用@ConfigurationProperties绑定配置,更符合Spring规范:

@Component
@ConfigurationProperties(prefix = "exchange-api")
public class ApiProperties {
    private String apiUrl;
    private String apiKey;
    private String cacheName;
    private Integer apiCallLimit;

    // 生成getter和setter方法
}

然后在RateService中注入ApiProperties替代静态变量:

@Service
public class RateService {
    private final ApiProperties apiProperties;
    private final RestTemplate restTemplate;
    private final RateRepository rateRepository;

    // 构造方法注入
    public RateService(ApiProperties apiProperties, RestTemplate restTemplate, RateRepository rateRepository) {
        this.apiProperties = apiProperties;
        this.restTemplate = restTemplate;
        this.rateRepository = rateRepository;
    }

    private RateEntity saveRatesFromApi(LocalDate rateDate, EnumCurrency base, List<EnumCurrency> targets) {
        log.info("ExchangeService | saveRatesFromApi is called");

        HttpHeaders headers = new HttpHeaders();
        // 使用配置类中的apiKey
        headers.add("apikey", apiProperties.getApiKey());
        headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
        final HttpEntity<String> headersEntity = new HttpEntity<>(headers);
        String url = getExchangeUrl(rateDate, base, targets);

        ResponseEntity<RateResponse> responseEntity = restTemplate.exchange(url, HttpMethod.GET, headersEntity, RateResponse.class);

        RateResponse rates = responseEntity.getBody();
        RateEntity entity = convert(rates);
        entity.setDate(rateDate);
        return rateRepository.save(entity);
    }

    private String getExchangeUrl(LocalDate rateDate, EnumCurrency base, List<EnumCurrency> targets) {
        String symbols = String.join("%2C", targets.stream().map(EnumCurrency::name).toArray(String[]::new));
        // 使用配置类中的apiUrl
        return apiProperties.getApiUrl() + rateDate + "?symbols=" + symbols + "&base=" + base;
    }
}

二、Jackson反序列化错误(Unrecognized field "message")

问题原因

APILayer返回的错误响应包含message字段,但自定义的RestTemplateError类未定义该字段,且未配置Jackson忽略未知属性,导致反序列化失败。

解决方案

方式1:添加message字段到RestTemplateError

public class RestTemplateError {
    private String error;
    private int status;
    private String path;
    private long timestamp;
    private String message; // 新增字段匹配API返回

    // 生成对应getter和setter
}

方式2:配置Jackson忽略未知字段

在RestTemplateError类上添加@JsonIgnoreProperties注解,让Jackson忽略未定义的字段:

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

@JsonIgnoreProperties(ignoreUnknown = true)
public class RestTemplateError {
    private String error;
    private int status;
    private String path;
    private long timestamp;

    // 生成getter和setter
}

可选:完善RestTemplate错误处理

配置RestTemplate的错误处理器,确保API返回错误状态码时能正确解析错误信息:

@Bean
public RestTemplate restTemplate() {
    RestTemplate restTemplate = new RestTemplate();
    restTemplate.setErrorHandler(new DefaultResponseErrorHandler() {
        @Override
        protected boolean hasError(HttpStatus statusCode) {
            return statusCode.is4xxClientError() || statusCode.is5xxServerError();
        }

        @Override
        public void handleError(ClientHttpResponse response) throws IOException {
            ObjectMapper mapper = new ObjectMapper();
            RestTemplateError error = mapper.readValue(response.getBody(), RestTemplateError.class);
            throw new RuntimeException(error.getMessage() != null ? error.getMessage() : error.getError(), response.getStatusCode());
        }
    });
    return restTemplate;
}

内容的提问来源于stack exchange,提问作者Sercan Noyan Germiyanoğlu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 06:10:44