Spring应用:用户Locale偏好保存与登录自动切换实现咨询
Hey there! Let's figure out how to save your users' locale preferences to MySQL when they change their language selection. Here's a step-by-step solution that integrates smoothly with your existing code:
1. Update Frontend Language Selection
First, adjust your HTML and JavaScript to send a save request before applying the locale change. We'll ditch the direct ?lang= URL jumps in favor of a dedicated backend endpoint for persistence:
Modified HTML Select:
<form id="change-language-form" name="change-language-form" class="change-language-form ng-pristine ng-valid" method="POST"> <div class="row"> <div class="text-right col-sm-offset-8 col-sm-4"> <select id="language-selector" name="language-selector" class="language-selector"> <option value="">Language </option> <option value="en-GB">English </option> <option value="zh">中文 </option> <option value="de-DE">Deutsch </option> <option value="es-ES">Español </option> <option value="fr-FR">Français </option> </select> </div> </div> <div class="row"> <div class="spacer-sml"></div> </div> </form>
Updated JavaScript:
$('#language-selector').change(function() { var selectedLocale = $(this).find("option:selected").val(); if (selectedLocale) { // First save the preference to the database $.post('/save-user-locale', { locale: selectedLocale }, function() { // Reload the page to apply the new locale window.location.reload(); }).fail(function() { alert('Oops, failed to save your language preference.'); // Fallback: still apply the locale to the current session window.location = '?lang=' + selectedLocale.replace('-', '_'); }); } });
2. Create a Controller to Handle Preference Saving
Add a controller that receives the locale selection, saves it to the database for the logged-in user, and updates the current session's locale:
@Controller public class LocalePreferenceController { private static final Logger logger = LogManager.getLogger(LocalePreferenceController.class); @Autowired private UserService userService; @Autowired private LocaleResolver localeResolver; @PostMapping("/save-user-locale") @ResponseBody public ResponseEntity<Void> saveUserLocale( @RequestParam("locale") String localeTag, Authentication authentication, HttpServletRequest request, HttpServletResponse response) { // Only save if user is logged in if (authentication == null || authentication.getPrincipal() == null) { return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build(); } String username = (String) authentication.getPrincipal(); try { // Save locale to database via your UserService userService.saveUserPreferredLocale(username, localeTag); // Update the current session's locale immediately Locale userLocale = Locale.forLanguageTag(localeTag); localeResolver.setLocale(request, response, userLocale); logger.debug("Saved locale {} for user {}", localeTag, username); return ResponseEntity.ok().build(); } catch (Exception e) { logger.error("Failed to save locale for user {}", username, e); return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build(); } } }
3. Add Save Logic to UserService
Update your UserService to include the method that persists the locale to the database:
@Service("UserService") public class UserService { // ... existing methods and dependencies ... public void saveUserPreferredLocale(String username, String localeTag) { // Fetch the user from your repository User user = userRepository.findByUsername(username); if (user != null) { user.setPreferredLocale(localeTag); // Ensure your User entity has this field userRepository.save(user); } } // Your existing getUsersPreferedLocaleOption method remains unchanged }
4. Update Security Configuration
Make sure your SecurityConfig allows authenticated users to access the new endpoint. Add this line to your authorizeRequests block:
.antMatchers("/save-user-locale").authenticated()
5. Verify Your User Entity & Database
Ensure your User entity has a preferredLocale field (e.g., String preferredLocale;) and your MySQL table has a corresponding column (like VARCHAR(20) to store tags like en-GB or zh).
How It Works
- When a logged-in user selects a language, the JS sends a POST request to
/save-user-locale - The controller saves the locale to the database and updates the current session's locale
- On subsequent logins, your existing
CustomAuthenticationSuccessHandlerloads the saved locale from the database and applies it - For unauthenticated users, the fallback logic still applies the locale to their current session without saving
内容的提问来源于stack exchange,提问作者karen

