All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.micronaut.http.bind.binders.QueryValueArgumentBinder Maven / Gradle / Ivy

/*
 * Copyright 2017-2020 original authors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package io.micronaut.http.bind.binders;

import io.micronaut.core.annotation.AnnotationMetadata;
import io.micronaut.core.bind.annotation.AbstractArgumentBinder;
import io.micronaut.core.convert.ArgumentConversionContext;
import io.micronaut.core.convert.ConversionService;
import io.micronaut.core.convert.format.Format;
import io.micronaut.core.convert.value.ConvertibleMultiValues;
import io.micronaut.core.type.Argument;
import io.micronaut.http.BasicHttpAttributes;
import io.micronaut.http.HttpRequest;
import io.micronaut.http.annotation.QueryValue;
import io.micronaut.http.uri.UriMatchVariable;

import java.util.Collections;
import java.util.Optional;

/**
 * A binder for binding arguments annotated with @QueryValue.
 *
 * @param  The argument type
 * @author James Kleeh
 * @author Andriy Dmytruk
 * @since 2.0.2
 */
public class QueryValueArgumentBinder extends AbstractArgumentBinder implements AnnotatedRequestArgumentBinder {

    /**
     * Constructor.
     *
     * @param conversionService conversion service
     */
    public QueryValueArgumentBinder(ConversionService conversionService) {
        super(conversionService);
    }

    /**
     * Constructor.
     *
     * @param conversionService conversion service
     * @param argument The argument
     */
    public QueryValueArgumentBinder(ConversionService conversionService, Argument argument) {
        super(conversionService, argument);
    }

    @Override
    public RequestArgumentBinder createSpecific(Argument argument) {
        return new QueryValueArgumentBinder<>(conversionService, argument);
    }

    @Override
    public Class getAnnotationType() {
        return QueryValue.class;
    }

    /**
     * Binds the argument with {@link QueryValue} annotation to the request
     * (Also binds without annotation if request body is not permitted).
     * 

* It will first try to convert to ConvertibleMultiValues type and if conversion is successful, add the * corresponding parameters to the request. (By default the conversion will be successful if the {@link Format} * annotation is present and has one of the supported values - see * {@link io.micronaut.core.convert.converters.MultiValuesConverterFactory} for specific converters). Otherwise, * the uri template will be used to deduce what will be done with the request. For example, simple parameters are * converted to {@link String} */ @Override public BindingResult bind(ArgumentConversionContext context, HttpRequest source) { ConvertibleMultiValues parameters = source.getParameters(); Argument argument = context.getArgument(); AnnotationMetadata annotationMetadata = argument.getAnnotationMetadata(); if (source.getMethod().permitsRequestBody() && !annotationMetadata.hasAnnotation(QueryValue.class)) { // During the unmatched check avoid requests that don't allow bodies return BindingResult.unsatisfied(); } // First try converting from the ConvertibleMultiValues type and if conversion is successful, return it. // Otherwise, use the given uri template to deduce what to do with the variable Optional multiValueConversion; if (annotationMetadata.hasAnnotation(Format.class)) { multiValueConversion = conversionService.convert(parameters, context); } else { multiValueConversion = Optional.empty(); } if (multiValueConversion.isPresent()) { return () -> multiValueConversion; } // If we need to bind all request params to command object // checks if the variable is defined with modifier char *, e.g. ?pojo* String parameterName = resolvedParameterName(argument); boolean bindAll = BasicHttpAttributes.getRouteMatchInfo(source) .map(umi -> { UriMatchVariable uriMatchVariable = umi.getVariableMap().get(parameterName); return uriMatchVariable != null && uriMatchVariable.isExploded(); }).orElse(false); if (bindAll) { Object value; // Only maps and POJOs will "bindAll", lists work like normal if (Iterable.class.isAssignableFrom(argument.getType())) { value = doResolve(context, parameters); if (value == null) { value = Collections.emptyList(); } } else { value = parameters.asMap(); } return doConvert(value, context); } return doBind(context, parameters, BindingResult.unsatisfied()); } @Override protected String getParameterName(Argument argument) { return argument.getAnnotationMetadata().stringValue(QueryValue.class).orElse(argument.getName()); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy