HttpHeaders ::setAcceptLanguageAsLocales делает заголовок строчным

#java #spring-boot #http-headers #locale

#java #весенняя загрузка #http-заголовки #locale

Вопрос:

Когда я использую setAcceptLanguageAsLocales, все содержимое заголовка в нижнем регистре

 HttpHeaders headers = new HttpHeaders();
headers.setAcceptLanguageAsLocales(List.of(Locale.US, Locale.GERMANY));
 

Результат:

 Accept-Language: en-us, de-de
 

Почему он преобразуется в нижний регистр? Я бы ожидал:

 Accept-Language: en-US, de-DE
 

Ответ №1:

Это следствие кода Spring Framework. Если вы проверите HttpHeaders код, вы обнаружите, что реализация метода setAcceptLanguageAsLocales выглядит следующим образом:

 public void setAcceptLanguageAsLocales(List<Locale> locales) {
  setAcceptLanguage(locales.stream()
      .map(locale -> new Locale.LanguageRange(locale.toLanguageTag()))
      .collect(Collectors.toList()));
}
 

Важной частью является преобразование в Locale.LanguageRange объект. Если вы проверите его код, вы обнаружите, что его LanguageRange(String range, double weight) конструктор реализован следующим образом:

 public LanguageRange(String range, double weight) {
    if (range == null) {
        throw new NullPointerException();
    }
    if (weight < MIN_WEIGHT || weight > MAX_WEIGHT) {
        throw new IllegalArgumentException("weight="   weight);
    }

    range = range.toLowerCase(Locale.ROOT);

    // Do syntax check.
    boolean isIllFormed = false;
    String[] subtags = range.split("-");
    if (isSubtagIllFormed(subtags[0], true)
        || range.endsWith("-")) {
        isIllFormed = true;
    } else {
        for (int i = 1; i < subtags.length; i  ) {
            if (isSubtagIllFormed(subtags[i], false)) {
                isIllFormed = true;
                break;
            }
        }
    }
    if (isIllFormed) {
        throw new IllegalArgumentException("range="   range);
    }

    this.range = range;
    this.weight = weight;
}
 

Важной частью является строка range = range.toLowerCase(Locale.ROOT); , которая фактически преобразует все в предоставленном locale.toLanguageTag() в нижний регистр, отсюда и результат, который вы наблюдали. Приведенный ниже код имитирует код Spring Framework и покажет вам результаты:

 public class Main {
    public static void main(String[] args) {
        List<Locale> locales = List.of(Locale.US, Locale.GERMANY);
        System.out.println("::::: Original Locales :::::");
        System.out.println(locales);

        System.out.println("::::: Language Tags :::::");
        List<Locale.LanguageRange> languages = locales.stream()
                .map(locale -> {
                    String languageTag = locale.toLanguageTag();
                    System.out.println(languageTag);

                    return new Locale.LanguageRange(languageTag);
                })
                .collect(Collectors.toList());
        System.out.println("::::: Locales Language Rages :::::");
        System.out.println(languages);
    }
}