写在前面: 低头走路,更应抬头看路
为什么写这个
Spring作为Web层框架的经典框架,已经走过了十几年了。在项目过程中使用的点滴,如不整理便容易流于琐碎,不成系统。而单纯学习某个知识点不运用到项目之中变不深刻。近期打算把最近几个月做的项目整理一下,以作梳理和总结。这里主要记录下在项目中使用的国际化操作,因为要在系统支持中英文,所以可以使用国际化来对操作的日志信息进行记录,并做可视化以被查验。
怎么做
使用Spring的支持国际化bean
①org.springframework.context.support.ReloadableResourceBundleMessageSource(每次加载)
②org.springframework.context.support.ResourceBundleMessageSource(加载一次)
这里就直接写在项目中的配置方式:
<bean id="applicationContextUtil" class="com.jzvasp.common.utils.ApplicationContextUtil"/>
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basenames">
<list>
<value>com.jzvasp.common.log.global.logGlobalResource</value>
</list>
</property>
</bean>
上面的是多个国际化文件的配置,用list
如果是单文件的话,如下设置:
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basename">
<value>com.jzvasp.common.log.global.logGlobalResource</value>
</property>
</bean>
国际化资源文件:
我们在com.jzvasp.common.log.global包下建两个文件:
①logGlobalResource_en_US.properties US资源
exportHeat = user “{0}” export heat statistics “{1}”
sumExportRating = export Rating Statistics Excel
②logGlobalResource_zh_CN.properties 中文资源
exportHeat = 用户 “{0}” 导出热度统计 “{1}”
sumExportRating = 导出收视率统计Excel
ApplicationContext
在使用中,为了拿到messageSource对象,我们需要先获得ApplicationContext对象,可以通过它的方法:
Object org.springframework.beans.factory.BeanFactory.getBean(String key)获取。
自定义ApplicationContextUtil.java
public class ApplicationContextUtil implements ApplicationContextAware {
private static ApplicationContext context;
@Override
public void setApplicationContext(ApplicationContext context)throws BeansException {
ApplicationContextUtil.context = context;
}
public static ApplicationContext getContext() {
return context;
}
public static ApplicationContext getApplicationContext() {
return context;
}
public static void setContext(ApplicationContext context) {
ApplicationContextUtil.context = context;
}
public static Object getBean(String key){
return context.getBean(key);
}
}
自定义添加log的参数:
public class AddLogParam {
private String key; //国际化日志文件的key
private String key1; //子key,非必要
private Object[] param; //key值里面可能要的参数,没有参数就为null
private String state; //操作状态,暂时1表示成功,0表示失败
private String username; //操作者名
public AddLogParam(){}
public AddLogParam(String key, Object[] param, String state) {
super();
this.key = key;
this.param = param;
this.state = state;
}
public AddLogParam(String key, Object[] param, String state, String username) {
super();
this.key = key;
this.param = param;
this.state = state;
this.username = username;
}
public AddLogParam(String key, String key1, Object[] param, String state, String username) {
super();
this.key = key;
this.key1 = key1;
this.param = param;
this.state = state;
this.username = username;
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public String getKey1() {
return key1;
}
public void setKey1(String key1) {
this.key1 = key1;
}
public Object[] getParam() {
return param;
}
public void setParam(Object[] param) {
this.param = param;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
}
封装LogService如下:
public boolean addLog(AddLogParam param, HttpServletRequest request) {
if(param != null){
String language = "zh_CN";
Cookie myCookie[]=request.getCookies();//创建一个Cookie对象数组
if(null!=myCookie && myCookie.length>0){
for(int i=0;i<myCookie.length;i++){
Cookie newCookie= myCookie[i];
if(newCookie.getName().equals("jzad_language")){
language = newCookie.getValue();
break;
}
}
}
//从cookie中取出当前语言后,获取对应的国际化日志数据,getParam()数组的元素会赋值给国际化文件中的{0}等通配符
String content = getMessage(param.getKey(), param.getParam(), language);
String summary = getMessage(param.getKey1(), param.getParam(), language);
LogBean log = new LogBean();
log.setOperateContent(content);
log.setSummary(summary);
log.setState(param.getState());
log.setUserName(param.getUsername());
Date date = new Date();
log.setAddTime(CommonsUtil.changeDateToString(date, CommonsUtil.DEFAULT_DATETIME_FORMAT));
logDao.save(log);//将日志数据存到数据库中
return true;
}
return false;
}
private static String getMessage(String key, Object[] params, String local) {
MessageSource messageSource = (MessageSource) ApplicationContextUtil.getBean("messageSource");
Locale cal = null;
if ("zh_CN".equals(local)) {
cal = Locale.CHINA;
}
if ("zh_TW".equals(local)) {
cal = Locale.TAIWAN;
}
if ("en_US".equals(local)) {
cal = Locale.US;
}
String msg = messageSource.getMessage(key, params, cal);
return msg;
}
测试
在Action中如下使用即可:
UserJson user = (UserJson) session.get("user");
AddLogParam logparam = new AddLogParam("exportHeat", "sumExportRating",
new Object[] { user.getUserName(), "" }, "2", user.getUserName());
这里将国际化文件中的Key以及参数传递到Service层,然后通过getMessage获取完整信息并保存到数据库中。
结图:
如果本地测试,可以直接使用下面这种方式:
context = new ClassPathXmlApplicationContext(
new String[] { "spring.xml" });
System.out.println(context.getMessage("exportHeat", new Object[]{"admin", ""}, Locale.US));
//user "admin" export heat statistics ""
结束
虽然只是一个很小的点,记录一下,以便后面用到的时候查看。