8

我正在尝试将此 Google App Engine maven 服务器存储库重写为 Spring。

我的 URL 映射有问题。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
    

目录文件的原始应用程序映射。

使用@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 调度程序。

4

5 回答 5

1

我曾经遇到过类似的问题,也是关于 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您需要进行一些字符串解析。您可以requestUriServletUriComponentsBuilder

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
   ...
}
于 2020-04-08T12:38:41.743 回答
0

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

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

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

于 2020-04-13T15:28:16.323 回答
0

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

\/{1}$

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

于 2020-04-08T10:04:18.023 回答
0

好吧,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));
        }

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

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

于 2020-04-13T11:41:42.433 回答
-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    
于 2020-04-06T23:56:00.113 回答