简体   繁体   English

如何使用 Spring 基于查询参数键和值进行过滤

[英]How to filter based on query parameter key and value with Spring

Our application submits jobs to another service on either a monthly or quarterly basis.我们的应用程序按月或按季度将工作提交给另一个服务。 We have an API that allows us to trigger one of the following scenarios:我们有一个 API 允许我们触发以下场景之一:

  1. Submit a single job using its ID使用其 ID 提交单个作业
  2. Submit all jobs that are scheduled to run each month提交计划每月运行的所有作业
  3. Submit all jobs that are scheduled to run each quarter提交计划在每个季度运行的所有作业

Currently we have 3 different API endpoints for the 3 scenarios, but would like to update the API to use a structure similar to the following:目前我们有 3 个不同的 API 端点用于 3 个场景,但想更新 API 以使用类似于以下的结构:

  1. /submit?type=single&id=123
  2. /submit?type=all&frequency=monthly
  3. /submit?type=all&frequency=quarterly

My question is how can we achieve this kind of mapping inside a Controller class so that each of the 3 API's has its own method, uniquely identified by the key-values provided to it.我的问题是我们如何在 Controller class 中实现这种映射,以便 3 个 API 中的每一个都有自己的方法,由提供给它的键值唯一标识。

Currently we have 3 methods similar to the following, which allows us to share the API path between the 3 methods, but differentiate them based on the params value.目前我们有 3 种类似如下的方法,这使得我们可以在 3 种方法之间共享 API 路径,但根据params值区分它们。 Is there a similar approach we could use that allows us to filter based on both the query param key and value?是否有类似的方法可以使用,允许我们根据查询参数键和值进行过滤?

@PostMapping(value = "/submit", params = "monthly")
@ResponseStatus(HttpStatus.ACCEPTED)
public void submitAllMonthlyJobs() {
// Code
}

One approach is to use a single method that handles all 3 scenarios, and inside that method we fork to one of the 3 options based on the query params.一种方法是使用一种方法来处理所有 3 个场景,在该方法中,我们根据查询参数分叉到 3 个选项之一。 But I'm hopeful there's a cleaner approach where Spring handles this for us.但我希望有一种更清洁的方法,让 Spring 为我们处理这个问题。

Thanks for your help.谢谢你的帮助。

Each request mapping like @RequestMapping , @GetMapping , @PostMapping etc. can be filtered not only by path , but also by params .每个请求映射,如@RequestMapping@GetMapping@PostMapping等,不仅可以通过path过滤,还可以通过params过滤。 Your endpoint with the three mappings could look like this:具有三个映射的端点可能如下所示:

@RestController
public class JobEndpoint {

    @PostMapping(path = "submit", params = "type=single")
    public void submitSingleJob(@RequestParam("id") long id) {
        System.out.println("submitting single job " + id);
    }

    @PostMapping(path = "submit", params = {"type=all", "frequency=monthly"})
    public void submitMonthlyJobs() {
        System.out.println("submitting monthly jobs");
    }

    @PostMapping(path = "submit", params = {"type=all", "frequency=quarterly"})
    public void submitQuarterlyJobs() {
        System.out.println("submitting quarterly jobs");
    }
}

And just to be sure that it works:只是为了确保它有效:

@WebMvcTest
@ExtendWith(OutputCaptureExtension.class)
class JobEndpointTest {

    @Autowired
    private MockMvc mvc;

    @Test
    void submitSingleJob(CapturedOutput output) throws Exception {
        mvc.perform(post("/submit?type=single&id=123")).andExpect(status().isOk());
        assertThat(output).contains("submitting single job 123");
    }

    @Test
    void submitMonthlyJobs(CapturedOutput output) throws Exception {
        mvc.perform(post("/submit?type=all&frequency=monthly")).andExpect(status().isOk());
        assertThat(output).contains("submitting monthly jobs");
    }

    @Test
    void submitQuarterlyJobs(CapturedOutput output) throws Exception {
        mvc.perform(post("/submit?type=all&frequency=quarterly")).andExpect(status().isOk());
        assertThat(output).contains("submitting quarterly jobs");
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM