【问题标题】:In spring, how about if PathVariable contains RequestMapping value在spring中,PathVariable是否包含RequestMapping值呢
【发布时间】:2018-07-11 09:19:12
【问题描述】:

如果我想使用 RequestMapping = "/{content}" 创建一个基本控制器来处理一般情况。但是对于一些特定的内容,我想为这种特殊情况创建一个具体的控制器,并从那个基本控制器继承。

例如:

@RequestMapping(value = "/{content}")
class ContentController {

    public ContentController(@PathVariable String content) { ... }

}


@RequestMapping(value = "/specialContent")
class SpecialContentController extends ContentController {

    public SpecialContentController() { super("specialContent"); }

    // overwrite sth
    ....

} 

这合法吗?还是其他更好的实现?

【问题讨论】:

    标签: spring request-mapping path-variables


    【解决方案1】:

    您似乎对 spring 中的控制器如何工作感到困惑。

    控制器是singleton,它在应用程序启动时创建,并调用其方法来处理传入请求。

    因为您的控制器不是为每个请求创建的,而是在处理任何请求之前创建的,所以您不能在构造函数中使用路径变量 - 既因为在创建实例时没有关于它的值的信息,也因为您将希望它反映当前正在处理的请求,并且由于控制器可以同时处理许多多个请求,因此您不能将其存储为类属性,否则多个请求会相互干扰。

    要实现您想要的,您应该使用方法并组合它们,如下所示:

    @RestController
    public class ContentController {
    
        @GetMapping("/specialContent")
        public Map<String, String> handleSpecialContent() {
            Map<String, String> map = handleContent("specialContent");
            map.put("special", "true");
            return map;
        }
    
        @GetMapping("/{content}")
        public Map<String, String> handleContent(@PathVariable String content) {
            HashMap<String, String> map = new HashMap<>();
            map.put("content", content);
            return map;
        }
    
    }
    

    注意{content:^(?!specialContent$).*$} 中的正则表达式,以确保 Spring 永远不会将 specialContent 路由到那里。你可以得到正则表达式 here 的解释并玩弄它here

    如果我们进行测试,您会发现它有效:

    $ http localhost:8080/test
    HTTP/1.1 200 
    Content-Type: application/json;charset=UTF-8
    Date: Thu, 01 Feb 2018 08:18:11 GMT
    Transfer-Encoding: chunked
    
    {
        "content": "test"
    }
    
    $ http localhost:8080/specialContent
    HTTP/1.1 200 
    Content-Type: application/json;charset=UTF-8
    Date: Thu, 01 Feb 2018 08:18:15 GMT
    Transfer-Encoding: chunked
    
    {
        "content": "specialContent",
        "special": "true"
    }
    

    【讨论】:

      【解决方案2】:

      @PathVariable 不应在构造函数中使用。

      【讨论】:

      • 你应该用更多信息和解释来充实你的答案为什么你不应该在构造函数中使用@PathVariable
      猜你喜欢
      • 2011-01-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-02-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多