Skip to content

ServerWebInputException is throw each time Http request with mandatory request parameters is handled. [SPR-17338] #21872

Closed
@spring-projects-issues

Description

@spring-projects-issues

Dmytro Mrachkovskyi opened SPR-17338 and commented

ServerWebInputException is throw each time Http request with mandatory request parameters is handled in AbstractNamedValueArgumentResolver. Even though this does not brake request handling flow, exception (and stack trace)  is generated each time and it has performance impact. 

Root-cause: 

In

 

org.springframework.web.reactive.result.method.annotation.AbstractNamedValueArgumentResolver#resolveArgument 

 return this.resolveName(resolvedName.toString(), nestedParameter, exchange)
.flatMap((arg) -> mappingFunction())
.switchIfEmpty(this.getDefaultValue(namedValueInfo, parameter, bindingContext, model, exchange));

switchIfEmpty takes default value as an argument. As for mandatory arguments there is no default value ServerWebInputException will be thrown in getDefaultValue() method and wrapped into Mono.error(ex). This error mono will never be used until mandatory request parameter exists, but Exception it self is crated when there is no need in it.

Fix. Default value should be evaluated only if request parameter is empty: 

package org.springframework.web.reactive.result.method.annotation;

public abstract class AbstractNamedValueArgumentResolver extends HandlerMethodArgumentResolverSupport {

...

private Mono<Object> getDefaultValue(NamedValueInfo namedValueInfo, MethodParameter parameter,
        BindingContext bindingContext, Model model, ServerWebExchange exchange) {
        return Mono.fromSupplier(() -> {
            Object value = null;
            if (namedValueInfo.defaultValue != null) {
                value = resolveStringValue(namedValueInfo.defaultValue);
            }
            else if (namedValueInfo.required && !parameter.isOptional()) {
                handleMissingValue(namedValueInfo.name, parameter, exchange);
            }
            value = handleNullValue(namedValueInfo.name, value, parameter.getNestedParameterType());
            value = applyConversion(value, namedValueInfo, parameter, bindingContext, exchange);
            handleResolvedValue(value, namedValueInfo.name, parameter, model, exchange);
            return value;
        });
}

Affects: 5.0.9, 5.1 GA

Referenced from: commits 983bce1, 8422976

Backported to: 5.0.10

Metadata

Metadata

Assignees

Labels

in: webIssues in web modules (web, webmvc, webflux, websocket)status: backportedAn issue that has been backported to maintenance branchestype: enhancementA general enhancement

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions