spring-projects / spring-projects/spring-hateoas
Unable to control the serialization of Link after upgrade to Spring HATEOAS 1.0
@odrotbohm is already working on this.
Since Jul 28, 2021.
- 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
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.