Spring boot 定位来自 RestController 的每个响应参数



我正在尝试本地化项目中每个API响应中的几乎每个参数。

我已经发现我们可以在春季启动中做这样的事情:

MessageSourceAccessor accessor = new MessageSourceAccessor(messageSource, locale);
return accessor.getMessage(code);

并将代码与本地化消息映射保留在messages_en.propertiesmessages_fr.properties等中。

但是对于我的应用程序,我特别有两个要求:

  • 我想将此逻辑与我的业务逻辑分开,即我不想在每个控制器中编写本地化逻辑。
  • 我想在通过
  • 服务器的所有响应的每个响应参数上尝试它,也许在杰克逊将对象转换为字符串或转换为 JSON 后。

在 Spring 启动中是否有办法实现这一点,或者是否有任何可用的库?

我已经找到了解决方案。我没有对字段使用 String,而是使用自定义类,例如 LocalizedText

import lombok.AllArgsConstructor;
import lombok.Data;
@Data
@AllArgsConstructor
public class LocalizedText {
    private String text;
}

对于序列化,我创建了一个 反序列化程序 LocalizedTextSerailizer ,如下所示:

import java.io.IOException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
@Component
 public class LocalizedTextSerializer extends StdSerializer<LocalizedText> {
     private static final long serialVersionUID = 619043384446863988L;
    @Autowired
    I18nUtil messages;
    public LocalizedTextSerializer() {
        super(LocalizedText.class);
    }
    public LocalizedTextSerializer(Class<LocalizedText> t) {
        super(t);
    }
    @Override
    public void serialize(LocalizedText value, JsonGenerator gen, SerializerProvider provider) throws IOException {
        gen.writeString(messages.get(value.getText()));
    }
}

I18nUtil

import java.util.Locale;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.context.NoSuchMessageException;
import org.springframework.context.support.MessageSourceAccessor;
import org.springframework.stereotype.Component;
import lombok.extern.slf4j.Slf4j;
@Component
@Slf4j
public class I18nUtil {
    @Autowired
    private MessageSource messageSource;
    public String get(String code) {
        try {
            MessageSourceAccessor accessor = new MessageSourceAccessor(messageSource, Locale.getDefault());
            return accessor.getMessage(code);
        } catch (NoSuchMessageException nsme) {
            log.info("Message not found in localization: " + code);
            return code;
        }
    }
}

这几乎可以达到目的,我不必弄乱业务逻辑,我可以本地化应用程序中任何响应的任何参数。

注意:

  1. 在这里,I18nUtil 返回相同的代码,如果它在 message.properties 中找不到任何消息。
  2. 默认区域设置在 I18nUtil 中使用,用于演示。