-
setCookieName(String) method has been removed and is now replaced by a constructor that accepts the cookie name directly: CookieLocaleResolver(String cookieName).
- The
setCookieMaxAge(Integer) method is superseded by setCookieMaxAge(Duration), which leverages the java.time.Duration API for more precise and flexible expiry configurations.
- The
determineDefaultLocale(HttpServletRequest request) method deprecated (removed in Spring 7) and its internal logic has been internalized; it is now superseded by the functional setDefaultLocaleFunction(Function) method, which provides a more modern and customizable way to resolve the default locale. for example:
@Bean
public CookieLocaleResolver localeResolver() {
CookieLocaleResolver resolver = new CookieLocaleResolver();
resolver.setDefaultLocaleFunction(request -> {
String header = request.getHeader("X-Custom-Header");
return header != null ? Locale.forLanguageTag(header) : Locale.US;
});
return resolver;
}
Controller
package com.logicbig.example;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import java.util.LinkedHashMap;
import java.util.Locale;
import java.util.Map;
@Controller
public class TheController {
@RequestMapping(value = "/",
method = {RequestMethod.POST, RequestMethod.GET})
public String handleGet (Model model, Locale locale) {
FormData formData = new FormData();
formData.setLocaleCode(locale.toString());
model.addAttribute("formData", formData);
Map<String, String> localeChoices = new LinkedHashMap<>();
Locale l = Locale.US;
localeChoices.put(l.toString(), l.getDisplayLanguage());
l = Locale.GERMANY;
localeChoices.put(l.toString(), l.getDisplayLanguage());
l = Locale.FRANCE;
localeChoices.put(l.toString(), l.getDisplayLanguage());
model.addAttribute("localeChoices", localeChoices);
return "main";
}
@RequestMapping(value = "/page1")
public String handlePage1 () {
return "page1";
}
@RequestMapping(value = "/page2")
public String handlePage2 () {
return "page2";
}
public static class FormData {
private String localeCode;
public String getLocaleCode () {
return localeCode;
}
public void setLocaleCode (String localeCode) {
this.localeCode = localeCode;
}
}
}
The rest of the artifacts remain the same as in the last example. The output and flow are also the same.
After changing the language in the dropdown, a cookie will be created in the browser.
In the Google Chrome browser (right-click on the page > Inspect > Application (top toolbar) > Storage (left tree) > Cookies > http://localhost:8080):
Integration Test
package com.logicbig.example;
import jakarta.servlet.http.Cookie;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.setup.DefaultMockMvcBuilder;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
import static org.hamcrest.Matchers.hasProperty;
import static org.hamcrest.Matchers.is;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
@ExtendWith(SpringExtension.class)
@WebAppConfiguration
@ContextConfiguration(classes = WebConfig.class)
public class ControllerTest {
@Autowired
private WebApplicationContext wac;
private MockMvc mockMvc;
@BeforeEach
public void setup() {
DefaultMockMvcBuilder builder = MockMvcBuilders.webAppContextSetup(this.wac);
this.mockMvc = builder.build();
}
@Test
public void localeSetByPostPersistsOnSubsequentGet() throws Exception {
MvcResult result =
mockMvc.perform(post("/")
.param("localeCode",
"de_DE")
)
.andExpect(status().isOk())
.andExpect(cookie().exists("localInfo"))
.andExpect(model().attribute(
"formData",
hasProperty("localeCode",
is("de_DE"))))
.andReturn();
mockMvc.perform(get("/").cookie(
result.getResponse().getCookies())
)
.andExpect(status().isOk())
.andExpect(model().attribute("formData",
hasProperty("localeCode",
is("de_DE"))));
mockMvc.perform(get("/page1").cookie(
result.getResponse().getCookies()))
.andExpect(status().isOk())
.andExpect(view().name("page1"))
.andExpect(forwardedUrl("/WEB-INF/pages/page1.jsp"));
}
}
mvn clean test -Dtest="ControllerTest"
Output
$ mvn clean test -Dtest="ControllerTest"
[INFO] Scanning for projects...
[INFO]
[INFO] --------< com.logicbig.example:cookie-locale-resolver-example >---------
[INFO] Building cookie-locale-resolver-example 1.0-SNAPSHOT
[INFO] from pom.xml
[INFO] --------------------------------[ war ]---------------------------------
[INFO]
[INFO] --- clean:3.2.0:clean (default-clean) @ cookie-locale-resolver-example ---
[INFO] Deleting D:\example-projects\spring-mvc\cookie-locale-resolver-example\target
[INFO]
[INFO] --- resources:3.3.1:resources (default-resources) @ cookie-locale-resolver-example ---
[INFO] Copying 3 resources from src\main\resources to target\classes
[INFO]
[INFO] --- compiler:3.3:compile (default-compile) @ cookie-locale-resolver-example ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 3 source files to D:\example-projects\spring-mvc\cookie-locale-resolver-example\target\classes
[INFO]
[INFO] --- resources:3.3.1:testResources (default-testResources) @ cookie-locale-resolver-example ---
[INFO] skip non existing resourceDirectory D:\example-projects\spring-mvc\cookie-locale-resolver-example\src\test\resources
[INFO]
[INFO] --- compiler:3.3:testCompile (default-testCompile) @ cookie-locale-resolver-example ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 1 source file to D:\example-projects\spring-mvc\cookie-locale-resolver-example\target\test-classes
[INFO]
[INFO] --- surefire:3.2.5:test (default-test) @ cookie-locale-resolver-example ---
[INFO] Using auto detected provider org.apache.maven.surefire.junit4.JUnit4Provider
[INFO]
[INFO] -------------------------------------------------------
[INFO] T E S T S
[INFO] -------------------------------------------------------
[INFO] Running com.logicbig.example.ControllerTest
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.756 s -- in com.logicbig.example.ControllerTest
[INFO]
[INFO] Results:
[INFO]
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 2.882 s
[INFO] Finished at: 2026-08-27T18:48:42+08:00
[INFO] ------------------------------------------------------------------------