springboot国际化与乱码处理

spring boot 国际化与乱码处理

1,maven依赖:

1.1 参数校验的依赖包

		
		<dependency>
			<groupId>javax.validationgroupId>
			<artifactId>validation-apiartifactId>
		dependency>
		
		<dependency>
			<groupId>org.hibernategroupId>
			<artifactId>hibernate-validatorartifactId>
			<version>5.1.0.Finalversion>
		dependency>

2,相关配置

2.1 spring校验参数配置

2.1.1 配置说明:

messageSource.setDefaultEncoding(“UTF-8”) :设置配置文件的编码
messageSource.setBasename(“i18n/message”) :指定国际化配置文件的目录与文件标识头;
i18n :表示国际化文件目录,位于classpath路径下;
message :表示国际化文件标识符,即国际化的文件必须以message开头,用于区分默认文件,中文、英文等;

message标识符示例:
message.properties : 默认文件 ,一般为中文提示
message_zh_CN.properties : 中文提示文件
message_en_US.peoperties : 英文提示文件
@Configuration
public class WebConfig {
	public MessageSource messageSource() {
		ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
		messageSource.setDefaultEncoding("UTF-8");
		messageSource.setCacheSeconds(0);
		messageSource.setBasename("i18n/message");
		return messageSource;
	}

	/**
	 * 自定义国际化文件存放路径
	 * 
	 * @return
	 */
	@Bean
	public Validator validator() {
		LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean();
		validator.setValidationMessageSource(messageSource());
		return validator;
	}
}
2.1.2 自定义国际化处理类

示例说明:示例文件将涉及到两个对象:BeanUtil与RedisUtil,BeanUtil工具将在示例之后附上源码,而RedisUtil工具则需要配置与添加其依赖;
示例:

package com.huwei.filter;

import java.util.Locale;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

import javax.servlet.http.HttpServletRequest;  
import javax.servlet.http.HttpServletResponse;  
import javax.servlet.http.HttpSession;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.LocaleResolver;

import com.huwei.util.BeanUtil;
import com.huwei.util.RedisUtil;  
  
/** 
 * 自定义国际化语言解析器 
 */
@Component
public class MyLocaleResolver implements LocaleResolver{  
      
    private static final String I18N_LANGUAGE = "i18n_language";  
    private static final String I18N_LANGUAGE_SESSION = "i18n_language_session";  
  
    @Autowired
    private RedisUtil redisUtil;
    
    @Override  
    public Locale resolveLocale(HttpServletRequest req) {  
        String i18n_language = req.getParameter(I18N_LANGUAGE);  
        Locale locale = Locale.getDefault();  
        if(Objects.nonNull(i18n_language)) {  
            String[] language = i18n_language.split("_");  
            locale = new Locale(language[0], language[1]);  
              
            //将国际化语言保存到session  
//            HttpSession session = req.getSession();  
//            session.setAttribute(I18N_LANGUAGE_SESSION, locale);
            
            //分布式系统建议换成到redis,避免多服务之间信息不同步问题;
            HttpSession session = req.getSession();
            String localeJsonString = BeanUtil.toJson(locale);
            redisUtil.opsForString().set((session.getId() + "#" + I18N_LANGUAGE_SESSION), localeJsonString,
            		15, TimeUnit.MINUTES);
            
        }else {  
            //如果没有带国际化参数,则判断session有没有保存,有保存,则使用保存的,也就是之前设置的,避免之后的请求不带国际化参数造成语言显示不对  
//            HttpSession session = req.getSession();  
//            Locale localeInSession = (Locale) session.getAttribute(I18N_LANGUAGE_SESSION);
//            if(localeInSession != null) {  
//                locale = localeInSession;  
//            }  
            
           //分布式系统建议换成到redis,避免多服务之间信息不同步问题;
           HttpSession session = req.getSession();  
           String localeJson = (String) redisUtil.opsForString().get(session.getId() + "#" + I18N_LANGUAGE_SESSION);
           Locale localeInRedis = BeanUtil.toBean(localeJson, Locale.class);
           if(Objects.isNull(localeInRedis)) {
        	   locale = localeInRedis;
           }
        }  
        return locale;  
    }  
  
    @Override  
    public void setLocale(HttpServletRequest req, HttpServletResponse res, Locale locale) {  
          
    }  
  
}  

BeanUtil工具示例:
依赖jar: gson

package com.huwei.util;

import java.io.UnsupportedEncodingException;
import java.lang.reflect.Field;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

import lombok.extern.slf4j.Slf4j;


/**
 * bean util
 * @author huwei
 */
@Slf4j
public class BeanUtil {
	
	static private Gson gson = new GsonBuilder().disableHtmlEscaping().create(); 
	
	static public Map<String ,Object> toMap(Object obj){
		return toMap(obj, null);
	}
	
	static public Map<String ,Object> toMap(String key ,Object obj){
		Map<String ,Object> empty = new HashMap<String, Object>();
		empty.put(key, obj);
		return empty;
	}
	
	static public Map<String ,Object> toMap(Object obj ,String ...excludeFields){
		Map<String ,Object> empty = new HashMap<String, Object>();
		
		if(Objects.isNull(obj)) {
			return empty;
		}
		
		return beanToMap(obj ,excludeFields);
	}
	
