Spring MVC,JsonSerializer和i18n

时间:2013-01-29 19:22:47

标签: spring-mvc internationalization jackson

我正在使用自定义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访问序列化程序中的弹簧“MessageSource”类,但由于这个类没有被Spring实例化,我不能这样做,我也不能注入它。 请你能给出一些提示,或者更好,更简单的方法吗?

提前谢谢。

2 个答案:

答案 0 :(得分:1)

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

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

答案 1 :(得分:1)

您可以使用SerializerProvider中的getLocale()Methode