Merge branch '5-accept-language-works-for-i18n-db-schema-but-not-for-messages-properties' into 'master'
Locale Lookup Closes #5 See merge request !2
This commit is contained in:
		
						commit
						e80343053b
					
				|  | @ -10,11 +10,13 @@ import org.springframework.web.servlet.LocaleResolver; | |||
| import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; | ||||
| import org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver; | ||||
| 
 | ||||
| import de.mstock.monolith.web.i18n.AcceptHeaderLookupLocaleResolver; | ||||
| 
 | ||||
| @Configuration | ||||
| public class I18nConfig extends WebMvcConfigurerAdapter { | ||||
| 
 | ||||
|   private static final List<Locale> SUPPORTED_LOCALES = | ||||
|       Arrays.asList(new Locale("de_DE"), new Locale("en_US")); | ||||
|       Arrays.asList(new Locale("en", "US"), new Locale("de", "DE")); | ||||
| 
 | ||||
|   /** | ||||
|    * Creates a Bean, managed by Spring. | ||||
|  | @ -23,9 +25,10 @@ public class I18nConfig extends WebMvcConfigurerAdapter { | |||
|    */ | ||||
|   @Bean | ||||
|   public LocaleResolver localeResolver() { | ||||
|     AcceptHeaderLocaleResolver localeResolver = new AcceptHeaderLocaleResolver(); | ||||
|     Locale defaultLocale = SUPPORTED_LOCALES.get(0); | ||||
|     AcceptHeaderLocaleResolver localeResolver = new AcceptHeaderLookupLocaleResolver(defaultLocale); | ||||
|     localeResolver.setSupportedLocales(SUPPORTED_LOCALES); | ||||
|     localeResolver.setDefaultLocale(Locale.US); | ||||
|     localeResolver.setDefaultLocale(defaultLocale); | ||||
|     return localeResolver; | ||||
|   } | ||||
| 
 | ||||
|  |  | |||
|  | @ -0,0 +1,44 @@ | |||
| package de.mstock.monolith.web.i18n; | ||||
| 
 | ||||
| import java.util.ArrayList; | ||||
| import java.util.Arrays; | ||||
| import java.util.List; | ||||
| import java.util.Locale; | ||||
| import java.util.Locale.LanguageRange; | ||||
| 
 | ||||
| import javax.servlet.http.HttpServletRequest; | ||||
| 
 | ||||
| import org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver; | ||||
| 
 | ||||
| public class AcceptHeaderLookupLocaleResolver extends AcceptHeaderLocaleResolver { | ||||
| 
 | ||||
|   private final Locale fallback; | ||||
|   private final ArrayList<LanguageRange> ranges = new ArrayList<>(); | ||||
| 
 | ||||
|   public AcceptHeaderLookupLocaleResolver(Locale fallback) { | ||||
|     this.fallback = fallback; | ||||
|   } | ||||
| 
 | ||||
|   @Override | ||||
|   public void setSupportedLocales(List<Locale> locales) { | ||||
|     super.setSupportedLocales(locales); | ||||
|     ranges.clear(); | ||||
|     for (Locale supportedLocale : getSupportedLocales()) { | ||||
|       ranges.add(new LanguageRange(supportedLocale.getLanguage() + "-*")); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   @Override | ||||
|   public Locale resolveLocale(HttpServletRequest request) { | ||||
|     Locale resolvedLocale = super.resolveLocale(request); | ||||
|     if (getSupportedLocales().contains(resolvedLocale)) { | ||||
|       return resolvedLocale; | ||||
|     } | ||||
|     Locale lookup = Locale.lookup(ranges, Arrays.asList(resolvedLocale)); | ||||
|     if (lookup != null) { | ||||
|       return lookup; | ||||
|     } | ||||
|     return fallback; | ||||
|   } | ||||
| 
 | ||||
| } | ||||
|  | @ -1,18 +1 @@ | |||
| company = Mosh | ||||
| general.backToTop = Back to top | ||||
| general.sampleImage = Sample image | ||||
| navigation.toggle = Toggle navigation | ||||
| navigation.legalNotice = Legal Notice | ||||
| products.kiwis=Kiwis | ||||
| products.blueberries=Blueberries | ||||
| products.cherries=Cherries | ||||
| products.kiwis.prettyUrlFragment=kiwis | ||||
| products.blueberries.prettyUrlFragment=blueberries | ||||
| products.cherries.prettyUrlFragment=cherries | ||||
| products.goto = Go to product | ||||
| features.headline1 = Delicious Fruits. | ||||
| features.subheadline1 = It'll blow your mind. | ||||
| features.headline2 = Oh yeah, it's that good. | ||||
| features.subheadline2 = See for yourself. | ||||
| features.headline3 = And lastly, this one. | ||||
| features.subheadline3 = Checkmate. | ||||
|  | @ -14,4 +14,4 @@ features.subheadline1 = Es wird dich umhauen. | |||
| features.headline2 = Das ist gut. | ||||
| features.subheadline2 = Sieh' selbst. | ||||
| features.headline3 = Und zum Schluss, das hier. | ||||
| features.subheadline3 = Bingo. | ||||
| features.subheadline3 = Bingo. | ||||
|  |  | |||
|  | @ -0,0 +1,17 @@ | |||
| general.backToTop = Back to top | ||||
| general.sampleImage = Sample image | ||||
| navigation.toggle = Toggle navigation | ||||
| navigation.legalNotice = Legal Notice | ||||
| products.kiwis=Kiwis | ||||
| products.blueberries=Blueberries | ||||
| products.cherries=Cherries | ||||
| products.kiwis.prettyUrlFragment=kiwis | ||||
| products.blueberries.prettyUrlFragment=blueberries | ||||
| products.cherries.prettyUrlFragment=cherries | ||||
| products.goto = Go to product | ||||
| features.headline1 = Delicious Fruits. | ||||
| features.subheadline1 = It'll blow your mind. | ||||
| features.headline2 = Oh yeah, it's that good. | ||||
| features.subheadline2 = See for yourself. | ||||
| features.headline3 = And lastly, this one. | ||||
| features.subheadline3 = Checkmate. | ||||
|  | @ -1,19 +0,0 @@ | |||
| package de.mstock.monolith; | ||||
| 
 | ||||
| import static org.junit.Assert.assertTrue; | ||||
| 
 | ||||
| import org.junit.Test; | ||||
| import org.junit.runner.RunWith; | ||||
| import org.springframework.boot.test.context.SpringBootTest; | ||||
| import org.springframework.test.context.junit4.SpringRunner; | ||||
| 
 | ||||
| @RunWith(SpringRunner.class) | ||||
| @SpringBootTest | ||||
| public class MonolithApplicationTests { | ||||
| 
 | ||||
|   @Test | ||||
|   public void contextLoads() { | ||||
|     assertTrue(true); | ||||
|   } | ||||
| 
 | ||||
| } | ||||
|  | @ -0,0 +1,80 @@ | |||
| package de.mstock.monolith.web; | ||||
| 
 | ||||
| import static org.hamcrest.CoreMatchers.containsString; | ||||
| import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; | ||||
| import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; | ||||
| import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; | ||||
| 
 | ||||
| import java.util.Locale; | ||||
| 
 | ||||
| import org.junit.Before; | ||||
| import org.junit.Test; | ||||
| import org.junit.runner.RunWith; | ||||
| import org.springframework.beans.factory.annotation.Autowired; | ||||
| import org.springframework.boot.test.context.SpringBootTest; | ||||
| import org.springframework.http.HttpHeaders; | ||||
| import org.springframework.test.context.junit4.SpringRunner; | ||||
| import org.springframework.test.context.web.WebAppConfiguration; | ||||
| import org.springframework.test.web.servlet.MockMvc; | ||||
| import org.springframework.test.web.servlet.setup.MockMvcBuilders; | ||||
| import org.springframework.web.context.WebApplicationContext; | ||||
| 
 | ||||
| @RunWith(SpringRunner.class) | ||||
| @SpringBootTest | ||||
| @WebAppConfiguration | ||||
| public class HomepageControllerTest { | ||||
| 
 | ||||
|   @Autowired | ||||
|   private WebApplicationContext webApplicationContext; | ||||
| 
 | ||||
|   private MockMvc mockMvc; | ||||
| 
 | ||||
|   @Before | ||||
|   public void setup() { | ||||
|     mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build(); | ||||
|   } | ||||
| 
 | ||||
|   @Test | ||||
|   public void shouldPrintEnglishTexts() throws Exception { | ||||
|     mockMvc.perform(get("/").header(HttpHeaders.ACCEPT_LANGUAGE, "en").locale(new Locale("en"))) | ||||
|         .andExpect(status().isOk()).andExpect(content().string(containsString("Fruits"))) | ||||
|         .andExpect(content().string(containsString("to top"))); | ||||
|   } | ||||
| 
 | ||||
|   @Test | ||||
|   public void shouldPrintGermanTexts() throws Exception { | ||||
|     mockMvc.perform(get("/").header(HttpHeaders.ACCEPT_LANGUAGE, "de").locale(new Locale("de"))) | ||||
|         .andExpect(status().isOk()).andExpect(status().isOk()) | ||||
|         .andExpect(content().string(containsString("Obst"))) | ||||
|         .andExpect(content().string(containsString("nach oben"))); | ||||
|   } | ||||
| 
 | ||||
|   @Test | ||||
|   public void shouldPrintEnglishTextsForAustralia() throws Exception { | ||||
|     mockMvc | ||||
|         .perform( | ||||
|             get("/").header(HttpHeaders.ACCEPT_LANGUAGE, "en-AU").locale(new Locale("en", "AU"))) | ||||
|         .andExpect(status().isOk()).andExpect(content().string(containsString("Fruits"))) | ||||
|         .andExpect(content().string(containsString("to top"))); | ||||
|   } | ||||
| 
 | ||||
|   @Test | ||||
|   public void shouldPrintGermanTextsForAustria() throws Exception { | ||||
|     mockMvc | ||||
|         .perform( | ||||
|             get("/").header(HttpHeaders.ACCEPT_LANGUAGE, "de-AT").locale(new Locale("de", "AT"))) | ||||
|         .andExpect(status().isOk()).andExpect(status().isOk()) | ||||
|         .andExpect(content().string(containsString("Obst"))) | ||||
|         .andExpect(content().string(containsString("nach oben"))); | ||||
|   } | ||||
| 
 | ||||
|   @Test | ||||
|   public void shouldPrintEnglishTextsForChina() throws Exception { | ||||
|     mockMvc | ||||
|         .perform( | ||||
|             get("/").header(HttpHeaders.ACCEPT_LANGUAGE, "zh-CN").locale(new Locale("zh", "CN"))) | ||||
|         .andExpect(status().isOk()).andExpect(content().string(containsString("Fruits"))) | ||||
|         .andExpect(content().string(containsString("to top"))); | ||||
|   } | ||||
| 
 | ||||
| } | ||||
		Reference in New Issue
	
	 Matthias Stock
						Matthias Stock