java - Java Spring boot Api:控制器行为取决于查询参数
问题描述
基本上我被迫使用如下路径 url
GET /accounts/<accountNumber::string>/reports?type=<DAILY>&date=<YYYY-MM-DD>
问题是我的行为高度依赖于我的报告类型,正如您在我的示例中看到的“每日”。所以我正在寻找一种设计模式,它允许我模拟一个控制器工厂,该工厂将为我的每种报告类型实例化特定的控制器。例如,我将有一个 DefaultController 具有一个名为 getReport 的方法,该方法将映射到我的 GET 请求,并将生成和返回报告的任务委托给其他特定控制器(即:DailyReportController)。
我希望我的设计尽可能地依赖于 SOLID 原则和其他干净的代码和可维护性原则。因此,即使我要在一个月内添加一个报告类型,我只需要在我的 ReportType 枚举中添加一个新的 TypeReportController 和一个值,并且在我的控制器和我的服务中没有无限的方法
解决方案
我已阅读您的描述。但我认为可以有一个控制器端点,您的控制器将选择不同的服务实现。就像如果您的参数是DAILY那么它将选择DailyReportServiceImpl并选择其他实现取决于您的报告类型。您可以尝试以下设计:
@RestController
@RequestMapping
public class ReportController {
@Autowired
ReportService reportService;
@GetMapping(value = "/accounts/{accountNumber}/reports")
public Report getReport(@PathParam("accountNumber") String accountNumber,
@RequestParam("type") String type,@RequestParam("date")Date date){
if(ReportEnum.DAILY.name().equals(type))
{
reportService = new DailyReportServiceImpl();
}else if(ReportEnum.MONTHLY.name().equals(type)){
reportService = new MonthlyReportService();
}
return reportService.getReport();
}
}
并为服务声明一个接口:
public interface ReportService {
public Report getReport();
}
然后从 dailyreportservice 和其他服务中实现这个服务: DailyReportServiceImpl 将是这样的:
public class DailyReportServiceImpl implements ReportService {
@Override
public Report getReport() {
return null;
}
}
MonthlyReportService 将是这样的:
public class MonthlyReportService implements ReportService {
@Override
public Report getReport() {
return null;
}
}
声明一个报告类:
public class Report {
}
那么你需要定义一个枚举:
public enum ReportEnum {
DAILY("DAILY"),
MONTHLY("MONTHLY"),
YEARLY("YEARLY");
private String name;
ReportEnum(String name) {
this.name = name;
}
public String getName() {
return name();
}
}
NB: : 无论如何,你定义不同控制器端点的具体原因是什么?
如果是,您可以以另一种方式定义端点:像这样。
@RestController
@RequestMapping
public class ReportController {
@Autowired
ReportService reportService;
@GetMapping(value = "/accounts/{accountNumber}/reports/DAILY")
public Report getReportDaily(@PathParam("accountNumber") String accountNumber,
@RequestParam("date")Date date){
reportService = new DailyReportServiceImpl();
return reportService.getReport();
}
@GetMapping(value = "/accounts/{accountNumber}/reports/MONTHLY")
public Report getReportMonthly(@PathParam("accountNumber") String accountNumber,
@RequestParam("date")Date date){
reportService = new MonthlyReportService();
return reportService.getReport();
}
}
但我认为前一个是最好的设计。
推荐阅读
- linux-kernel - Raspberry PI 3 b+ IO 外设在 Linux 内核虚拟地址空间中映射到哪里?
- ios - Swift4 中的异步 DispatchQueue 和多线程
- c# - 为什么没有在 MigrationDbContext 上建模 AppUser?
- function - 电量查询中的迭代计算
- ms-word - 如何自动更新 Word 的 Office.js 加载项中的字段?
- elasticsearch - elasticsearch中使用父子关系有哪些注意事项
- html - HTML 卡片图标不固定在该给定位置;他们正在改变卡的名称
- javascript - 将 Java 代码转换为 JS(jsweet 错误)
- scala - 类型参数 [Nothing,X] 不符合类型参数界限 [T,X<: XX[T]]>
- android - 长按动作的搜索栏