处理不明确的处理程序方法映射约定
Posted
技术标签:
【中文标题】处理不明确的处理程序方法映射约定【英文标题】:Handle Ambiguous handler methods mapped convention 【发布时间】:2022-01-05 03:09:08 【问题描述】:我有 Chemical
资源的 2 个 GET 端点:
在第一个端点中,我想要化学对象的 id,这在每种化学物质中都是唯一的。
@GetMapping("/chemical/id")
在第二个 GET 端点中,我想要与特定实验室相对应的所有化学品(实验室是强制性的)。
@GetMapping("/chemical/labKey")
Spring无法区分/chemical/myLab
和/chemical/12
,这个我可以理解。我知道我应该更改端点映射,但是如何更改?有人可以为这种特定情况提出一个好的约定吗?例如。 @GetMapping("/chemical/labKey/id"
对我来说似乎是多余的,因为我不使用 labKey
pathVariable,我只需要 id
,我会这样称呼:chemicalService.findById(id)
。
【问题讨论】:
【参考方案1】:我认为最好的方法是使用两个端点:
/chemical/id
将使用 @GetMapping("/chemicals/id")
按标识符获取您的化学品。
第二个将使用查询参数labKey
根据实验室密钥进行过滤。这将有一个通用的@GetMapping("/chemicals")
。 chemicals?labKey=lab1
将是 URI。
以下是我的实现。 控制器类
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
@Service
public class ChemicalService
private List<ChemicalDTO> chemicals = Arrays.asList(
new ChemicalDTO(1L, "chem1", "lab1"),
new ChemicalDTO(2L, "chem2", "lab2"),
new ChemicalDTO(3L, "chem3", "lab1"),
new ChemicalDTO(4L, "chem4", "lab3")
);
public Optional<ChemicalDTO> getChemicalById(Long id)
return chemicals.stream().filter(e -> e.getId().equals(id)).findAny();
public List<ChemicalDTO> getChemicalByLabKey(String labKey)
if( labKey.isBlank() || labKey.isEmpty() ) return new ArrayList<>();
return chemicals
.stream()
.filter(e -> e.getLabKey().equals(labKey))
.collect(Collectors.toList());
服务类
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
@Service
public class ChemicalService
private List<ChemicalDTO> chemicals = Arrays.asList(
new ChemicalDTO(1L, "chem1", "lab1"),
new ChemicalDTO(2L, "chem2", "lab2"),
new ChemicalDTO(3L, "chem3", "lab1"),
new ChemicalDTO(4L, "chem4", "lab3")
);
public Optional<ChemicalDTO> getChemicalById(Long id)
return chemicals.stream().filter(e -> e.getId().equals(id)).findAny();
public List<ChemicalDTO> getChemicalByLabKey(String labKey)
if( labKey.isBlank() || labKey.isEmpty() ) return new ArrayList<>();
return chemicals
.stream()
.filter(e -> e.getLabKey().equals(labKey))
.collect(Collectors.toList());
DTO 类
import lombok.AllArgsConstructor;
import lombok.Data;
@Data
@AllArgsConstructor
public class ChemicalDTO
private Long id;
private String name;
private String labKey;
您可以在REST resource naming conventions 和示例here 中找到更多信息
【讨论】:
【参考方案2】:如果路径相同且路径变量的数量也相同,则以下是处理这种情况的干净方法。
你可以考虑下面的代码sn-p
@GetMapping(value = "/chemical", params = "id")
public String getChemicalById(@RequestParam(value = "id") String id)
return "ID method: "+id;
@GetMapping(value = "/chemical", params = "label")
public String getChemicalByLabel(@RequestParam(value = "label") String label)
return "Label method: "+label;
网址如下:
/chemical?id=ID /chemical?label=LABEL【讨论】:
以上是关于处理不明确的处理程序方法映射约定的主要内容,如果未能解决你的问题,请参考以下文章
Spring MVC-处理程序映射(Handler Mapping)-控制器类名称处理程序映射(Controller Class Name Handler Mapping)示例(转载实践)