Skip to content

Provide mechanism to control trimming in StringToArrayConverter and StringToCollectionConverter #23850

Open

Description

@SingleShot

@RequestParams (i.e. HTTP query parameters) with leading or trailing spaces, including single parameters or delimited parameters, are trimmed when mapping them to a collection. It is likely this happens for other cases. A query parameter with a leading/trailing space is a perfectly reasonable construct provided it is encoded correctly. However by the time it gets into a controller, the space(s) have been trimmed.

I can see this happening in at least two Boot classes, and there are probably more:

  • StringToCollectionConverter
  • DelimitedStringToCollectionConverter

Simply removing the trim() calls is not the right choice as these are also used for parsing application.yml, and possibly have other uses. I suggest these converters should accept a trim? parameter at construction time, and the WebConversionService be given its own instances of the converters with trim=false so query params with leading/trailing spaces can be properly passed. Something like that anyway...

Activity

  1. rstoyanchev commented on Nov 29, 2019

    @rstoyanchev
    Contributor

    We can't really change the default behavior in web applications. Regardless of one's opinion (and from prior discussions, something like this will have opinions on both sides) existing applications already rely on the current behavior. Adding a trim property to those converters however does seem reasonable to me.

  2. rstoyanchev commented on Nov 29, 2019

    @rstoyanchev
    Contributor

    /cc @jhoeller, @sbrannen, seems straight forward to me, but just in case you have any comments.

  3. added
    in: coreIssues in core modules (aop, beans, core, context, expression)
    and removed on Nov 29, 2019
  4. added this to the 5.2.2 milestone on Nov 29, 2019
  5. rstoyanchev commented on Nov 29, 2019

    @rstoyanchev
    Contributor

    This applies to StringToArrayConverter and StringToCollectionConverter from the Spring Framework side. DelimitedStringToCollectionConverter is in Spring Boot.

  6. changed the title [-]Leading/Trailing Spaces Trimmed When Mapping RequestParams to Collections[/-] [+]Property to control trimming in StringToArrayConverter and StringToCollectionConverter[/+] on Nov 29, 2019
  7. sbrannen commented on Nov 29, 2019

    @sbrannen
    Member

    This applies to StringToArrayConverter and StringToCollectionConverter from the Spring Framework side.

    I think it's reasonable to add opt-in trimming support (enabled by default, of course) to those converters, especially since they would then align with the existing trimValues support in StringArrayPropertyEditor.

    ... except that those two classes are not public. So I don't see how a user would register one with a custom trimValues = false option.

  8. rstoyanchev commented on Nov 29, 2019

    @rstoyanchev
    Contributor

    Ah, so they are. That makes the question even more pertinent. How is one even supposed to control this? In a web application it is possible to register a PropertyEditor via @InitBinder method, possibly in an @ControllerAdvice but this isn't easy to discover, and should be at least documented as such, if there isn't a good route via the global ConversionService. And we don't have a property editor for collections.

  9. sbrannen commented on Nov 29, 2019

    @sbrannen
    Member

    In the web, if you're only concerned with converting from a String to a String[], you could register a StringArrayPropertyEditor with the trimValues flag set to false; however, as far as I know, we don't have a PropertyEditor for generic collections. In addition, StringArrayPropertyEditor does not support arbitrary object arrays: it only supports string arrays.

    If we make StringToArrayConverter and StringToCollectionConverter public, users could then register their custom-configured variants via WebMvcConfigurer.addFormatters(FormatterRegistry).

    Otherwise, users would have to implement their own variants of StringToArrayConverter and StringToCollectionConverter (for example, via copy-n-paste but removing the .trim() invocations or making the trimming optional).

    To be honest, I've never understood why StringToArrayConverter, StringToCollectionConverter, and other such built-in converters are package private classes.

  10. modified the milestones: 5.2.2, 5.2.3 on Nov 29, 2019
  11. modified the milestones: 5.2.3, 5.3 M1 on Dec 10, 2019
  12. changed the title [-]Property to control trimming in StringToArrayConverter and StringToCollectionConverter[/-] [+]Provide mechanism to control trimming in StringToArrayConverter and StringToCollectionConverter[/+] on Dec 10, 2019
  13. sbrannen commented on Dec 10, 2019

    @sbrannen
    Member

    Team Decisions:

    Investigate how to make the trimming in such converters configurable without making such converters public or how to make the functionality required to implement a custom converter by reusing the core functionality of such built-in converters — for example, by making the core functionality available via a public utility method.

    Alternatively, we may decide to make certain built-in converters directly public or indirectly public via static factory methods in a yet-to-be-defined utility class.

    We may consider introducing a StringCollectionPropertyEditor analogous to the existing StringArrayPropertyEditor and whether it makes sense to have such a StringCollectionPropertyEditor support arbitrary object arrays as opposed to only string arrays like StringArrayPropertyEditor.


    If we make the trimming support configurable, we would need to assess how best to apply that to existing default registered converters — for an entire ApplicationContext or specifically for use in Spring MVC and Spring Webflux. For example, one may wish to disable trimming for StringToArrayConverter while retaining trimming for StringToCollectionConverter. Similarly, for some converters, it would appear that trimming may always make sense (e.g., StringToBooleanConverter, StringToNumber, etc.).

    If we extract the existing core functionality from StringToArrayConverter and StringToCollectionConverter, we should build the trimValues support into that and delegate to that from StringToArrayConverter and StringToCollectionConverter with trimValues = true by default.

    In any case, we must keep in mind that StringToArrayConverter and StringToCollectionConverter rely on the ConversionService in order to convert strings to the appropriate target type.

  14. modified the milestones: 5.3 M1, 5.3 M2 on Jun 15, 2020
  15. modified the milestones: 5.3 M2, 5.3 RC1 on Aug 8, 2020
  16. modified the milestones: 5.3 RC1, 5.x Backlog on Aug 25, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    in: coreIssues in core modules (aop, beans, core, context, expression)status: pending-design-workNeeds design work before any code can be developedtype: enhancementA general enhancement

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions