Specify generic type nullness in spring-web
See gh-34140
This commit is contained in:
@@ -738,14 +738,14 @@ public class RequestEntity<T> extends HttpEntity<T> {
|
||||
|
||||
private final String uriTemplate;
|
||||
|
||||
private final Object @Nullable [] uriVarsArray;
|
||||
private final @Nullable Object @Nullable [] uriVarsArray;
|
||||
|
||||
private final @Nullable Map<String, ?> uriVarsMap;
|
||||
private final @Nullable Map<String, ? extends @Nullable Object> uriVarsMap;
|
||||
|
||||
UriTemplateRequestEntity(
|
||||
@Nullable T body, @Nullable HttpHeaders headers,
|
||||
@Nullable HttpMethod method, @Nullable Type type, String uriTemplate,
|
||||
Object @Nullable [] uriVarsArray, @Nullable Map<String, ?> uriVarsMap) {
|
||||
@Nullable Object @Nullable [] uriVarsArray, @Nullable Map<String, ?> uriVarsMap) {
|
||||
|
||||
super(body, headers, method, null, type);
|
||||
this.uriTemplate = uriTemplate;
|
||||
@@ -757,11 +757,11 @@ public class RequestEntity<T> extends HttpEntity<T> {
|
||||
return this.uriTemplate;
|
||||
}
|
||||
|
||||
public Object @Nullable [] getVars() {
|
||||
public @Nullable Object @Nullable [] getVars() {
|
||||
return this.uriVarsArray;
|
||||
}
|
||||
|
||||
public @Nullable Map<String, ?> getVarsMap() {
|
||||
public @Nullable Map<String, ? extends @Nullable Object> getVarsMap() {
|
||||
return this.uriVarsMap;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2024 the original author or authors.
|
||||
* Copyright 2002-2025 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.
|
||||
@@ -260,7 +260,7 @@ public class Jackson2ObjectMapperBuilder {
|
||||
* @since 5.2.4
|
||||
*/
|
||||
public Jackson2ObjectMapperBuilder annotationIntrospector(
|
||||
Function<AnnotationIntrospector, AnnotationIntrospector> pairingFunction) {
|
||||
Function<@Nullable AnnotationIntrospector, @Nullable AnnotationIntrospector> pairingFunction) {
|
||||
|
||||
this.annotationIntrospector = pairingFunction.apply(this.annotationIntrospector);
|
||||
return this;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2024 the original author or authors.
|
||||
* Copyright 2002-2025 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.
|
||||
@@ -56,7 +56,7 @@ public class RestClientResponseException extends RestClientException {
|
||||
|
||||
private final @Nullable String responseCharset;
|
||||
|
||||
private transient @Nullable Function<ResolvableType, ?> bodyConvertFunction;
|
||||
private transient @Nullable Function<ResolvableType, ? extends @Nullable Object> bodyConvertFunction;
|
||||
|
||||
|
||||
/**
|
||||
@@ -200,7 +200,7 @@ public class RestClientResponseException extends RestClientException {
|
||||
* @param bodyConvertFunction the function to use
|
||||
* @since 6.0
|
||||
*/
|
||||
public void setBodyConvertFunction(Function<ResolvableType, ?> bodyConvertFunction) {
|
||||
public void setBodyConvertFunction(Function<ResolvableType, ? extends @Nullable Object> bodyConvertFunction) {
|
||||
this.bodyConvertFunction = bodyConvertFunction;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2023 the original author or authors.
|
||||
* Copyright 2002-2025 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.
|
||||
@@ -99,7 +99,8 @@ final class StatusHandler {
|
||||
});
|
||||
}
|
||||
|
||||
private static Function<ResolvableType, ?> initBodyConvertFunction(ClientHttpResponse response, byte[] body, List<HttpMessageConverter<?>> messageConverters) {
|
||||
@SuppressWarnings("NullAway")
|
||||
private static Function<ResolvableType, ? extends @Nullable Object> initBodyConvertFunction(ClientHttpResponse response, byte[] body, List<HttpMessageConverter<?>> messageConverters) {
|
||||
Assert.state(!CollectionUtils.isEmpty(messageConverters), "Expected message converters");
|
||||
return resolvableType -> {
|
||||
try {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2021 the original author or authors.
|
||||
* Copyright 2002-2025 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.
|
||||
@@ -159,7 +159,7 @@ public class FormContentFilter extends OncePerRequestFilter {
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable String[] getParameterValues(String name) {
|
||||
public String[] getParameterValues(String name) {
|
||||
String[] parameterValues = super.getParameterValues(name);
|
||||
List<String> formParam = this.formParams.get(name);
|
||||
if (formParam == null) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2024 the original author or authors.
|
||||
* Copyright 2002-2025 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.
|
||||
@@ -357,7 +357,7 @@ public class HandlerMethod extends AnnotatedMethod {
|
||||
* beans, and others). {@code @Controller}'s that require proxying should prefer
|
||||
* class-based proxy mechanisms.
|
||||
*/
|
||||
protected void assertTargetBean(Method method, Object targetBean, Object[] args) {
|
||||
protected void assertTargetBean(Method method, Object targetBean, @Nullable Object[] args) {
|
||||
Class<?> methodDeclaringClass = method.getDeclaringClass();
|
||||
Class<?> targetBeanClass = targetBean.getClass();
|
||||
if (!methodDeclaringClass.isAssignableFrom(targetBeanClass)) {
|
||||
@@ -369,11 +369,14 @@ public class HandlerMethod extends AnnotatedMethod {
|
||||
}
|
||||
}
|
||||
|
||||
protected String formatInvokeError(String text, Object[] args) {
|
||||
protected String formatInvokeError(String text, @Nullable Object[] args) {
|
||||
String formattedArgs = IntStream.range(0, args.length)
|
||||
.mapToObj(i -> (args[i] != null ?
|
||||
"[" + i + "] [type=" + args[i].getClass().getName() + "] [value=" + args[i] + "]" :
|
||||
"[" + i + "] [null]"))
|
||||
.mapToObj(i -> {
|
||||
Object arg = args[i];
|
||||
return (arg != null ?
|
||||
"[" + i + "] [type=" +arg.getClass().getName() + "] [value=" + arg + "]" :
|
||||
"[" + i + "] [null]");
|
||||
})
|
||||
.collect(Collectors.joining(",\n", " ", " "));
|
||||
return text + "\n" +
|
||||
"Controller [" + getBeanType().getName() + "]\n" +
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2024 the original author or authors.
|
||||
* Copyright 2002-2025 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.
|
||||
@@ -24,6 +24,7 @@ import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
@@ -226,7 +227,7 @@ public class ExceptionHandlerMethodResolver {
|
||||
* Return the {@link Method} mapped to the given exception type, or
|
||||
* {@link #NO_MATCHING_EXCEPTION_HANDLER} if none.
|
||||
*/
|
||||
private @Nullable ExceptionHandlerMappingInfo getMappedMethod(Class<? extends Throwable> exceptionType, MediaType mediaType) {
|
||||
private ExceptionHandlerMappingInfo getMappedMethod(Class<? extends Throwable> exceptionType, MediaType mediaType) {
|
||||
List<ExceptionMapping> matches = new ArrayList<>();
|
||||
for (ExceptionMapping mappingInfo : this.mappedMethods.keySet()) {
|
||||
if (mappingInfo.exceptionType().isAssignableFrom(exceptionType) && mappingInfo.mediaType().isCompatibleWith(mediaType)) {
|
||||
@@ -237,7 +238,7 @@ public class ExceptionHandlerMethodResolver {
|
||||
if (matches.size() > 1) {
|
||||
matches.sort(new ExceptionMapingComparator(exceptionType, mediaType));
|
||||
}
|
||||
return this.mappedMethods.get(matches.get(0));
|
||||
return Objects.requireNonNull(this.mappedMethods.get(matches.get(0)));
|
||||
}
|
||||
else {
|
||||
return NO_MATCHING_EXCEPTION_HANDLER;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2024 the original author or authors.
|
||||
* Copyright 2002-2025 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.
|
||||
@@ -78,7 +78,7 @@ public final class HandlerMethodValidator implements MethodValidator {
|
||||
@Override
|
||||
public void applyArgumentValidation(
|
||||
Object target, Method method, MethodParameter @Nullable [] parameters,
|
||||
Object[] arguments, Class<?>[] groups) {
|
||||
@Nullable Object[] arguments, Class<?>[] groups) {
|
||||
|
||||
MethodValidationResult result = validateArguments(target, method, parameters, arguments, groups);
|
||||
if (!result.hasErrors()) {
|
||||
@@ -110,7 +110,7 @@ public final class HandlerMethodValidator implements MethodValidator {
|
||||
@Override
|
||||
public MethodValidationResult validateArguments(
|
||||
Object target, Method method, MethodParameter @Nullable [] parameters,
|
||||
Object[] arguments, Class<?>[] groups) {
|
||||
@Nullable Object[] arguments, Class<?>[] groups) {
|
||||
|
||||
return this.validationAdapter.validateArguments(target, method, parameters, arguments, groups);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2024 the original author or authors.
|
||||
* Copyright 2002-2025 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.
|
||||
@@ -172,9 +172,9 @@ public class InvocableHandlerMethod extends HandlerMethod {
|
||||
* @see #doInvoke
|
||||
*/
|
||||
public @Nullable Object invokeForRequest(NativeWebRequest request, @Nullable ModelAndViewContainer mavContainer,
|
||||
Object... providedArgs) throws Exception {
|
||||
@Nullable Object... providedArgs) throws Exception {
|
||||
|
||||
Object[] args = getMethodArgumentValues(request, mavContainer, providedArgs);
|
||||
@Nullable Object[] args = getMethodArgumentValues(request, mavContainer, providedArgs);
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Arguments: " + Arrays.toString(args));
|
||||
}
|
||||
@@ -200,15 +200,15 @@ public class InvocableHandlerMethod extends HandlerMethod {
|
||||
* <p>The resulting array will be passed into {@link #doInvoke}.
|
||||
* @since 5.1.2
|
||||
*/
|
||||
protected Object[] getMethodArgumentValues(NativeWebRequest request, @Nullable ModelAndViewContainer mavContainer,
|
||||
Object... providedArgs) throws Exception {
|
||||
protected @Nullable Object[] getMethodArgumentValues(NativeWebRequest request, @Nullable ModelAndViewContainer mavContainer,
|
||||
@Nullable Object... providedArgs) throws Exception {
|
||||
|
||||
MethodParameter[] parameters = getMethodParameters();
|
||||
if (ObjectUtils.isEmpty(parameters)) {
|
||||
return EMPTY_ARGS;
|
||||
}
|
||||
|
||||
Object[] args = new Object[parameters.length];
|
||||
@Nullable Object[] args = new Object[parameters.length];
|
||||
for (int i = 0; i < parameters.length; i++) {
|
||||
MethodParameter parameter = parameters[i];
|
||||
parameter.initParameterNameDiscovery(this.parameterNameDiscoverer);
|
||||
@@ -239,7 +239,7 @@ public class InvocableHandlerMethod extends HandlerMethod {
|
||||
/**
|
||||
* Invoke the handler method with the given argument values.
|
||||
*/
|
||||
protected @Nullable Object doInvoke(Object... args) throws Exception {
|
||||
protected @Nullable Object doInvoke(@Nullable Object... args) throws Exception {
|
||||
Method method = getBridgedMethod();
|
||||
try {
|
||||
if (KotlinDetector.isKotlinReflectPresent()) {
|
||||
@@ -285,7 +285,7 @@ public class InvocableHandlerMethod extends HandlerMethod {
|
||||
* instead.
|
||||
* @since 6.0
|
||||
*/
|
||||
protected Object invokeSuspendingFunction(Method method, Object target, Object[] args) {
|
||||
protected Object invokeSuspendingFunction(Method method, Object target, @Nullable Object[] args) {
|
||||
Object result = CoroutinesUtils.invokeSuspendingFunction(method, target, args);
|
||||
return (result instanceof Mono<?> mono ? mono.handle(KotlinDelegate::handleResult) : result);
|
||||
}
|
||||
@@ -297,7 +297,9 @@ public class InvocableHandlerMethod extends HandlerMethod {
|
||||
private static class KotlinDelegate {
|
||||
|
||||
@SuppressWarnings("DataFlowIssue")
|
||||
public static @Nullable Object invokeFunction(Method method, Object target, Object[] args) throws InvocationTargetException, IllegalAccessException, NoSuchMethodException {
|
||||
public static @Nullable Object invokeFunction(Method method, Object target, @Nullable Object[] args) throws
|
||||
InvocationTargetException, IllegalAccessException, NoSuchMethodException {
|
||||
|
||||
KFunction<?> function = ReflectJvmMapping.getKotlinFunction(method);
|
||||
// For property accessors
|
||||
if (function == null) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2024 the original author or authors.
|
||||
* Copyright 2002-2025 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.
|
||||
@@ -127,13 +127,13 @@ final class HttpServiceMethod {
|
||||
}
|
||||
|
||||
|
||||
public @Nullable Object invoke(Object[] arguments) {
|
||||
public @Nullable Object invoke(@Nullable Object[] arguments) {
|
||||
HttpRequestValues.Builder requestValues = this.requestValuesInitializer.initializeRequestValuesBuilder();
|
||||
applyArguments(requestValues, arguments);
|
||||
return this.responseFunction.execute(requestValues.build());
|
||||
}
|
||||
|
||||
private void applyArguments(HttpRequestValues.Builder requestValues, Object[] arguments) {
|
||||
private void applyArguments(HttpRequestValues.Builder requestValues, @Nullable Object[] arguments) {
|
||||
Assert.isTrue(arguments.length == this.parameters.length, "Method argument mismatch");
|
||||
for (int i = 0; i < arguments.length; i++) {
|
||||
Object value = arguments[i];
|
||||
@@ -383,10 +383,10 @@ final class HttpServiceMethod {
|
||||
}
|
||||
|
||||
private record ExchangeResponseFunction(
|
||||
Function<HttpRequestValues, Object> responseFunction) implements ResponseFunction {
|
||||
Function<HttpRequestValues, @Nullable Object> responseFunction) implements ResponseFunction {
|
||||
|
||||
@Override
|
||||
public Object execute(HttpRequestValues requestValues) {
|
||||
public @Nullable Object execute(HttpRequestValues requestValues) {
|
||||
return this.responseFunction.apply(requestValues);
|
||||
}
|
||||
|
||||
@@ -403,7 +403,7 @@ final class HttpServiceMethod {
|
||||
MethodParameter param = new MethodParameter(method, -1).nestedIfOptional();
|
||||
Class<?> paramType = param.getNestedParameterType();
|
||||
|
||||
Function<HttpRequestValues, Object> responseFunction;
|
||||
Function<HttpRequestValues, @Nullable Object> responseFunction;
|
||||
if (ClassUtils.isVoidType(paramType)) {
|
||||
responseFunction = requestValues -> {
|
||||
client.exchange(requestValues);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2024 the original author or authors.
|
||||
* Copyright 2002-2025 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.
|
||||
@@ -233,7 +233,7 @@ public final class HttpServiceProxyFactory {
|
||||
Method method = invocation.getMethod();
|
||||
HttpServiceMethod httpServiceMethod = this.httpServiceMethods.get(method);
|
||||
if (httpServiceMethod != null) {
|
||||
Object[] arguments = KotlinDetector.isSuspendingFunction(method) ?
|
||||
@Nullable Object[] arguments = KotlinDetector.isSuspendingFunction(method) ?
|
||||
resolveCoroutinesArguments(invocation.getArguments()) : invocation.getArguments();
|
||||
return httpServiceMethod.invoke(arguments);
|
||||
}
|
||||
@@ -246,7 +246,7 @@ public final class HttpServiceProxyFactory {
|
||||
throw new IllegalStateException("Unexpected method invocation: " + method);
|
||||
}
|
||||
|
||||
private static Object[] resolveCoroutinesArguments(Object[] args) {
|
||||
private static Object[] resolveCoroutinesArguments(@Nullable Object[] args) {
|
||||
Object[] functionArgs = new Object[args.length - 1];
|
||||
System.arraycopy(args, 0, functionArgs, 0, args.length - 1);
|
||||
return functionArgs;
|
||||
|
||||
@@ -140,6 +140,7 @@ public class DefaultUriBuilderFactory implements UriBuilderFactory {
|
||||
* with a Map of variables.
|
||||
* @param defaultUriVariables default URI variable values
|
||||
*/
|
||||
@SuppressWarnings("NullAway") // https://github.com/uber/NullAway/issues/1126
|
||||
public void setDefaultUriVariables(@Nullable Map<String, ? extends @Nullable Object> defaultUriVariables) {
|
||||
if (defaultUriVariables != null) {
|
||||
if (this.defaultUriVariables == null) {
|
||||
@@ -431,6 +432,7 @@ public class DefaultUriBuilderFactory implements UriBuilderFactory {
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("NullAway") // https://github.com/uber/NullAway/issues/1126
|
||||
public URI build(Map<String, ?> uriVars) {
|
||||
if (!CollectionUtils.isEmpty(defaultUriVariables)) {
|
||||
Map<String, Object> map = new HashMap<>(defaultUriVariables.size() + uriVars.size());
|
||||
@@ -446,6 +448,7 @@ public class DefaultUriBuilderFactory implements UriBuilderFactory {
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("NullAway") // https://github.com/uber/NullAway/issues/1126
|
||||
public URI build(@Nullable Object... uriVars) {
|
||||
if (ObjectUtils.isEmpty(uriVars) && !CollectionUtils.isEmpty(defaultUriVariables)) {
|
||||
return build(Collections.emptyMap());
|
||||
|
||||
Reference in New Issue
Block a user