From 1e3161b16154cf21738a2d147cd51ee9318bfa61 Mon Sep 17 00:00:00 2001 From: rstoyanchev Date: Tue, 13 Jun 2023 10:52:48 +0100 Subject: [PATCH] Expose MethodParameter in MissingServletRequestParameterException See gh-26219 --- ...ssingServletRequestParameterException.java | 50 +++++++++++++++++-- .../RequestParamMethodArgumentResolver.java | 5 +- 2 files changed, 49 insertions(+), 6 deletions(-) diff --git a/spring-web/src/main/java/org/springframework/web/bind/MissingServletRequestParameterException.java b/spring-web/src/main/java/org/springframework/web/bind/MissingServletRequestParameterException.java index c16a74a04f0..b1ce0f52587 100644 --- a/spring-web/src/main/java/org/springframework/web/bind/MissingServletRequestParameterException.java +++ b/spring-web/src/main/java/org/springframework/web/bind/MissingServletRequestParameterException.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2022 the original author or authors. + * Copyright 2002-2023 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,6 +16,9 @@ package org.springframework.web.bind; +import org.springframework.core.MethodParameter; +import org.springframework.lang.Nullable; + /** * {@link ServletRequestBindingException} subclass that indicates a missing parameter. * @@ -29,6 +32,9 @@ public class MissingServletRequestParameterException extends MissingRequestValue private final String parameterType; + @Nullable + private final MethodParameter parameter; + /** * Constructor for MissingServletRequestParameterException. @@ -36,7 +42,28 @@ public class MissingServletRequestParameterException extends MissingRequestValue * @param parameterType the expected type of the missing parameter */ public MissingServletRequestParameterException(String parameterName, String parameterType) { - this(parameterName, parameterType, false); + super("", false, null, new Object[] {parameterName}); + this.parameterName = parameterName; + this.parameterType = parameterType; + this.parameter = null; + getBody().setDetail(initBodyDetail(this.parameterName)); + } + + /** + * Constructor with a {@link MethodParameter} instead of a String parameterType. + * @param parameterName the name of the missing parameter + * @param parameter the target method parameter for the missing value + * @param missingAfterConversion whether the value became null after conversion + * @since 6.1 + */ + public MissingServletRequestParameterException( + String parameterName, MethodParameter parameter, boolean missingAfterConversion) { + + super("", missingAfterConversion, null, new Object[] {parameterName}); + this.parameterName = parameterName; + this.parameterType = parameter.getNestedParameterType().getSimpleName(); + this.parameter = parameter; + getBody().setDetail(initBodyDetail(this.parameterName)); } /** @@ -45,14 +72,21 @@ public class MissingServletRequestParameterException extends MissingRequestValue * @param parameterType the expected type of the missing parameter * @param missingAfterConversion whether the value became null after conversion * @since 5.3.6 + * @deprecated in favor of {@link #MissingServletRequestParameterException(String, MethodParameter, boolean)} */ + @Deprecated(since = "6.1", forRemoval = true) public MissingServletRequestParameterException( String parameterName, String parameterType, boolean missingAfterConversion) { super("", missingAfterConversion, null, new Object[] {parameterName}); this.parameterName = parameterName; this.parameterType = parameterType; - getBody().setDetail("Required parameter '" + this.parameterName + "' is not present."); + this.parameter = null; + getBody().setDetail(initBodyDetail(this.parameterName)); + } + + private static String initBodyDetail(String name) { + return "Required parameter '" + name + "' is not present."; } @@ -77,4 +111,14 @@ public class MissingServletRequestParameterException extends MissingRequestValue return this.parameterType; } + /** + * Return the target {@link MethodParameter} if the exception was raised for + * a controller method argument. + * @since 6.1 + */ + @Nullable + public MethodParameter getMethodParameter() { + return this.parameter; + } + } diff --git a/spring-web/src/main/java/org/springframework/web/method/annotation/RequestParamMethodArgumentResolver.java b/spring-web/src/main/java/org/springframework/web/method/annotation/RequestParamMethodArgumentResolver.java index eb5f2b31151..2a0673239f9 100644 --- a/spring-web/src/main/java/org/springframework/web/method/annotation/RequestParamMethodArgumentResolver.java +++ b/spring-web/src/main/java/org/springframework/web/method/annotation/RequestParamMethodArgumentResolver.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2022 the original author or authors. + * Copyright 2002-2023 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -214,8 +214,7 @@ public class RequestParamMethodArgumentResolver extends AbstractNamedValueMethod } } else { - throw new MissingServletRequestParameterException(name, - parameter.getNestedParameterType().getSimpleName(), missingAfterConversion); + throw new MissingServletRequestParameterException(name, parameter, missingAfterConversion); } }