springboot实现国际化

1. 需求:

通过请求头中指定的属性例如lang指定本次请求需要响应数据的语言

2. 解决方案

1. 创建国际化资源

1. 使用idea创建资源组

 

 2. 将不同语言的数据写入对应的文件,保证key相同

messages_en_US.properties

000000=operation success

messages_zh_CN.properties

000000=操作成功

 2. 编写配置

1. application.yml 增加国际化目录配置

spring:
  messages:
    #指定国际化资源文件资源组
    basename: i18n/messages

 2. 增加配置类 从请求头获取多语言关键字

package com.fkp.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.LocaleResolver;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Locale;

@Configuration
public class I18nConfiguration {

    @Bean
    public LocaleResolver localeResolver(){
        return new I18nLocaleResolver();
    }

    static class I18nLocaleResolver implements LocaleResolver{

        @Override
        public Locale resolveLocale(HttpServletRequest request) {
            String lang = request.getHeader("lang");
            Locale locale = Locale.getDefault();
            if("zh_CN".equals(lang)){
                locale = Locale.SIMPLIFIED_CHINESE;
            }else if("en_US".equals(lang)){
                locale = Locale.US;
            }
            return locale;
        }

        @Override
        public void setLocale(HttpServletRequest request, HttpServletResponse response, Locale locale) {

        }
    }
}

 3. 使用国际化

1. 定义国际化工具类 I18nUtils

package com.fkp.util;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.context.NoSuchMessageException;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.stereotype.Component;

@Component
public class I18nUtils {

    @Autowired
    private MessageSource messageSource;

    public String getMessage(String key){
        String langMessage = key;
        try {
         langMessage = messageSource.getMessage(key, new Object[]{}, LocaleContextHolder.getLocale());
        }catch (NoSuchMessageException e){
            e.printStackTrace();
        }catch (Exception e){
            e.printStackTrace();
            langMessage = "i18n inner error!";
        }
        return langMessage;
    }

}

2. 定义统一的返回对象 RestResponse

package com.fkp.param;

import com.fkp.util.I18nUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.Serializable;

@Component
public class RestResponse<T> implements Serializable {
    private static final long serialVersionUID = 2621638727631497840L;
    private String code;
    private String status;
    private String msg;
    private T data;
    private static final String CODE_SUCCESS = "000000";
    private static final String STATUS_SUCCESS = "success";
    private static final String STATUS_FAIL = "fail";

    private static I18nUtils i18nUtils;

    @Autowired
    private void setI18nUtils(I18nUtils i18nUtils){
        RestResponse.i18nUtils = i18nUtils;
    }

    public RestResponse() {
    }

    public RestResponse(String code, String status, String msg) {
        this.code = code;
        this.status = status;
        this.msg = i18nUtils.getMessage(msg);
    }

    public RestResponse(String code, String status, String msg, T data) {
        this.code = code;
        this.status = status;
        this.msg = i18nUtils.getMessage(msg);
        this.data = data;
    }

    public static <T> RestResponse<T> success(){
        RestResponse<T> res = new RestResponse<>();
        res.setCode(CODE_SUCCESS);
        res.setStatus(STATUS_SUCCESS);
        res.setMsg(i18nUtils.getMessage(CODE_SUCCESS));
        return res;
    }

    public static <T> RestResponse<T> success(String msg){
        RestResponse<T> res = new RestResponse<>();
        res.setCode(CODE_SUCCESS);
        res.setStatus(STATUS_SUCCESS);
        res.setMsg(i18nUtils.getMessage(msg));
        return res;
    }

    public static <T> RestResponse<T> success(T data){
        RestResponse<T> res = new RestResponse<>();
        res.setCode(CODE_SUCCESS);
        res.setStatus(STATUS_SUCCESS);
        res.setMsg(i18nUtils.getMessage(CODE_SUCCESS));
        res.setData(data);
        return res;
    }

    public static <T> RestResponse<T> success(String msg, T data){
        RestResponse<T> res = new RestResponse<>();
        res.setCode(CODE_SUCCESS);
        res.setStatus(STATUS_SUCCESS);
        res.setMsg(i18nUtils.getMessage(msg));
        res.setData(data);
        return res;
    }

    public static <T> RestResponse<T> fail(String code){
        RestResponse<T> res = new RestResponse<>();
        res.setCode(code);
        res.setStatus(STATUS_FAIL);
        res.setMsg(i18nUtils.getMessage(code));
        return res;
    }

    public static <T> RestResponse<T> fail(String code, String msg){
        RestResponse<T> res = new RestResponse<>();
        res.setCode(code);
        res.setStatus(STATUS_FAIL);
        res.setMsg(i18nUtils.getMessage(msg));
        return res;
    }

    public static <T> RestResponse<T> fail(String code, T data){
        RestResponse<T> res = new RestResponse<>();
        res.setCode(code);
        res.setStatus(STATUS_FAIL);
        res.setMsg(i18nUtils.getMessage(code));
        res.setData(data);
        return res;
    }

    public static <T> RestResponse<T> fail(String code, String msg, T data){
        RestResponse<T> res = new RestResponse<>();
        res.setCode(code);
        res.setStatus(STATUS_FAIL);
        res.setMsg(i18nUtils.getMessage(msg));
        res.setData(data);
        return res;
    }

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public String getStatus() {
        return status;
    }

    public void setStatus(String status) {
        this.status = status;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }
}

3. 定义Controller用来测试

package com.fkp.controller;

import com.fkp.param.RestResponse;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping(value = "/i18n")
public class I18nController {

    @RequestMapping(value = "/test", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
    public RestResponse<User> test(@RequestParam("name") String name){
        User user = new User();
        user.setName(name);
        return RestResponse.success(user);
    }

    static class User{
        private String name;

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }
    }
}

 4. 测试

1. 请求头lang为en_US

 2. 请求头lang为zh_CN

3.备注

1.当new对象时,该对象中普通注入的对象无法注入,需要使用静态注入,静态注入方式可使用set方法注入,若对象中的属性想要普通注入则该对象必须要以注入的方式创建,不可new.

在定义RestResponse时需要使用I18nUtils,为了保证其既可以使用new对象的方式使用也可以使用静态方法的方式使用,因此i18n对象需要静态注入,前提保证RestResponse对象使用@Component注解标注即让Spring容器管理。

    private static I18nUtils i18nUtils;

    @Autowired
    private void setI18nUtils(I18nUtils i18nUtils){
        RestResponse.i18nUtils = i18nUtils;
    }

4. 改进

1. 通过在I18nUtils类中直接注入静态的MessageSource对象,将getMessage方法定义为静态方法,则在RestResponse类中不需要注入静态的I8nUtils对象直接调用其静态方法即可,则RestResponse类也无需交由Spring容器管理。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值