Прерывистая ошибка эталонной цепочки картографа модели Джексона - PullRequest
0 голосов
/ 21 декабря 2018

При использовании Spring Boot Framework я столкнулся со странной проблемой с картографом модели Джексона.Кажется, что у Джексона иногда возникают проблемы с отображением данных JSON в один из моих DTO.Как ни странно, это происходит только в том случае, если конечная точка, имеющая проблемы, НЕ является одной из первых конечных точек, вызываемых при запуске сервера.Вот ошибка:

2018-12-21 11:10:05.012 [http-nio-8080-exec-7] WARN  o.s.w.s.m.s.DefaultHandlerExceptionResolver.handleHttpMessageNotReadable(384) - Failed to read HTTP message: org.springframework.http.converter.HttpMessageNotReadableException: Could not read JSON document: No _valueDeserializer assigned
 at [Source: java.io.PushbackInputStream@22361a02; line: 1, column: 208] (through reference chain: c.r.p.a.d.s.ServiceProviderSubscriptionDTO["advisor"]->c.r.p.a.d.AdvisorDTO["lastModifiedBy"]); nested exception is com.fasterxml.jackson.databind.JsonMappingException: No _valueDeserializer assigned
 at [Source: java.io.PushbackInputStream@22361a02; line: 1, column: 208] (through reference chain: c.r.p.a.d.s.ServiceProviderSubscriptionDTO["advisor"]->c.r.p.a.d.AdvisorDTO["lastModifiedBy"])

Ниже указана конечная точка, которая вызывается при возникновении этой ошибки.Эта ошибка возникает только в том случае, если я позвоню за несколько конечных точек до того, который указан ниже.Если я вызову эту конечную точку первым после запуска сервера, он будет выполнен успешно.

/**
 * POST /subscriptions/subscribe -> Create account subscription.
 *
 * @param serviceProviderSubscriptionDTO the subscription information
 * @return the created subscription object
 */
@RequestMapping(value = "/subscriptions/subscribe", method = RequestMethod.POST)
@Timed
public ResponseEntity<?> subscribe(@RequestBody ServiceProviderSubscriptionDTO serviceProviderSubscriptionDTO) {
    this.logger.error("Service Provider Subscription DTO:      " + ReflectionToStringBuilder.toString(serviceProviderSubscriptionDTO));
    try {
        SubscriptionDTO result = this.service.create(serviceProviderSubscriptionDTO);
        return ResponseEntity.ok().body(result);
    } catch (Exception ex) {
        ex.printStackTrace();
        this.logger.error(ex.getMessage());
    }
    return ResponseEntity.badRequest().body(new ErrorDTO("SUBSCRIPTION_CREATE_FAILED"));
} 

Если я изменяю контроллер для принятия только универсальной карты, а затем использую org.modelmapper.ModelMapper для сопоставления его с ServiceProviderSubscriptionDTO, все работает нормально, независимо от того, когда я вызываю конечную точку.Очевидно, что это не идеальное решение, поскольку я теряю все преимущества аннотации RequestBody в Spring Framework.

/**
 * POST /subscriptions/subscribe -> Create account subscription.
 *
 * @param serviceProviderSubscriptionDTO the subscription information
 * @return the created subscription object
 */
@RequestMapping(value = "/subscriptions/subscribe", method = RequestMethod.POST)
@Timed
public ResponseEntity<?> subscribe(@RequestBody Map<String, Object> serviceProviderSubscriptionDTO) {
    this.logger.error("Service Provider Subscription DTO:      " + ReflectionToStringBuilder.toString(serviceProviderSubscriptionDTO));
    try {
        ServiceProviderSubscriptionDTO converted = this.modelMapper.map(serviceProviderSubscriptionDTO, ServiceProviderSubscriptionDTO.class);
        SubscriptionDTO result = this.service.create(converted);
        return ResponseEntity.ok().body(result);
    } catch (Exception ex) {
        ex.printStackTrace();
        this.logger.error(ex.getMessage());
    }
    return ResponseEntity.badRequest().body(new ErrorDTO("SUBSCRIPTION_CREATE_FAILED"));
} 

Ниже приведены DTO для справки.

Подписка поставщика услуг DTO

@JsonIgnoreProperties(ignoreUnknown = true)
public class ServiceProviderSubscriptionDTO {
    /**
     * The payment source token.
     */
    protected String paymentSourceToken;
    /**
     * The Advisor reference.
     */
    @JsonIgnoreProperties("subscription")
    private AdvisorDTO advisor;

    public String getPaymentSourceToken() {
        return this.paymentSourceToken;
    }

    public void setPaymentSourceToken(String paymentSourceToken) {
        this.paymentSourceToken = paymentSourceToken;
    }

    public AdvisorDTO getAdvisor() {
        return this.advisor;
    }

    public void setAdvisor(AdvisorDTO advisor) {
        this.advisor = advisor;
    }
}

Подписка DTO

@JsonIgnoreProperties(ignoreUnknown = true)
public class SubscriptionDTO {
    /**
     * Database identification number.
     */
    @Id
    protected Long id;
    /**
     * First and last name of the user who created the record in database.
     */
    protected String lastModifiedBy;
    /**
     * The Advisor reference.
     */
    @JsonIgnoreProperties({ "subscription", "lastModifiedBy" })
    private AdvisorDTO advisor;
    /**
     * The Service Provider Subscription.
     */
    private ServiceProviderSubscriptionDTO serviceProviderSubscription;

    public Long getId() {
        return this.id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getLastModifiedBy() {
        return this.lastModifiedBy;
    }

    public void setLastModifiedBy(String lastModifiedBy) {
        this.lastModifiedBy = lastModifiedBy;
    }

    public AdvisorDTO getAdvisor() {
        return this.advisor;
    }

    public void setAdvisor(AdvisorDTO advisor) {
        this.advisor = advisor;
    }

    public ServiceProviderSubscriptionDTO getServiceProviderSubscription() {
        return this.serviceProviderSubscription;
    }

    public void setServiceProviderSubscription(ServiceProviderSubscriptionDTO serviceProviderSubscription) {
        this.serviceProviderSubscription = serviceProviderSubscription;
    }
}

Advisor DTO

@JsonIgnoreProperties(ignoreUnknown = true)
public class AdvisorDTO {
    /**
     * Database identification number.
     */
    @Id
    protected Long id;
    /**
     * First and last name of the user who created the record in database.
     */
    protected String lastModifiedBy;
    /**
     * The subscription.
     */
    private SubscriptionDTO subscription;

    public Long getId() {
        return this.id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getLastModifiedBy() {
        return this.lastModifiedBy;
    }

    public void setLastModifiedBy(String lastModifiedBy) {
        this.lastModifiedBy = lastModifiedBy;
    }

    public SubscriptionDTO getSubscription() {
        return this.subscription;
    }

    public void setSubscription(SubscriptionDTO subscription) {
        this.subscription = subscription;
    }
}

Для меня это похоже на проблему с типом отображения модели, когда другие конечные точки кэшируют некоторыесвоего рода инструкции для сопоставителя моделей, которые несовместимы с этим объектом.Я не знаю точно, что делает Джексон с этими полезными нагрузками, когда они считываются в контроллеры, поэтому я могу только строить догадки.Эти ошибки генерируются до запуска любого из моих кодов контроллера.

Кто-нибудь знает, что может быть причиной этого и как я могу это исправить?

Spring Boot: 1.5.3.RELEASE

Spring Core: 4.3.8.RELEASE

Jackson Core: 2.8.8

Java: 8

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...