HttpHeaders::setAcceptLanguageAsLocales 使 header 小写

HttpHeaders::setAcceptLanguageAsLocales makes header lowercase

当我使用 setAcceptLanguageAsLocales 时,header 内容全部为小写

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

结果:

Accept-Language: en-us, de-de

为什么要转为小写?我希望:

Accept-Language: en-US, de-DE

这是 Spring 框架代码的结果。查看HttpHeaderscode会发现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 框架代码,并将向您展示结果:

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);
    }
}