Paul Marcelin Bejan
Paul Marcelin Bejan

Reputation: 1685

Java SpringBoot @PathVariable on RestController

I have the following @RestController:

package io.github.paulmarcelinbejan.coandaairlines.reservationsystem.adapters.inbound.controller.rest;

import java.util.List;

import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import io.github.paulmarcelinbejan.coandaairlines.reservationsystem.adapters.inbound.impl.rest.CurrencyInboundAdapterRestImpl;
import io.github.paulmarcelinbejan.coandaairlines.reservationsystem.ports.currency.domain.CurrencyDTO;
import io.github.paulmarcelinbejan.davinci.adapters.api.DavinciApiResponse;

import lombok.RequiredArgsConstructor;

@RestController
@RequiredArgsConstructor
@RequestMapping("/api/currency")
public class CurrencyRestController {

    private final CurrencyInboundAdapterRestImpl currencyInboundAdapterRestImpl;

    @GetMapping(value = "/id/{id}", produces = MediaType.APPLICATION_JSON_VALUE)
    public DavinciApiResponse<CurrencyDTO> findById(@PathVariable Integer id) {
        return currencyInboundAdapterRestImpl.findById(id);
    }

    @GetMapping(value = "/code/{code}", produces = MediaType.APPLICATION_JSON_VALUE)
    public DavinciApiResponse<CurrencyDTO> findByCode(@PathVariable String code) {
        return currencyInboundAdapterRestImpl.findByCode(code);
    }

    @GetMapping(value = "/", produces = MediaType.APPLICATION_JSON_VALUE)
    public DavinciApiResponse<List<CurrencyDTO>> findAll() {
        return currencyInboundAdapterRestImpl.findAll();
    }

}

but when I access Swagger, it doesn't show me the space to insert the pathVariable:

enter image description here

If I try to execute I have the following exception:

{
  "status": "KO",
  "errors": {
    "timestampUTC": "2024-04-02T11:24:45.416132Z",
    "exceptionType": "IllegalArgumentException",
    "message": "Name for argument of type [java.lang.Integer] not specified, and parameter name information not available via reflection. Ensure that the compiler uses the '-parameters' flag."
  }
}

same issue also from postman:

enter image description here

If I remove the @PathVariable then on swagger I can see it:

enter image description here

but still same error:

{
  "status": "KO",
  "errors": {
    "timestampUTC": "2024-04-02T11:26:56.186060Z",
    "exceptionType": "IllegalArgumentException",
    "message": "Name for argument of type [java.lang.Integer] not specified, and parameter name information not available via reflection. Ensure that the compiler uses the '-parameters' flag."
  }
}

On another project, I have similar @RestController:

package com.hyperbank.types.currency.controller;

import java.util.List;

import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import com.hyperbank.types.currency.dto.CurrencyResponse;
import com.hyperbank.types.currency.dto.CurrencySaveRequest;
import com.hyperbank.types.currency.dto.CurrencyUpdateRequest;
import com.hyperbank.types.currency.mapper.CurrencyMapper;
import com.hyperbank.types.currency.service.CurrencyService;

import io.github.paulmarcelinbejan.toolbox.exception.functional.FunctionalException;
import io.github.paulmarcelinbejan.toolbox.utils.validation.ValidatorUtils;
import io.github.paulmarcelinbejan.toolbox.web.response.OkResponse;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;

@RestController
@RequiredArgsConstructor
@RequestMapping("/api/currency")
public class CurrencyRestController {

    private final CurrencyService currencyService;
    
    private final CurrencyMapper currencyMapper;

    @GetMapping(value = "/{id}", produces = MediaType.APPLICATION_JSON_VALUE)
    public @ResponseBody CurrencyResponse findById(@PathVariable Integer id) throws FunctionalException {
        return currencyMapper.toResponse(currencyService.findById(id));
    }

    @GetMapping(value = "/", produces = MediaType.APPLICATION_JSON_VALUE)
    public @ResponseBody List<CurrencyResponse> findAll() {
        return currencyMapper.toResponses(currencyService.findAll());
    }

}

and on that one, there are no issue:

enter image description here

any idea ?

Upvotes: 2

Views: 693

Answers (3)

sothi
sothi

Reputation: 1

(VS CODE USER) You can also use the "Java: Clean java Language Server Workspace" option:

Open the Command Palette with Ctrl+Shift+P (or Cmd+Shift+P on macOS). Type and select Java: Clean java Language Server Workspace. then (For Maven: mvn clean install For Gradle: ./gradlew clean build)

Upvotes: 0

T.Rex
T.Rex

Reputation: 121

If you don't use Maven (in debug mode for example), you can configure your IDE and add the -parameters option. Everything is explained here :

Upgrading to Spring Framework 6.x

Sometimes it is also necessary to manually configure your IDE.

In IntelliJ IDEA, open Settings and add -parameters to the following field.

Build, Execution, Deployment → Compiler → Java Compiler → Additional command line parameters

In Eclipse IDE, open Preferences and activate the following checkbox.

Java → Compiler → Store information about method parameters (usable via reflection)

Upvotes: 0

Magesh Priya
Magesh Priya

Reputation: 26

Reason : This problem arises because Swagger, a tool that helps you document your API, need to know the names of the variable you use in your code. But, sometimes ,the java compiler doesn't save this information by default.So, Swagger get confused and can't show the correct documentation for your API.

Solution : To fix that, you need to tell the java compiler to save this information. once you do that, Swagger will find the pathvariable name and display the correct documentation for your API.

Add (Maven pom.xml file)

        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <compilerArgs>
                        <arg>-parameters</arg>
                    </compilerArgs>
                </configuration>
            </plugin>
        </plugins>

Upvotes: 1

Related Questions