Skip to content

Commit a2713f3

Browse files
committed
Correct
1 parent 58b48b6 commit a2713f3

File tree

3 files changed

+31
-7
lines changed

3 files changed

+31
-7
lines changed

core-processor/src/main/java/io/micronaut/context/visitor/ExecutableVisitor.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import io.micronaut.context.annotation.Executable;
1919
import io.micronaut.core.annotation.Internal;
2020
import io.micronaut.core.annotation.NonNull;
21+
import io.micronaut.inject.ast.ClassElement;
2122
import io.micronaut.inject.ast.KotlinParameterElement;
2223
import io.micronaut.inject.ast.MethodElement;
2324
import io.micronaut.inject.ast.ParameterElement;
@@ -48,7 +49,8 @@ public TypeElementQuery query() {
4849
@Override
4950
public void visitMethod(MethodElement element, VisitorContext context) {
5051
for (ParameterElement parameter : element.getParameters()) {
51-
if (parameter.getType().isPrimitive() && parameter.isNullable()
52+
ClassElement type = parameter.getType();
53+
if (type.isPrimitive() && !type.isArray() && parameter.isNullable()
5254
&& !(parameter instanceof KotlinParameterElement kotlinParameterElement && kotlinParameterElement.hasDefault())) {
5355
context.warn("@Nullable on primitive types will allow the method to be executed at runtime with null values, causing an exception", parameter);
5456
}

http/src/main/java/io/micronaut/http/bind/DefaultRequestBinderRegistry.java

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
*/
1616
package io.micronaut.http.bind;
1717

18+
import io.micronaut.core.annotation.AnnotationMetadata;
19+
import io.micronaut.core.annotation.AnnotationUtil;
1820
import io.micronaut.core.annotation.NonNull;
1921
import io.micronaut.core.bind.ArgumentBinder;
2022
import io.micronaut.core.bind.annotation.Bindable;
@@ -33,8 +35,8 @@
3335
import io.micronaut.http.annotation.Body;
3436
import io.micronaut.http.bind.binders.AnnotatedRequestArgumentBinder;
3537
import io.micronaut.http.bind.binders.ContinuationArgumentBinder;
36-
import io.micronaut.http.bind.binders.CookieObjectArgumentBinder;
3738
import io.micronaut.http.bind.binders.CookieAnnotationBinder;
39+
import io.micronaut.http.bind.binders.CookieObjectArgumentBinder;
3840
import io.micronaut.http.bind.binders.DefaultBodyAnnotationBinder;
3941
import io.micronaut.http.bind.binders.DefaultUnmatchedRequestArgumentBinder;
4042
import io.micronaut.http.bind.binders.HeaderAnnotationBinder;
@@ -48,6 +50,8 @@
4850
import io.micronaut.http.bind.binders.TypedRequestArgumentBinder;
4951
import io.micronaut.http.cookie.Cookie;
5052
import io.micronaut.http.cookie.Cookies;
53+
import io.micronaut.inject.annotation.AnnotationMetadataHierarchy;
54+
import io.micronaut.inject.annotation.MutableAnnotationMetadata;
5155
import jakarta.inject.Inject;
5256
import jakarta.inject.Singleton;
5357

@@ -71,7 +75,7 @@
7175
public class DefaultRequestBinderRegistry implements RequestBinderRegistry {
7276

7377
private static final long CACHE_MAX_SIZE = 30;
74-
78+
private static final AnnotationMetadata NULLABLE_ANNOTATION_METADATA;
7579
private final Map<Class<? extends Annotation>, RequestArgumentBinder> byAnnotation = new LinkedHashMap<>();
7680
private final Map<TypeAndAnnotation, RequestArgumentBinder> byTypeAndAnnotation = new LinkedHashMap<>();
7781
private final Map<Integer, RequestArgumentBinder> byType = new LinkedHashMap<>();
@@ -81,6 +85,12 @@ public class DefaultRequestBinderRegistry implements RequestBinderRegistry {
8185
private final List<RequestArgumentBinder<Object>> unmatchedBinders = new ArrayList<>();
8286
private final DefaultUnmatchedRequestArgumentBinder defaultUnmatchedRequestArgumentBinder;
8387

88+
static {
89+
MutableAnnotationMetadata nullable = new MutableAnnotationMetadata();
90+
nullable.addAnnotation(AnnotationUtil.NULLABLE, Map.of());
91+
NULLABLE_ANNOTATION_METADATA = nullable;
92+
}
93+
8494
/**
8595
* @param conversionService The conversion service
8696
* @param binders The request argument binders
@@ -268,7 +278,14 @@ private static ArgumentBinder.BindingResult<? extends HttpRequest<?>> convertBod
268278
.filter(arg -> arg.getType() != Void.class);
269279
if (typeVariable.isPresent()) {
270280
@SuppressWarnings("unchecked")
271-
ArgumentConversionContext<Object> unwrappedConversionContext = ConversionContext.of((Argument<Object>) typeVariable.get());
281+
Argument<Object> argument = (Argument<Object>) typeVariable.get();
282+
argument = argument.withAnnotationMetadata(
283+
new AnnotationMetadataHierarchy(
284+
argument.getAnnotationMetadata(),
285+
NULLABLE_ANNOTATION_METADATA // HttpRequest's body can be null
286+
)
287+
);
288+
ArgumentConversionContext<Object> unwrappedConversionContext = ConversionContext.of(argument);
272289
ArgumentBinder.BindingResult<Object> bodyBound = bodyAnnotationBinder.bindFullBody(unwrappedConversionContext, source);
273290
// can't use flatMap here because we return a present optional even when the body conversion failed
274291
return new PendingRequestBindingResult<>() {
@@ -286,14 +303,14 @@ public List<ConversionError> getConversionErrors() {
286303
public Optional<HttpRequest<?>> getValue() {
287304
Optional<Object> body = bodyBound.getValue();
288305
if (pushCapable) {
289-
return Optional.of(new PushCapableRequestWrapper<Object>((HttpRequest<Object>) source, (PushCapableHttpRequest<?>) source) {
306+
return Optional.of(new PushCapableRequestWrapper<>((HttpRequest<Object>) source, (PushCapableHttpRequest<?>) source) {
290307
@Override
291308
public Optional<Object> getBody() {
292309
return body;
293310
}
294311
});
295312
} else {
296-
return Optional.of(new HttpRequestWrapper<Object>((HttpRequest<Object>) source) {
313+
return Optional.of(new HttpRequestWrapper<>((HttpRequest<Object>) source) {
297314
@Override
298315
public Optional<Object> getBody() {
299316
return body;

http/src/main/java/io/micronaut/http/body/InputStreamBodyReader.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,15 @@
3434
@Prototype
3535
@BootstrapContextCompatible
3636
@Internal
37-
final class InputStreamBodyReader implements MessageBodyReader<InputStream> {
37+
final class InputStreamBodyReader implements TypedMessageBodyReader<InputStream> {
3838

3939
@Override
4040
public InputStream read(Argument<InputStream> type, MediaType mediaType, Headers httpHeaders, InputStream inputStream) throws CodecException {
4141
return inputStream;
4242
}
43+
44+
@Override
45+
public Argument<InputStream> getType() {
46+
return Argument.of(InputStream.class);
47+
}
4348
}

0 commit comments

Comments
 (0)