spring-projects / spring-projects/spring-hateoas

Unable to control the serialization of Link after upgrade to Spring HATEOAS 1.0

Open
#1,480 3 comments 0 reactions 1 assignee View on GitHub

@odrotbohm is already working on this.

Since Jul 28, 2021.

process: waiting for feedback
Dominant language
Java
Stars
1.1k
Forks
476
PR merge metrics
No merged PRs in 30d

Description

Our apps run behind the AWS API Gateway. Internally, we can call the apps directly, but externally customers must come in via the gateway.

So a particular app might have the endpoint: /api/public/v1/currentUser

But the API Gateway wants to expose this as: /currentUser

To achieve this, we have the gateway set a custom HTTP header: X-Forwarded-Omit where it can pass through the part of the path to omit. In the example above, it sets "X-Forwarded-Omit: /api/public/v1".

In the apps themselves, we were handling this via a custom serializer registered with the MappingJackson2HttpMessageConverter class and it worked well.

@Configuration
public class LinkConfiguration implements WebMvcConfigurer {

    @Override
    public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
        for (HttpMessageConverter<?> converter : converters) {
            if (converter instanceof MappingJackson2HttpMessageConverter) {
                MappingJackson2HttpMessageConverter jsonMessageConverter = (MappingJackson2HttpMessageConverter) converter;

                ObjectMapper objectMapper = jsonMessageConverter.getObjectMapper();
                objectMapper.setMixInResolver(new CustomResolver());

                break;
            }
        }
    }

    private static class CustomResolver implements ClassIntrospector.MixInResolver {

        @Override
        public Class<?> findMixInClassFor(Class<?> cls) {
            if (Link.class.equals(cls)) {
                return LinkMixin.class;
            }
            return null;
        }
    }
}
@JsonIgnoreProperties({ "rel" })
public abstract class LinkMixin extends Link {

    private static final long serialVersionUID = 4720588561299667409L;

    @Override
    @JsonInclude(JsonInclude.Include.ALWAYS)
    @JsonSerialize(using = CustomHrefSerializer.class)
    public abstract String getHref();

    @Override
    @JsonInclude(JsonInclude.Include.NON_EMPTY)
    @JsonSerialize(using = Jackson2HalModule.TrueOnlyBooleanSerializer.class)
    public abstract boolean isTemplated();
}
public class CustomHrefSerializer extends NonTypedScalarSerializerBase<String> {
    public CustomHrefSerializer() {
        super(String.class);
    }

    @Override
    public void serialize(String value, JsonGenerator jgen, SerializerProvider provider)
            throws IOException, JsonGenerationException {
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        HttpServletRequest servletRequest = ((ServletRequestAttributes) requestAttributes).getRequest();
        String omit = servletRequest.getHeader("X-Forwarded-Omit");

        if (StringUtils.isEmpty(omit)) {
            jgen.writeString(value);
        } else {
            jgen.writeString(value.replace(omit, ""));
        }
    }
}

After the upgrade to Spring HATEOAS 1.0, it no longer works.

It seems the problem is the json serializer never deals with Link objects now. Instead it gets Links which it treats as a simple type rather than a collection of Link objects, so our custom serializer is never called.

The Links class has a private constructor so I don't think it's possible to create a custom mixin for it.

Is there another way to do this given the changes in 1.0? Or perhaps another way entirely that I'm not familiar with?

Thanks.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.