spring-bootのプロパティspring.servlet.encoding.charset(4.xより前はserver.servlet.encoding.charset)により、HTTPリクエスト・レスポンスの文字コードを制御できる。これの挙動を確認する。
plugins {
id 'java'
id 'org.springframework.boot' version '4.0.4'
id 'io.spring.dependency-management' version '1.1.7'
}
group = 'com.example'
version = '0.0.1-SNAPSHOT'
java {
toolchain {
languageVersion = JavaLanguageVersion.of(21)
}
}
configurations {
compileOnly {
extendsFrom annotationProcessor
}
}
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-validation'
implementation 'org.springframework.boot:spring-boot-starter-webmvc'
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-webmvc-test'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
}
tasks.named('test') {
useJUnitPlatform()
}
プロパティ対応クラスのjavadocは以下になっている。
@ConfigurationProperties("spring.servlet.encoding")
public class ServletEncodingProperties {
/**
* Charset of HTTP requests and responses. Added to the "Content-Type" header if not
* set explicitly.
*/
private Charset charset = DEFAULT_CHARSET; // StandardCharsets.UTF_8
明示的なContent-Typeが無ければ追加、となっている。たとえば、以下のようなプロパティ指定をして適当なRestControllerを作成すると、
spring.servlet.encoding.charset=Shift_JIS
spring.servlet.encoding.force=true
下記のレスポンスヘッダーになる。もっとも、現代でapplication/jsonにcharsetを付与するケースは少ないし、ましてやShift_JISはまずありえないので、例としてはちょっと微妙だが……
Content-Type: application/json;charset=Shift_JIS
上記プロパティ未指定時のデフォルト挙動を見てみる。
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class SampleRestController {
@GetMapping("/sample")
public ResponseEntity<String> sample(HttpServletRequest request, HttpServletResponse response) {
System.out.println(request.getCharacterEncoding());
System.out.println(response.getCharacterEncoding());
結果は以下のとおり。
UTF-8
ISO-8859-1
レスポンスはざっと見た感じTomcatのデフォルトorg.apache.coyote.Constants.DEFAULT_BODY_CHARSET.name();のISO-8859-1になるようだ。
今一度以下のようなプロパティにしてみる。
spring.servlet.encoding.charset=Shift_JIS
spring.servlet.encoding.force=true
するとこうなる。
Shift_JIS
Shift_JIS
このプロパティを使用するクラスはどこか。auto-configのHttpEncodingAutoConfigurationでCharacterEncodingFilterの生成時にセットしている。javadoc見る限り、デフォルトのエンコーディング指定や強制、が主要な役割となる。
このプロパティ周りだけでもまぁまぁややこしい挙動なのが分かる。なるべくデフォルトの'UTF-8'に任せ、プロパティは変更せず、必要な最小限の設定が良さそうな事が分かる。