猿问

如何为带请求参数和不带请求参数的请求定义不同的 Spring MVC 请求处理程序?

Spring MVC 有没有办法为没有请求参数的请求和有请求参数的请求定义不同的处理程序?


有一个简单的控制器:


@RestController

@RequestMapping("/strategies")

public class StrategyController {

    ...


    @GetMapping

    public List<Strategy> getAll() {

        return service.getBeans().stream()

            .map(mapper::toDto)

            .collect(toList());

    }


    @GetMapping

    public List<Strategy> search(StrategyFilter filter) {

        return service.search(new StrategySearchSpecification(

                filter.getCode(),

                filter.getName(),

                filter.getType()

            )).stream()

            .map(mapper::toDto)

            .collect(toList());

    }

}


我想要getAll()方法来处理没有请求参数的请求: /strategies


我想要search(StrategyFilter filter)方法来处理带有请求参数的请求: /strategies?name=SomeName&type=SomeType


似乎无法通过params属性来区分这种情况,因为可以省略@GetMapping任何属性。StrategyFilter


在此配置中,我得到一个明显的错误:


Caused by: java.lang.IllegalStateException: Ambiguous mapping. 

Cannot map 'strategyController' method 

public List<Strategy> StrategyController.getAll() to {[/strategies],methods=[GET]}: 


There is already 'strategyController' bean method public List<Strategy> StrategyController.search(StrategyFilter) mapped.

当然也可以这样写:


@GetMapping

public List<Strategy> get(StrategyFilter filter) {

    return noFilterProvided(filter) ? getAll() : search(filter);

}

但是每次过滤器的属性数量发生变化时,都需要更改“noFilterProvided(StrategyFilter filter)”。


天涯尽头无女友
浏览 108回答 2
2回答

翻过高山走不出你

Spring 框架使用基于点的匹配。它从可用的匹配中选择最高的匹配。通过标准越多的人得分越高。如果您在一个匹配中定义了请求的查询参数,那么当参数存在时它将被接受。其他情况另说。要定义请求的参数,请将它们作为直接属性传递,而不是作为 StrategyFilter 属性传递。在缺少参数的情况下,这样的实例初始化也成功(这些属性不会被初始化,它们保持默认状态:“”/0/false)。所以会出现模棱两可的匹配错误。最后:使用直接属性而不是 StrategyFilter。您设计的其他问题是直接 StrategySearchSpecification 实例化。它不是以这种方式进行单元测试的。将其定义为 Spring 组件。@Component@Getter // Lombok annotation to generate getter methods@Setter // Lombok annotation to generate setter methodspublic class StrategySearchSpecification{&nbsp; private CODE_TYPE code;&nbsp; private String name;&nbsp; private TYPE_TYPE type;}并将其作为参数注入(正确的实现/模拟)并使用它的设置方法。@RestController@RequestMapping("/strategies")public class StrategyController {&nbsp; &nbsp; ...&nbsp; &nbsp; @GetMapping&nbsp; &nbsp; public List<Strategy> getAll() {&nbsp; &nbsp; &nbsp; &nbsp; return service.getBeans().stream()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .map(mapper::toDto)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .collect(toList());&nbsp; &nbsp; }&nbsp; &nbsp; @GetMapping&nbsp; &nbsp; public List<Strategy> search(@RequestParam CODE_TYPE code, @RequestParam String name, @RequestParam TYPE_TYPE type, StrategySearchSpecification specification ) {&nbsp; &nbsp; &nbsp; &nbsp; specification.setCode( code );&nbsp; &nbsp; &nbsp; &nbsp; specification.setName( name );&nbsp; &nbsp; &nbsp; &nbsp; specification.setType( type );&nbsp; &nbsp; &nbsp; &nbsp; return service.search( specification&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; )).stream()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .map(mapper::toDto)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .collect(toList());&nbsp; &nbsp; }}

心有法竹

如果StrategyFilter具有属性nameand type,这应该有效:@RestController@RequestMapping("/strategies")public class StrategyController {&nbsp; &nbsp; ...&nbsp; &nbsp; @GetMapping&nbsp; &nbsp; public List<Strategy> getAll() {&nbsp; &nbsp; &nbsp; &nbsp; return service.getBeans().stream()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .map(mapper::toDto)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .collect(toList());&nbsp; &nbsp; }&nbsp; &nbsp; @GetMapping("{name}/{type}")&nbsp; &nbsp; public List<Strategy> search(StrategyFilter filter) {&nbsp; &nbsp; &nbsp; &nbsp; return service.search(new StrategySearchSpecification(&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; filter.getCode(),&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; filter.getName(),&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; filter.getType()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; )).stream()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .map(mapper::toDto)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .collect(toList());&nbsp; &nbsp; }}
随时随地看视频慕课网APP

相关分类

Java
我要回答