Привязка нескольких значений запроса в POJO

#java #micronaut #micronaut-client #micronaut-rest

#java #micronaut #micronaut-клиент #micronaut-rest

Вопрос:

У меня есть простой контроллер и rest API, как показано ниже, в котором я хочу сопоставить значения запросов ‘name’, ‘price’ и ‘description’ в ProductSearchCriteria :

     @Controller("/api/v1/product")
    public class ProductController {
        private static final Logger LOG = LoggerFactory.getLogger(ProductController.class);
    
        @Operation(summary = "Find all products")
        @ApiResponses(value = {@ApiResponse(content = {@Content(mediaType = "application/json", schema = @Schema(implementation = ProductViewModel.class))})})
        @Get(uri="/")
        List<ProductViewModel> find(@Valid ProductSearchCriteria searchCriteria) {
            LOG.info("Finding all the products");
            //return productProducer.find(searchCriteria);
            return new ArrayList<>();
        }
    }
  

критерии поиска продукта

 public class ProductSearchCriteria {
    @JsonProperty("name")
    Optional<String> name;

    @JsonProperty("price")
    Optional<Float> price;

    @JsonProperty("description")
    Optional<String> description;

    public Optional<String> getName() {
        return name;
    }

    public void setName(Optional<String> name) {
        this.name = name;
    }

    public Optional<Float> getPrice() {
        return price;
    }

    public void setPrice(Optional<Float> price) {
        this.price = price;
    }

    public Optional<String> getDescription() {
        return description;
    }

    public void setDescription(Optional<String> description) {
        this.description = description;
    }
}
  

Ошибка

 Error: 400 Bad Request
    {
      "message": "Required argument [ProductSearchCriteria searchCriteria] not specified",
      "path": "/searchCriteria",
      "_links": {
        "self": {
          "href": "/api/v1/product?name=stringamp;price=0amp;description=string",
          "templated": false
        }
      }
    }
  

Ответ №1:

Вы что-то пропустили в @Get аннотации

     @Operation(summary = "Find all products")
    @ApiResponses(value = {@ApiResponse(content = {@Content(mediaType = "application/json", schema = @Schema(implementation = ProductViewModel.class))})})
    @Get(uri="/{?searchCriteria*}")
    List<ProductViewModel> find(@Valid ProductSearchCriteria searchCriteria) {
        LOG.info("Finding all the products");
        //return productProducer.find(searchCriteria);
        return new ArrayList<>();
    }
  

Вы также пропускаете @Introspected в своем ProductSearchCriteria POJO.

Поскольку вы используете @Valid , я бы использовал аннотацию проверки ProductSearchCriteria внутри вместо Optional

Комментарии:

1. Спасибо за ответ, он работает. Для чего используется @Introspected . Согласно определению «Аннотация, указывающая на тип, должна производить повторную проверку во время компиляции». Но я не совсем понял, что это значит

2. Micronaut не использует самоанализ Java, как другие фреймворки. У него есть собственный API BeanIntrospection, которому нужны метаданные, сгенерированные во время компиляции с помощью аннотации @Introspected . Ваш компонент ProductSearchCriteria будет заполнен через этот API, поэтому вы должны аннотировать компонент.