	/**
	 *  将 target目标的feild属性值赋值给original对象;
	 * @param original
	 * @param target
	 * @return
	 */
	static public <T> T addFeildValueInOrginal(T original ,T target) {
		if(Objects.isNull(original) || Objects.isNull(target) || !original.getClass().equals(target.getClass())) {
			return original;
		}
		
		return addFeildValueInOrginal0(original, target);
	}
	
	/**
	 * 将给定的对象转换为json字符串,转换失败返回null
	 * @param obj
	 * @return
	 */
	static public String toJson(Object obj) {
		try {
			return gson.toJson(obj);
		} catch (Exception e) {
			log.warn("---- > switch object to json string is failed ,and that object is : " + obj.toString() ,e);
		}
		return  null;
	}
	
	/**
	 * 将给定的json字符串转换为给定的class对象,失败返回null
	 * @param json
	 * @param cls
	 * @return
	 */
	static public <T> T toBean(String json ,Class<? extends T> cls) {
		try {
			return gson.fromJson(json, cls);
		} catch (Exception e) {
			log.warn("---- > switch json string to bean is failed ,and that object class is : " + cls + " ,and that json string is : " + json,e);
		}
		return null;
	}
	
	static public <T> T toBean(byte[] json ,Class<? extends T> cls) {
		return toBean(new String(json), cls);
	}
	
	static public <T> T toBean(byte[] json ,Charset charset ,Class<? extends T> cls) {
		try {
			return toBean(new String(json ,charset.name()), cls);
		} catch (UnsupportedEncodingException e) {
			log.warn("---- > switch json string to bean is failed ,and that object class is : " + cls + " ,and that json string is : " + json
					+ " ;cause is is no given character : " + charset,e);
			return null;
		}
	}

	static private <T> T addFeildValueInOrginal0(T original, T target) {
		Field[] originalFields = getDeclaredFields(original);
		Map<String ,Object> targetFields = beanToMap(target, null);
		
		if(Objects.isNull(originalFields)) {
			return original;
		}
		
		for(int i = 0 ,len = originalFields.length ;i < len ;++i) {
			Field f = originalFields[i];
			f.setAccessible(true);
			Object originalValue = null;
			try {
				originalValue = f.get(original);
			} catch (IllegalArgumentException e) {
			} catch (IllegalAccessException e) {
			}
			
			if(!Objects.isNull(originalValue)) {
				continue;
			}
			
			String name = f.getName();
			try {
				f.set(original, targetFields.get(name));
			} catch (IllegalArgumentException | IllegalAccessException e) {
				// 
			}
		}
		return original;
	}

	private static Field[] getDeclaredFields(Object original) {
		return original.getClass().getDeclaredFields();
	}

	private static Map<String, Object> beanToMap(Object obj, String[] excludeFields) {
		Map<String ,Object> result = new HashMap<String, Object>();
		
		Class<?> cls = obj.getClass();
		Field[] fields = cls.getDeclaredFields();
		
		if(Objects.isNull(fields) || fields.length == 0) {
			return result;
		}
		
		for(int i = 0 ,len = fields.length ;i < len ;++i) {
			Field field = fields[i];
			//打开私有访问
            field.setAccessible(true);
            //获取属性
            String name = field.getName();
            
            //排除属性
            if(valueInArrays(name ,excludeFields)) {
            	continue;
            }
            //获取属性值
            Object value = null;
            try {
				value = field.get(obj);
			} catch (IllegalArgumentException e) {
			} catch (IllegalAccessException e) {
			}
            
            result.put(name, value);
		}
		return result;
	}

	private static boolean valueInArrays(String name, String[] excludeFields) {
		if(Objects.isNull(name) || Objects.isNull(excludeFields) || excludeFields.length == 0) {
			return false;
		}
		
		for(int i = 0 ,len = excludeFields.length ;i < len ;++i) {
			if(name.equals(excludeFields[i])) {
				return true;
			}
		}
		
		return false;
	}

	public static byte[] toJsonAsBytes(Object obj) {
		String json = toJson(obj);
		return Objects.isNull(json) ? new byte[0] : json.getBytes();
	}
	
}

2.2 设置开发工具properties编码

2.2.1 eclipse示例:

设置路径:window -> perferences -> general -> content types -> text -> java properties file
示例图片:
springboot国际化与乱码处理_第1张图片

3,使用

3.1 定义参数约束

示例:

package com.huwei.entity;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;

import com.huwei.controller.valid.PasswordValid;
import com.huwei.controller.valid.PhoneValid;
import com.huwei.controller.valid.UsernameValid;

import lombok.Data;

@Data
@Entity
@Table(name="t_user")
public class User {
	@Id
	@GeneratedValue
	private Long id;
	@NotNull(message="{prompt.username.null}" ,groups= {UsernameValid.class})
	private String username;
	@Pattern(regexp="^1([358][0-9]|4[579]|66|7[0135678]|9[89])[0-9]{8}$" ,message="{prompt.phone.format}",groups= {PhoneValid.class})
	private String phone;
	@NotNull(message="{prompt.password.null}" ,groups= {PasswordValid.class})
	private String password;
}

3.2 controller 层使用

示例:

/**
	 * 请求短信验证码
	 * @return
	 */
	@PostMapping(value="/requestCode",produces = {"application/json; charset=UTF-8"})
	public String requestSmsCode(@Validated({PhoneValid.class}) User user ,Errors error ) {
		return authenticationService.requestSmsCode(user.getPhone());
	}

你可能感兴趣的:(spring)