【问题标题】:Spring request mapping with regex like in javax.ws.rs使用正则表达式的 Spring 请求映射,如 javax.ws.rs
【发布时间】:2020-07-15 23:21:04
【问题描述】:

我正在尝试将this Google App Engine maven server repository 重写为 Spring。

我的网址映射有问题。 Maven repo 服务器标准如下所示:

  1. URL 以斜线结尾,指向一个文件夹,例如:

    http://127.0.0.1/testDir/
    http://127.0.0.1/testDir/testDir2/
    
  2. 所有其他(末尾不带斜线)指向文件,例如:

    http://127.0.0.1/testFile.jar
    http://127.0.0.1/testFile.jar.sha1
    http://127.0.0.1/testDir/testFile2.pom
    http://127.0.0.1/testDir/testFile2.pom.md5
    

directoriesfiles 的原始应用映射。

使用了 @javax.ws.rs.Path 的注解,它支持的正则表达式与 Spring 不同。

我尝试了一堆组合,例如这样的:

@ResponseBody
@GetMapping("/{file: .*}")
public String test1(@PathVariable String file) {
    return "test1 " + file;
}

@ResponseBody
@GetMapping("{dir: .*[/]{1}$}")
public String test2(@PathVariable String dir) {
    return "test2 " + dir;
}

但我不知道如何在 Spring 应用程序中以正确的方式执行此操作。

我想避免编写自定义 servlet 调度程序。

【问题讨论】:

  • 您没有在这两种模式中转义 / char。可能是你的问题。

标签: java regex spring mapping javax.ws.rs


【解决方案1】:

试试这个解决方案:

@GetMapping("**/{file:.+?\\..+}")
public String processFile(@PathVariable String file, HttpServletRequest request) {   
    return "test1 " + file;
}

@GetMapping("**/{dirName:\\w+}")
public String processDirectory(@PathVariable String dirName, HttpServletRequest request) {
    String dirPath = request.getRequestURI();
    return "test2 " + dirPath;
}

问题中 URI 的结果:

test2 /testDir/
test2 /testDir/testDir2/

test1 testFile.jar
test1 testFile.jar.sha1
test1 testFile2.pom
test1 testFile2.pom.md5    

【讨论】:

    【解决方案2】:

    不知道你的java代码,但是如果你一次验证一个路径,你可以检查字符串是否以“/”结尾的文件夹和不是文件的字符串

    \/{1}$
    

    这个正则表达式只是检查字符串是否以“/”结尾,如果有匹配,你有一个文件夹,如果没有,你有一个文件

    【讨论】:

      【解决方案3】:

      我曾经遇到过类似的问题,也是关于 Maven 端点的 Spring 实现。

      对于文件端点,你可以这样做

      /**
       * An example Maven endpoint for Jar files
       */
      @GetMapping("/**/{artifactId}/{version}/{artifactId}-{version}.jar")
      public ResponseEntity<String> getJar(@PathVariable("artifactId") String artifactId, @PathVariable("version") String version) {
         ...
      }
      

      这为您提供了artifactIdversion,但对于groupId,您需要进行一些字符串解析。您可以在ServletUriComponentsBuilder 的帮助下获取当前的requestUri

      String requestUri = ServletUriComponentsBuilder.fromCurrentRequestUri().build().toUri().toString();
      // requestUri = /api/v1/com/my/groupId/an/artifact/v1/an-artifact-v1.jar
      

      对于文件夹端点,我不确定这是否可行,但您可以尝试一下

      @GetMapping("/**/{artifactId}/{version}")
      public ResponseEntity<String> getJar(@PathVariable("artifactId") String artifactId, @PathVariable("version") String version) {
         // groupId extracted as before from the requestUri
         ...
      }
      

      【讨论】:

        【解决方案4】:

        嗯,Spring 中没有其他特定标准,而不是您使用它的方式。但是,如果您可以自定义 URL,那么我有一种特殊的方法来区分目录和文件。这将增加应用程序的可扩展性和可读性,并为您减少大量代码。

        您现在的代码

        @ResponseBody
        @GetMapping("/{file: .*}")
        public String test1(@PathVariable String file) {
            return "test1 " + file;
        }
        
        @ResponseBody
        @GetMapping("{dir: .*[/]{1}$}")
        public String test2(@PathVariable String dir) {
            return "test2 " + dir;
        }
        

        在您的控制器类中将上述代码更改为如下

        private final Map<String, String> managedEntities=ImmutableMap.of(
                "file","Type_Of_Operation_You_want_For_File",
                "directory","Type_Of_Operation_You_want_For_Directory"
                );
        
        @GetMapping(path = "/{type:file|directory}")
        public String myFileOperationControl(@PathVariable String type){
                return "Test"+managedEntities.get(type));
                }
        

        然后按照您想要的方式进一步处理您的业务逻辑。如果您有任何问题,请告诉我。

        注意:请根据您的需要简单地增强端点。

        【讨论】:

          【解决方案5】:

          Spring 不允许匹配跨越多个路径段。路径段是路径分隔符 (/) 上路径的分隔值。所以没有正则表达式组合会让你到达那里。 Spring 5 虽然只允许使用 ** 或 {*foobar} 在 foobar uri 模板变量中捕获反应堆栈的跨多个路径段,但我认为这对你没有用。

          您的选择有限。如果可能的话,我认为最好的选择是使用与 / 不同的分隔符,您可以使用正则表达式。

          其他选项(这是混乱的)捕获所有(**)端点并从请求中读取路径并确定它是文件还是目录路径并执行操作。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2023-02-01
            • 1970-01-01
            • 2015-06-19
            • 2016-09-16
            • 2013-08-03
            • 1970-01-01
            • 2017-04-06
            相关资源
            最近更新 更多