【问题标题】:Configure Jackson for Google App Engine为 Google App Engine 配置 Jackson
【发布时间】:2017-07-08 17:48:01
【问题描述】:

有什么方法可以配置用于序列化 servlet 响应的 Jackson (ConfiguredObjectMapper)?

@Api(name = "rates",
        version = "v1",
        title = "Rates API")
public class RatesApi {
    static Logger LOG = Logger.getLogger(RatesApi.class.getSimpleName());

    @ApiMethod(name = "getLatestRates",
            path = "latest",
            httpMethod = HttpMethod.GET)
    public RatesEnvelope getLatestRates(@Named("base") String base) throws BadRequestException,
            InternalServerErrorException {

        try {
            RatesInfo ratesInfo = DatabaseUtils.getLatestRates(base);
            return new RatesEnvelope(ratesInfo.getDate(), base, ratesInfo.getTimestamp(), ratesInfo.getRates());
        } catch (IllegalArgumentException e) {
            throw new BadRequestException(e.getMessage());
        } catch (com.googlecode.objectify.NotFoundException e) {
            throw new InternalServerErrorException("no available rates");
        }
    }
}

我的问题是 RatesEnvelope 类包含 BigDecimal 字段,应使用 mapper.enable(SerializationFeature.WRITE_BIGDECIMAL_AS_PLAIN); 配置以避免 E 表示法。

web.xml

<?xml version="1.0" encoding="utf-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee" version="2.5">
    <servlet>
        <servlet-name>CurrencyWebserviceServlet</servlet-name>
        <servlet-class>PACKAGE_NAME.backend.servlet.OpenExchangeRatesWebserviceServlet</servlet-class>
        <load-on-startup>0</load-on-startup>
    </servlet>

    <servlet>
        <servlet-name>SystemServiceServlet</servlet-name>
        <servlet-class>com.google.api.server.spi.SystemServiceServlet</servlet-class>
        <init-param>
            <param-name>services</param-name>
            <param-value>PACKAGE_NAME.backend.spi.RatesApi</param-value>
        </init-param>
    </servlet>

    <servlet-mapping>
        <servlet-name>CurrencyWebserviceServlet</servlet-name>
        <url-pattern>/cron/fetchlatest</url-pattern>
    </servlet-mapping>

    <servlet-mapping>
        <servlet-name>SystemServiceServlet</servlet-name>
        <url-pattern>/_ah/spi/*</url-pattern>
    </servlet-mapping>

    <welcome-file-list>
        <welcome-file>index.html</welcome-file>
    </welcome-file-list>

    <security-constraint>
        <web-resource-collection>
            <web-resource-name>all</web-resource-name>
            <url-pattern>/*</url-pattern>
        </web-resource-collection>
        <user-data-constraint>
            <transport-guarantee>CONFIDENTIAL</transport-guarantee>
        </user-data-constraint>
    </security-constraint>

    <filter>
        <filter-name>ObjectifyFilter</filter-name>
        <filter-class>com.googlecode.objectify.ObjectifyFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>ObjectifyFilter</filter-name>
        <url-pattern>/*</url-pattern>
        <!-- Next three lines are for request dispatcher actions -->
        <dispatcher>REQUEST</dispatcher>
        <dispatcher>INCLUDE</dispatcher>
        <dispatcher>FORWARD</dispatcher>
    </filter-mapping>
</web-app>

【问题讨论】:

    标签: java json google-app-engine jackson


    【解决方案1】:

    创建 Jackson ObjectMapper 的一个实例。通过启用或禁用您需要的功能根据需要进行配置。修改您的 Spring 配置以使用它而不是默认配置。 Java 配置看起来像这样:

    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        final MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
        final ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.enable(SerializationFeature.WRITE_BIGDECIMAL_AS_PLAIN);
        converter.setObjectMapper(objectMapper);
        converters.add(converter);
        super.configureMessageConverters(converters);
    }
    

    【讨论】:

    • 在哪里配置 Spring?我使用 Google App Engine,我的项目中没有任何与 Spring 相关的内容。
    • 在这种情况下,您可能会使用如下所示的 Guice 模块来创建/配置对象实例:public class MyModule implements Module{ @Override public void configure(Binder binder) { //all your object bindings } @Provides ObjectMapper providesObjectMapper(){ ObjectMapper objectMapper = new ObjectMapper(); objectMapper.enable(SerializationFeature.WRITE_BIGDECIMAL_AS_PLAIN); return objectMapper; }
    • 如果我不使用 Guice 怎么办?我想知道 - 有没有简单的方法来配置杰克逊?比如编辑 config.xml 等。
    • 我认为不会有任何只适合杰克逊的。你能分享你的web.xml吗?我怀疑你使用谷歌云端点,在这种情况下这篇文章可能会有所帮助stackoverflow.com/questions/17128714/…
    • 是的,我使用 Google Cloud Endpoints。将 web.xml 添加到问题中。
    【解决方案2】:

    您使用的似乎是Cloud Endpoints Frameworks,它不使用 Jackson 注释。在您的情况下,您将使用 ApiTransformer 来实现您想要的。举个例子:

    @ApiTransformer(RatesEnvelopeTransformer.class)
    public class RatesEnvelope {
        private BigDecimal someBigDecimalField;
        // ...
    }
    
    public class RatesEnvelopeTransformer implements Transformer<BigDecimal, String> {
        public String transformTo(BigDecimal in) {
            return in.toPlainString();
        }
    
        public BigDecimal transformFrom(String in) {
            return new BigDecimal(in);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2015-12-08
      • 1970-01-01
      • 2016-02-05
      • 2012-11-19
      • 1970-01-01
      • 2014-11-14
      • 1970-01-01
      • 2021-09-12
      • 2015-02-10
      相关资源
      最近更新 更多