【问题标题】:Spring MVC @PathVariable treated as @RequestParam [duplicate]Spring MVC @PathVariable 被视为@RequestParam [重复]
【发布时间】:2017-11-10 08:43:20
【问题描述】:

我有一个 spring mvc API(XML 中的配置),里面有多个服务。但是当我尝试使用包含路径变量/{theCurrencyCode}@RequestMapping 添加服务时,创建的资源不是我所期望的。

我的预期:

http://localhost:8080/api/v3/parameters/currencies/EUR

什么有效:

http://localhost:8080/api/v3/parameters/currencies/{theCurrencyCode}?theCurrencyCode=EUR

这是我的映射:

import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import java.util.List;

import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;

@RequestMapping(value = "v3/", produces = { APPLICATION_JSON_VALUE })
public interface ParametersApi {

  @RequestMapping(
      value = "/parameters/currencies/{theCurrencyCode}",
      produces = { "application/json" },
      method = RequestMethod.GET)
  ResponseEntity<List<Currency>> GetCurrencies(@PathVariable("theCurrencyCode") String theCurrencyCode);

}

实施:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;

import java.util.ArrayList;
import java.util.List;

@Controller
public class ParametersApiController implements ParametersApi{

  private final CurrenciesService service;

  @Autowired
  public ParametersApiController(CurrenciesService service) {
    this.service = service;
  }

  @Override
  public ResponseEntity<List<Currency>> GetCurrencies(String code) {

    final List<Currency> currencies = service.getCurrencies(code);

    return new ResponseEntity<>(currencies, HttpStatus.OK);
  }
}

Swagger UI 确认了这一点,将 theCurrencyCode 视为“参数类型”query 而不是 path

如何让我的@PathVariable 工作?

【问题讨论】:

  • 这个问题好像已经讨论过了here

标签: java spring rest spring-mvc


【解决方案1】:

您的方法实现中缺少路径变量。 所以要修复,你需要这样写:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;

import java.util.ArrayList;
import java.util.List;

@Controller
public class ParametersApiController implements ParametersApi{

    private final CurrenciesService service;

    @Autowired
    public ParametersApiController(CurrenciesService service) {
        this.service = service;
    }

    @Override
    public ResponseEntity<List<Currency>> GetCurrencies(@PathVariable String theCurrencyCode) {
        final List<Currency> currencies = service.getCurrencies(theCurrencyCode);
        return new ResponseEntity<>(currencies, HttpStatus.OK);
    }
}

【讨论】:

    【解决方案2】:

    带注释的方法参数并未传递给所有实现。所以这就是你需要重新声明它的原因。

    【讨论】:

    • 在实现中添加@PathVariable 有效。唯一奇怪的是,我有另一个 API 具有相同的接口/实现逻辑,并且它在实现中没有 @PathVariable 的情况下工作。
    【解决方案3】:

    将您的界面更改为:

    import org.springframework.http.ResponseEntity;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    
    import java.util.List;
    
    import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
    
    @RequestMapping(value = "v3/", produces = { APPLICATION_JSON_VALUE })
    public interface ParametersApi {
    
      @RequestMapping(
          value = "/parameters/currencies/{theCurrencyCode}",
          produces = { "application/json" },
          method = RequestMethod.GET)
      ResponseEntity<List<Currency>> GetCurrencies(@PathVariable String theCurrencyCode);
    
    }
    

    您的路径变量名称和 URL 路径名称应该匹配。无需在括号中指定参数名称。

    【讨论】:

    • 谢谢,但我尝试过这种方式,它正在做完全相同的事情......
    • 尝试在控制器中将code 更改为theCurrencyCode 以获取GetCurrencies() 参数。
    • 试过但没有成功
    猜你喜欢
    • 2011-04-01
    • 2015-08-28
    • 2012-11-22
    • 2018-05-05
    • 1970-01-01
    • 2013-11-17
    相关资源
    最近更新 更多