При запросе одного com.codahale.metrics.Meter
через Jersey-REST-Service Джексон работает нормально и сериализует Измеритель (форматирование выполнено мной)
{
"count":0,
"fiveMinuteRate":0.0,
"fifteenMinuteRate":0.0,
"oneMinuteRate":0.0,
"meanRate":0.0
}
При запросе того же Измерителя, содержащегося внутриMap<String, Metric>
, Джексон жалуется:
Не найден сериализатор для класса com.codahale.metrics.Meter и не обнаружены свойства для создания BeanSerializer (во избежание исключения отключите SerializationFeature.FAIL_ON_EMPTY_BEANS)) (через цепочку ссылок: java.util.HashMap ["testMetric"])
Я мог бы просто заставить свой метод ресурсов возвращать строку, которую ObjectMapper
может создать (см. ниже), но я бы хотелчтобы мой метод возвращал Map<String, Metric>
.
Почему Джексон не может понять это самостоятельно?Как я могу заставить Джексона понять, что он знает, как сериализовать Объект?Как я могу проверить конфигурацию ObjectMapper, используемой Джерси?
Я проверил, что Карта не пуста и что Meter
находится там точно.
Когда я создаю ваниль ObjectMapper
и сериализовать карту
ObjectMapper mapper = new ObjectMapper();
mapper.writeValueAsString( myMetricMap );
, она работает просто отлично:
{
"testMetric":
{
"count":0,
"fiveMinuteRate":0.0,
"fifteenMinuteRate":0.0,
"oneMinuteRate":0.0,
"meanRate":0.0
}
}
dropwizard-metrics
предоставляет пакет metrics-json
, который включает в себя сериализаторы для метрик и проверок работоспособности.К сожалению, из-за беспорядка зависимостей я не могу его использовать.
РЕДАКТИРОВАТЬ: Как было предложено в комментариях, я попытался сериализовать Map<String, Meter>
- и это сработало!
Подводя итог:
public interface Metric {
// Empty Marker Interface
}
public class Meter implements Metric {
...
}
@Path("/")
@Produces( MediaType.APPLICATION_JSON )
public MetricsResource {
@GET
@Path("metric/{metricName}")
public Metric getMetric( @PathParam String metricName ) {
// Works!
return MetricsService.getMetric( metricName );
}
@GET
@Path("metricsAsString")
public String getMetricsAsString()
{
// Works!
return (new ObjectMapper()).writeValueAsString(
MetricsService.getMetrics());
}
@GET
@Path("meters")
public Map<String, Meter> getMeters()
{
// Works!
return MetricsService.getMeters();
}
@GET
@Path("metrics")
public Map<String, Metric> getMetrics()
{
// Fails!
return metricsService.getMetrics();
}
Я полагаю, что Джексон не определяет конкретный тип при неявной сериализации, но пытается сериализовать на основе (маркер) интерфейса Metric
.