Skip to content

Commit

Permalink
feat: allow to opt out links uri encoding
Browse files Browse the repository at this point in the history
  • Loading branch information
jimirocks committed Jul 12, 2024
1 parent e1cc5b4 commit ded35c2
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 3 deletions.
1 change: 1 addition & 0 deletions lib/src/main/asciidoc/configuration.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ see https://jsonapi.org/format/#auto-id--link-objects. To serialize the Spring H
Be aware that using the default, Spring HATEOAS complex links are rendered in a backward-incompatible way
(related to version 1.x.x of this library that only supports JSON:API 1.0),
since client might expect properties like title in the meta section. | true
| LinksUriEncoded | Whether the links should be URI encoded when serializing. Allowed by default. | true
|===

TIP: Since the JSON:API recommendation contains square brackets in the request parameter names,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,19 @@ public enum AffordanceType {
@Getter
private final boolean jsonApiCompliantLinks;

/**
* By default, JSON:API links are serialized as URI encoded.
*
* If you set this configuration ro {@literal false}, Spring HATEOAS links won't be URI encoded.
* This can be useful for instance to avoid double uri encoding when you pass the links to the model already
* URI encoded.
* @param linksUriEncoded The new value of this configuration's linksUriEncoded
* @return The default is {@literal true}.
*/
@With
@Getter
private final boolean linksUriEncoded;

@With(AccessLevel.PRIVATE)
private final Map<Class<?>, String> typeForClass;

Expand Down Expand Up @@ -361,8 +374,8 @@ public JsonApiConfiguration() {
this.affordancesRenderedAsLinkMeta = AffordanceType.NONE;
this.jsonApi11LinkPropertiesRemovedFromLinkMeta = true;
this.jsonApiCompliantLinks = true;
this.linksUriEncoded = true;
this.objectMapperCustomizer = customObjectMapper -> {
}; // Default to no action.
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ class JsonApiLinksSerializer extends AbstractJsonApiSerializer<Links> {
private static final ObjectMapper objectMapper = new ObjectMapper();
private JsonApiConfiguration.AffordanceType affordanceType;
private boolean removeHateoasLinkPropertiesFromMeta;
private boolean uriEncodeLinkHref = true;

public JsonApiLinksSerializer() {
super(Links.class);
Expand All @@ -56,6 +57,7 @@ public JsonApiLinksSerializer() {
public void setJsonApiConfiguration(JsonApiConfiguration jsonApiConfiguration) {
this.affordanceType = jsonApiConfiguration.getAffordancesRenderedAsLinkMeta();
this.removeHateoasLinkPropertiesFromMeta = jsonApiConfiguration.isJsonApi11LinkPropertiesRemovedFromLinkMeta();
this.uriEncodeLinkHref = jsonApiConfiguration.isLinksUriEncoded();
}

@Override
Expand All @@ -82,7 +84,7 @@ public void serialize(Links value, JsonGenerator gen, SerializerProvider provide

private void serializeLinkWithRelation(JsonGenerator gen, Link link) throws IOException {
if (isSimpleLink(link)) {
gen.writeStringField(link.getRel().value(), UriUtils.encodeQuery(link.getHref(), StandardCharsets.UTF_8));
gen.writeStringField(link.getRel().value(), uriEncodeLinkHref(link));
} else {
gen.writeObjectFieldStart(link.getRel().value());
writeComplexLink(gen, link);
Expand All @@ -91,7 +93,7 @@ private void serializeLinkWithRelation(JsonGenerator gen, Link link) throws IOEx
}

private void writeComplexLink(JsonGenerator gen, Link link) throws IOException {
gen.writeStringField("href", UriUtils.encodeQuery(link.getHref(), StandardCharsets.UTF_8));
gen.writeStringField("href", uriEncodeLinkHref(link));
Map<String, Object> attributes = getAttributes(link);
if (link.getTitle() != null) {
gen.writeStringField("title", link.getTitle());
Expand Down Expand Up @@ -119,6 +121,10 @@ private boolean isSimpleLink(Link link) {
return getAttributes(link).size() == 0;
}

private String uriEncodeLinkHref(Link link) {
return uriEncodeLinkHref ? UriUtils.encodeQuery(link.getHref(), StandardCharsets.UTF_8) : link.getHref();
}


private Map<String, Object> getAttributes(Link link) {
final Map<String, Object> attributeMap = objectMapper.convertValue(link, Map.class);
Expand Down

0 comments on commit ded35c2

Please sign in to comment.