【问题标题】:Spring MVC, JsonSerializer and i18nSpring MVC、JsonSerializer 和 i18n
【发布时间】:2013-01-29 19:22:47
【问题描述】:

我正在使用自定义 JsonSerializer 来生成 Spring MVC 方法的 JSON 响应。 响应中的字段之一是枚举,我想返回其值的本地化描述,而不是返回 toString() 的值,因为我还返回了枚举的一些属性。这是枚举代码的一部分:

public enum BalanceType {
    EXTERNAL_SOURCE(BalanceCurrency.EURO),
    EXTERNAL_DESTINATION(BalanceCurrency.EURO),
    MONEY_ACCOUNT(BalanceCurrency.EURO),
    CREDIT_ACCOUNT(BalanceCurrency.CREDIT);

    private BalanceCurrency currency;

    private BalanceType(BalanceCurrency currency) {
        this.currency = currency;
    }

    public BalanceCurrency getCurrency() {
        return currency;
    }
}

我正在使用这个自定义序列化程序:

public class BalanceTypeSerializer extends JsonSerializer<BalanceType> {

    @Override
    public void serialize(BalanceType balanceType, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException, JsonProcessingException {
        jsonGenerator.writeStartObject();
        jsonGenerator.writeStringField("value", balanceType.toString());
        jsonGenerator.writeStringField("currency", balanceType.getCurrency().toString());
        jsonGenerator.writeEndObject();
    }
}

这是用作 Spring MVC 方法的返回值(在列表中)的(简化的)类:

public class Balance {
    private ObjectId id;
    private ObjectId userId;
    @JsonSerialize(using = BalanceTypeSerializer.class)
    private BalanceType type;
    private double balance;
    private Date lastUpdated;

    // getters and setters
}

这是Spring MVC方法本身的简化代码:

@RequestMapping(value = "api/balance", method = RequestMethod.GET)
@ResponseBody
public List<Balance> getBalanceJSON(@ModelAttribute("userId") ObjectId userId, Locale locale){
    List<Balance> balanceList = balanceRepo.findByUserId(userId);
    return balanceList;
}

在这个方法中,我有 spring 提供的语言环境,但是我怎样才能把这个语言环境传递给序列化器对象呢? 另外,我想通过实现MessageSourceAware来访问序列化程序中的spring“MessageSource”类,但是由于这个类不是由Spring实例化的,所以我不能这样做,我也不能注入它. 请问,您能否提供一些提示或更好、更简单的方法来执行此操作?

提前谢谢你。

【问题讨论】:

  • 没有办法将MessageSource 或Locale 注入到序列化程序中,因为它们不是由spring 管理的。

标签: spring-mvc internationalization jackson


【解决方案1】:

在这种情况下,我可以想出几种方法来处理这个问题。一种解决方案是为您的 Balance 类创建一个包装类,该类还接受一个 Locale 对象,然后您将为其创建一个自定义序列化程序。然后,您可以手动序列化可访问Locale 的字段。不过,这需要大量的手动工作,所以我通常不会建议这种解决方案。

另一种传递上下文数据的方法是通过上下文服务 - 在这种情况下,Locale 实例是您的上下文数据。例如,如果您有一个 Spring 托管 bean 可以保存当前 Web 请求的 Locale,或者有一个 ThreadContext 变量可以保存 Locale。 Spring 为Spring MVC 构建了一些帮助类来执行此操作。您也可以考虑直接使用LocaleContextHolder,具体取决于您如何确定Locale。我认为这些类中的大多数都使用静态方法,因此您也可以在非 Spring 托管 bean 中使用。

【讨论】:

  • 我觉得你的第二个建议更好
  • 是的,我同意。第二种方法将是更好的方法。由于我在控制器中有当前的请求语言环境,我认为这是实现帮助枚举字段转换的辅助方法的正确位置。感谢您的帮助。
  • 无论如何,感谢您提出选项 1。经过深思熟虑后,我决定在我的项目中,在序列化之前明确并转换为LocalizedEntity 比依赖正确设置的全局状态更好。
【解决方案2】:

您可以使用来自 SerializerProvider 的 getLocale() 方法

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-03-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-18
    • 1970-01-01
    相关资源
    最近更新 更多