Repository: spring-projects/spring-framework

Issue #12969: `Formatter` subsystem's `ParserConverter` skips `parse()` invocation if input string is empty [SPR-8321]
Created: 2011-05-10T03:38:42Z
Gabriele Del Prete opened SPR-8321 and commented
ParserConverter will skip calling the parse() method of a Parser<T> if the to-be-converted field is empty, and will return null as the parsing result.
(You can see this at the very beginning of the convert() method in ParserConverter).
This mean that you get two different behaviors when receiving data from fields in a form, depending on whether you use or don't use parsers.

Suppose you have a String property on your command bean, and a matching input field on the view. Then:


if the user inputs any non empty string, the form bean property will be set to that string;
if the user inputs an empty string, the form bean property will be set to the empty string.

So far, so good, this is the expected behavior.

Now suppose you annotate the String property on your command bean with a Formatter<T> annotation with its parse() method implemented.

Then:

if the user inputs any non empty string, the parse() method will get correctly called, and will return whatever is its parsing result.
if the user inputs an empty string, the parse() method will never get called, and moreover the form bean property will be set to null.

This is wrong in my opinion because:


Spring is not allowing a Parser to handle empty strings on input, however one might very well want to consider empty strings as lecit value when parsing.


from the application point-of-view, using a Parser may result in having your command bean properties set to null... ironically enough, something you should never get as Parsers and Printers supposedly are not allowed to handle null values.


The proposed fix is, simply allow empty string to reach the Parser's parse() method, so that it can eventually handle it.

I'm attaching a sample webapp which shows the problem; the webapp shows a form with two String fields, one not annotated with a Formatter, and the other annotated with a simple @Trim formatters which trims strings when parsing and is a no-op when printing.
The form is pre-populated with non empty string; if you submit it, you can see both the Parser and the Printer part of the Formatter getting called on the annotated property (watch the log for this). If you otherwise submit the form with empty fields, you'll see the Parser is never called, and the annotated property is set to null (again, see the log as on the resulting webpage nulls are converted to the empty string).

Affects: 3.0.5
Reference URL: http://forum.springsource.org/showthread.php?101583-Why-does-the-Formatter-system-ignore-null-values
Attachments:

formatters-test.tar.gz (7.50 kB)

Issue Links:

#12973 Formatter subsystem: allow Parser to return null as the parsed object; allow Printers to accept null as the object to be formatted
#12201 Consider mapping empty form values to [null] for Object properties
#12038 Formatters bind empty form fields to [null] property values while DataBinder by default binds empty string

Duplicate issue #16768: FormattingConversionService.ParserConverter Does Not Allow Custom Formatting of Blank Query Parameters [SPR-12154]
Created: 2014-09-05T05:49:05Z
Craig Johnston opened SPR-12154 and commented
I have a form on a web page that takes various values for doing a search and makes a GET request to the server on submission. One of these field is an int field which can be empty. If it is empty I wish to set it to Integer.MAX_VALUE which signifies that no particular value is required in the search.
I registered a Formatter implementation with the FormatterRegistry.
		registry.addFormatterForFieldType(Integer.class, new Formatter<Integer>() {

			@Override
			public Integer parse(String text, Locale locale) throws ParseException {
				if (StringUtils.isBlank(text)) {
					return Integer.MAX_VALUE;
				}

				return Integer.parseInt(text);
			}

			@Override
			public String print(Integer value, Locale locale) {
				if (Integer.MAX_VALUE == value) {
					return "";
				}

				return value.toString();
			}
		});
However when a blank query parameter value is included in the request to the server, Spring is unable to call my formatter's parse method due to this section of FormattingConversionService.ParserConverter.
@Override
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
     String text = (String) source;
     if (!StringUtils.hasText(text)) {
          return null;
     }
null will be returned from this. TypeConverterDelegate does then attempt to fallback to PropertyEditors. My understanding however is that PropertyEditors are now discouraged and don't seem to play well with Web Flow.
My feeling is that it should be possible for custom Formatter implementations to handle the case of an empty parameter.

Affects: 4.0.6

Closing comment (2023-11-05T13:23:05Z): duplicate of #12969