Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring request mapping with regex like in javax.ws.rs

I'm trying rewrite this Google App Engine maven server repository to Spring.

I have problem with URL mapping. Maven repo server standard looks like this:

  1. URL with slash at the end, points to a folder, example:

    http://127.0.0.1/testDir/
    http://127.0.0.1/testDir/testDir2/
    
  2. all others (without slash at the end) point to files, example:

    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
    

Original app mapping for directories and for files.

There were used annotations @javax.ws.rs.Path which supports regexy differently than Spring.

I tried bunch of combinations, for example something like this:

@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;
}

But I can't figure out how to do this in right way in Spring application.

I'd like to avoid writing a custom servlet dispatcher.

like image 875
Artur Węgrzyn Avatar asked Apr 03 '20 18:04

Artur Węgrzyn


People also ask

What is the use of@ RequestMapping in Spring?

One of the most important annotations in spring is the @RequestMapping Annotation which is used to map HTTP requests to handler methods of MVC and REST controllers. In Spring MVC applications, the DispatcherServlet (Front Controller) is responsible for routing incoming HTTP requests to handler methods of controllers.

What is the use of@ RequestMapping annotation?

RequestMapping annotation is used to map web requests onto specific handler classes and/or handler methods. @RequestMapping can be applied to the controller class as well as methods.

How@ RequestMapping works?

The @RequestMapping annotation can be applied to class-level and/or method-level in a controller. The class-level annotation maps a specific request path or pattern onto a controller. You can then apply additional method-level annotations to make mappings more specific to handler methods.

What happens when two methods with different view has same request mapping?

Unfortunately, this is not possible. The request mapping has to be unique otherwise the application can't determine which method the incoming request should be mapped to.


1 Answers

I had a similar problem once, also regarding a Spring implementation of a maven endpoint.

For the file endpoints, you could do something like this

/**
 * 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) {
   ...
}

This gives you the artifactId and the version, but for the groupId you would need to do some string parsing. You can get the current requestUri with the help of the ServletUriComponentsBuilder

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

For the folder endpoints, I'm not sure if this will work, but you can give it a try

@GetMapping("/**/{artifactId}/{version}")
public ResponseEntity<String> getJar(@PathVariable("artifactId") String artifactId, @PathVariable("version") String version) {
   // groupId extracted as before from the requestUri
   ...
}
like image 111
Ahmed Sayed Avatar answered Oct 25 '22 21:10

Ahmed Sayed