Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Оглавление

Параметры запроса

Клиент передаёт данные не только в теле запроса, но и в самом адресе: /articles/5 — переменная пути, /search?q=java&page=2 — параметры строки запроса (query string, всё после знака ?). Ещё часть сведений приходит в заголовках. Micronaut раскладывает всё это по параметрам метода и сам приводит строки к нужным типам.

Источники значений

АннотацияОткуда значениеПример адреса
@PathVariableЧасть пути в фигурных скобках/search/tag/java
@QueryValueСтрока запроса после ?/search?q=java
@HeaderЗаголовок запросаUser-Agent: curl/8.21.0

Для переменной пути аннотацию можно не писать: параметр с тем же именем, что и {id} в адресе, Micronaut заполнит сам. Аннотация делает код нагляднее.

Контроллер поиска

Создайте файл поиска по блогу:

// src/main/java/com/example/SearchController.java
package com.example;
 
import io.micronaut.core.annotation.Nullable;
import io.micronaut.http.MediaType;
import io.micronaut.http.annotation.Controller;
import io.micronaut.http.annotation.Get;
import io.micronaut.http.annotation.Header;
import io.micronaut.http.annotation.PathVariable;
import io.micronaut.http.annotation.Produces;
import io.micronaut.http.annotation.QueryValue;
 
@Controller("/search")
@Produces(MediaType.TEXT_PLAIN)
public class SearchController {
 
    @Get
    public String search(@QueryValue String q,
                         @QueryValue(defaultValue = "1") int page) {
        return "Ищем '" + q + "', страница " + page;
    }
 
    @Get("/tag/{tag}")
    public String byTag(@PathVariable String tag, @QueryValue @Nullable String sort) {
        return "Тег " + tag + ", сортировка: " + (sort == null ? "нет" : sort);
    }
 
    @Get("/client")
    public String client(@Header("User-Agent") String userAgent) {
        return "Ваш клиент: " + userAgent;
    }
}

Параметр q обязателен, у page есть значение по умолчанию, а sort помечен @Nullable — если его нет, придёт null. Строка "2" из адреса сама превращается в int.

Проверка

curl "http://localhost:8080/search?q=micronaut"
curl "http://localhost:8080/search?q=micronaut&page=2"
curl "http://localhost:8080/search/tag/java?sort=new"
curl http://localhost:8080/search/client
Ищем 'micronaut', страница 1
Ищем 'micronaut', страница 2
Тег java, сортировка: new
Ваш клиент: curl/8.21.0

Адрес со знаком & берите в кавычки, иначе командная оболочка разрежет его на две команды.

Неверный тип

Если значение не удаётся привести к типу параметра, метод не вызывается — клиент получает 400:

curl "http://localhost:8080/search?q=x&page=two"
{"_links":{"self":[{"href":"/search?q=x&page=two","templated":false}]},"_embedded":{"errors":[{"message":"Failed to convert argument [page] for value [two] due to: For input string: \"two\"","path":"/page"}]},"message":"Bad Request"}

То же произойдёт с /articles/abc, если параметр id объявлен как Long.

Частая ошибка

Параметр без @Nullable и без значения по умолчанию Micronaut считает обязательным. Запрос без него получает 400:

curl http://localhost:8080/search
{"_links":{"self":[{"href":"/search","templated":false}]},"_embedded":{"errors":[{"message":"Required QueryValue [q] not specified","path":"/q"}]},"message":"Bad Request"}

Если параметр по смыслу необязательный, добавьте @Nullable (из пакета io.micronaut.core.annotation) или defaultValue.

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.