reliya1541
@reliya1541 (Taewoong Lim)

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

JAVAのproperties 問題

解決したいこと

JAVA17でpropertiesのapikeyを呼ぶ問題について。
apikeyはdataはあるんですが、使うことができないんです。
なぜpropertiesでは@ValueをつっかてRestTemplateの要請が失敗するのか知りたいです。

発生している問題・エラー

    @Value("${openai.api.key}")
    private String apiKey;

propertiesのapiKeyを呼んでrestTeamplateにつかうことができない問題

該当するソースコード

private String sendChatGptRequest(String prompt, String systemMessage, int maxTokens) {
        RestTemplate restTemplate = new RestTemplate();
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        headers.setBearerAuth(apiKey);

        JSONObject requestBody = new JSONObject();
        requestBody.put("model", "gpt-4o-mini-2024-07-18");
        requestBody.put("messages", new JSONArray()
                .put(new JSONObject().put("role", "system").put("content", systemMessage))
                .put(new JSONObject().put("role", "user").put("content", prompt))
        );
        requestBody.put("max_tokens", maxTokens);

        HttpEntity<String> entity = new HttpEntity<>(requestBody.toString(), headers);

        try {
            ResponseEntity<String> response = restTemplate.exchange(API_URL, HttpMethod.POST, entity, String.class);
            JSONObject responseBody = new JSONObject(response.getBody());
            return responseBody.getJSONArray("choices")
                    .getJSONObject(0)
                    .getJSONObject("message")
                    .getString("content")
                    .trim();
        } catch (HttpClientErrorException e) {
            log.error("HTTP Status: {}", e.getStatusCode());
            log.error("Response Body: {}", e.getResponseBodyAsString());
            throw new RuntimeException("Failed to process request. Please try again later.");
        }
    }

自分で試したこと

propertiesを使わずに直接キーに入れる=>成功
propertiesをValueを使用して読み込む => 失敗
properties を prefix を使って読み込む => 失敗
ymlに変更してValueを使用して読み込む => 成功

0

1Answer

こんにちは。試したことの1番と4番では使用すべきApiKeyと一致しいて、2番と3番では不一致しているのではないかと思いました。

不一致が起きている場合、エスケープしなくてはならなない¥マークがApiKeyに含まれていて、プロパティファイルから読み込んだ時にその部分の値が変化している状況や、あとは理由はわかりませんが、全く値が読み込まれていなくて空文字列になっているような状況が考えられるように思いました。

0Like

Comments

  1. @reliya1541

    Questioner

    お返事ありがとうございます。:slight_smile:
    変化がついて考えたんですがequalで確認したんです。
    まったく変化はいないです。
    私の考えではrestTemplateのリクエストで@Valueを使うことで何か問題があると疑がっています。

  2. 情報ありがとうございます。状況わかりました。
    解決方法は私には分からなかったのでChatGPTで調べました、以下の回答が何か役立たないでしょうか

    質問

    JavaのrestTemplateと共に@Valieプロパティを使うと何か競合することがありますか?

    回答

    @Value アノテーションと RestTemplate は直接的な競合関係にはないですが、いくつか注意すべき点があります。特に、@Value はアプリケーションの設定値やプロパティを注入するために使われ、RestTemplate はHTTP通信を行うために使います。以下のような問題が発生する可能性があります。

    1. @Value の非同期処理に関連する競合
      RestTemplate の呼び出しが非同期で行われている場合、プロパティがまだ注入されていないタイミングで RestTemplate を利用しようとすると、@Value で注入される値がまだセットされていない可能性があります。これを避けるためには、@Value で注入されるプロパティが正しく初期化されてから、RestTemplate を利用することを確実にする必要があります。

    例えば、@PostConstruct を使って、Bean初期化後に RestTemplate を呼び出すようにするとよいでしょう。

    @Component
    public class MyService {
    
        @Value("${my.property}")
        private String myProperty;
    
        private final RestTemplate restTemplate;
    
        @Autowired
        public MyService(RestTemplate restTemplate) {
            this.restTemplate = restTemplate;
        }
    
        @PostConstruct
        public void init() {
            // myProperty が正しく初期化された後に RestTemplate を使う
            System.out.println("Property value: " + myProperty);
        }
    }
    

Your answer might help someone💌