Skip to content

AlpsJacksonJsonHttpMessageConverter incorrectly claims canRead(application/json) in Spring Boot 4 → breaks Spring Data REST URI-to-Entity conversion #3418

@lagoshny

Description

@lagoshny

Description

After upgrading from Spring Boot 3.x.x to Spring Boot 4.0.0,
AlpsJacksonJsonHttpMessageConverter starts intercepting all application/json requests,
even though:

  • in Boot 3.x AlpsJsonHttpMessageConverter#canRead() always returned false
  • in Boot 4.x AlpsJacksonJsonHttpMessageConverter#canRead() incorrectly returns true via base class logic

As a result, Spring Data REST no longer resolves URI links such as:

{
  "author": "http://localhost:8080/api/v1/users/1"
}

and deserialization fails with:

InvalidFormatException: Cannot deserialize value of type `long`
from String "http://localhost:8080/api/v1/users/1"

This breaks entity relationship binding via URI.


Root Cause Analysis

In Spring Boot 4:

AlpsJacksonJsonHttpMessageConverter inherits from
AbstractSmartHttpMessageConverter.

Spring now calls:

AbstractSmartHttpMessageConverter#canRead(...)

instead of the converter's overridden method.

That method falls back to:

supports(clazz) && supportedMediaTypes.contains(application/json)

And the converter registers media types:

application/alps+json
application/json
*/*

Therefore, canRead incorrectly returns true for application/json.

In Boot 3.x the same converter always returned false for JSON, so
the correct Jackson-based PersistentEntityJacksonModule converter handled the payload and resolved URI links to Entity.


Reproduction

I have created minimal app to reproduce this bug.
Follow the next project instruction to reproduce the bug.


Expected behavior

Spring Data REST should:

  • detect "author": "http://.../users/1"
  • resolve entity via UriToEntityConverter
  • bind it correctly to Task.author

Exactly as it worked in Spring Boot 3.x.


Actual behavior in Spring Boot 4

  • ALPS converter intercepts JSON
  • no URI resolution happens
  • deserialization fails before hitting Data REST

Workaround

Remove application/json from ALPS supported types

@Bean
public HttpMessageConverter<Object> patchAlps(AlpsJacksonJsonHttpMessageConverter converter) {
    converter.setSupportedMediaTypes(
        converter.getSupportedMediaTypes().stream()
            .filter(mt -> !mt.includes(MediaType.APPLICATION_JSON))
            .toList()
    );
    return converter;
}

Metadata

Metadata

Assignees

Labels

has: ai-slopAn bloated issue that contains low-value AI-generated content.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions