So far, the handling of links detected via a JSON Path expression has assumed that the JsonProvider would always return JSONArray objects for collections. However, the JacksonJsonProvider for example, returns plain List instances. As JSONArray implements List, we now only refer to the latter for maximum compatibility with different JsonProvider implementations.
Original ticket: #1980
The reflection configuration of core Spring HATEOAS types is now done via HateoasRuntimeHints (previously RepresentationModelRuntimeHints). This allows the configuration to be contributed, even without @EnableHypermediaSupport in play, especially helpful in Web.fn scenarios.
We now register reflection hints for all types contained in EntityModel, so that MapSuppressingUnwrappingSerializer's default constructor can be called from Jackson.
Original ticket: #1981
Related ticket: spring-projects/spring-boot#36057
Fixed the regular expression to parse link header values to properly consider the comma to end an unquoted attribute value, too. Couple of additional unit tests, too.
We now inspect controller method return types and the generics of RepresentationModelAssembler for EntityModel and CollectionModel types and unwrap the type they box to register that for constructor and method invocation reflection.
We now register proxy types for all controller beans and the return types of their methods if suitable for proxying. This allows the link creation by pointing to controller methods.
We now also register all types (de)serialized by Jackson for reflection.
We now relax the generic bound of D to … extends RepresentationModel<?> as otherwise implementation code of, for example, toModel(…) has to produce a concrete representation model and cannot be typed to return RepresentationModel<?>.
Introduced UriMapping to contain the original request mapping used on a controller method as well as a MappingVariables instance that captures all used variables of those mappings. These mappings and variables are not following URI template semantics but rather PathPattern. One example of this playing into the processing is the path segment capture syntax {*…}. This is roughly equivalent to URI template's composite path syntax {/…*}, which however looks different (as the leading slash is contained in the variable expression).
While the handling of those has been added in the commit before, we now introduce the proper abstractions that cause a couple of internal deprecations and binary-incompatible changes and we only want to impose them on implementors upgrading to 2.0. Also, this allows simplifying WebHandler which has accumulated quite a bit of logic already.
We now properly handle path segment capture variables in URI mappings. Values handed into the dummy method invocations are expanded properly and a given null results in the composite segment template variable {/…*} being rendered to advertise the ability to add further segments.
We unfortunately cannot use UriComponentsBuilder in a way that we can populate it with encoded parameters *and* expand encoded path variable values. We currently use ….buildAndExpand(…) which considers the values provided unencoded but we never actually call ….toUri() on the resulting UriComponents instance.
We unfortunately cannot fix the problem at its root, as the only alternative would be to call ….build(true) indicating values already encoded but that stumbles above the template variables still present in the original template.
The only workaround right now is never calling UriComponents.toUri() but ….toUriString() as that doesn't apply the pending encoding that's not actually needed as we start with fully encoded values in the first place.
Heavily inspired by the PR @MikeRocke, we removed all usage of String.format(…) from hot code paths triggered by ….toString() as it's used in general output a lot.
Before:
Benchmark Mode Cnt Score Error Units
TemplateVariableBenchmark.toString(…) thrpt 3 2803239,270 ± 110258,955 ops/s
After:
Benchmark Mode Cnt Score Error Units
TemplateVariableBenchmark.toString(…) thrpt 3 10753653,459 ± 156684,459 ops/s
Slightly more compact default regex pattern. Untangle defaulting condition in PropertyMetdata.getPattern(). Extract test cases into dedicated methods. Couple of Javadoc fixes. Java-9-based polishing by using Optional.or(…) in JSR 303 PropertyMetadata implementation.
The presence of @NonBlank on a representation model's property now causes it to be considered required. It will also cause a default pattern exposed that allows clients to validate input values.
Fixes#1757.