I want to create enpoint with dynamic uri using regex in uri pattern.
URI template: [host]/{regexpart}/endpoint
Examples of dynamic uri:
[host]/a/endpoint
[host]/b/endpoint
Also I want to use slashes inside regex part of uri path, like that:
[host]/a/b/endpoint
[host]/a/b/c/d/endpoint
I have enpoint like this:
#GetMapping(path = "/{regexpart:[a-z/]*}/endpoint")
public DeferredResult<ResponseEntity<?>> enpoint(#PathVariable("regexpart") String regexpart) {
// Some logic
}
But it isn't working. Is there way to define the regex to use slashes inside it? Thanks!
The way you have it written, the regex pattern is limited to be within 1 path segment.
What you may be looking for is something like
#GetMapping(path = "/**/endpoint")
the ** will allow for any characters across multiple path segments.
This will allow any valid path within your [host] that ends in /endpoint
If you need to limit that to certain characters (like just [a-z], this should get you on the right track.
Related
I'm writing my own web crawler in Java, and I'm using URI#resolve to resolve URLs that appear on every HTML page that my crawler encounters. In certain cases, it's behaving in an unexpected way.
For example, while crawling https://hacks.mozilla.org, I notice that one of the URLs extracted is https://hacks.mozilla.orgabout/ (indeed, if you look at the HTML source for that page, you will find an <a href="about/">). I did some testing, and got these results:
URI uri1 = new URI("https://hacks.mozilla.org").resolve("about/");
System.out.println(uri1); // => https://hacks.mozilla.orgabout/
URI uri2 = new URI("https://hacks.mozilla.org/").resolve("about/");
System.out.println(uri2); // => https://hacks.mozilla.org/about/
I don't know how practical it is to attempt to mitigate this issue by manually adding the slash after the base URL, but I want to know if there is an actual non-hacky fix to this problem.
I did a little more experimentation, and realized that this happens when the path element is empty (null or 0-length string):
URI uri3 = new URI("http", null, "hacks.mozilla.org", 80, "", null, null).resolve("about/");
System.out.println(uri3); // => http://hacks.mozilla.org:80about/
URI constructor Javadoc states that (from http://docs.oracle.com/javase/7/docs/api/java/net/URI.html) :
If a path is given then it is appended. Any character not in the unreserved, punct, escaped, or other categories, and not equal to the slash character ('/') or the commercial-at character ('#'), is quoted.
So just filling this parameter with one of those accepted character will solve your problem.
Is there a clean and spec-conformant way to define a custom URL scheme that acts as an adapter on the resource returned by another URL?
I have already defined a custom URL protocol which returns a decrypted representation of a local file. So, for instance, in my code,
decrypted-file:///path/to/file
transparently decrypts the file you would get from file:///path/to/file. However, this only works for local files. No fun! I am hoping that the URL specification allows a clean way that I could generalize this by defining a new URL scheme as a kind of adapter on existing URLs.
For example, could I instead define a custom URL scheme decrypted: that could be used as an adapter that prefixes another absolute URL that retrieved a resource? Then I could just do
decrypted:file:///path/to/file
or decrypted:http://server/path/to/file or decrypted:ftp://server/path/to/file or whatever. This would make my decrypted: protocol composable with all existing URL schemes that do file retrieval.
Java does something similar with the jar: URL scheme but from my reading of RFC 3986 it seems like this Java technology violates the URL spec. The embedded URL is not properly byte-encoded, so any /, ?, or # delimiters in the embedded URL should officially be treated as segment delimiters in the embedding URL (even if that's not what JarURLConnection does). I want to stay within the specs.
Is there a nice and correct way to do this? Or is the only option to byte-encode the entire embedded URL (i.e., decrypted:file%3A%2F%2F%2Fpath%2Fto%2Ffile, which is not so nice)?
Is what I'm suggesting (URL adapters) done anywhere else? Or is there a deeper reason why this is misguided?
There's no built-in adaptor in Cocoa, but writing your own using NSURLProtocol is pretty straightforward for most uses. Given an arbitrary URL, encoding it like so seems simplest:
myscheme:<originalurl>
For example:
myscheme:http://example.com/path
At its simplest, NSURL only actually cares if the string you pass in is a valid URI, which the above is. Yes, there is then extra URL support layered on top, based around RFC 1808 etc. but that's not essential.
All that's required to be a valid URI is a colon to indicate the scheme, and no invalid characters (basically, ASCII without spaces).
You can then use the -resourceSpecifier method to retrieve the original URL and work with that.
I am writing a Java based REST web service using jersey. The entity for which I am writing the web service is a media file. A client requesting for a media file need to send the path and filename as the path param. The media path allowed can be up to a depth of five directories. Now the challenge is to write a single method to handle all the path depth possibilities. Using the path param is the only allowed choice in terms of the business scenario. Here is the method contract, which handles a media file request:
public Response getMediaFile(#PathParam("path") String path,
#PathParam("filename") String filename);
Problem with this method is that, if the request is like /media/filedir1/filedir2/filename then filename will not be fetch properly.
The solution I have implemented is that, I have overloaded this method to handle all the directories depth but I am not really convinced that this is the best solution:
public Response getMediaFile(#PathParam("path1") String path1,
#PathParam("path2") String path2,
#PathParam("filename") String filename);
public Response getMediaFile(#PathParam("path1") String path1,
#PathParam("path2") String path2,
#PathParam("path3") String path3,
#PathParam("filename") String filename);
And so on.
You should be able to use a regular expression in your #PathParam annotation to handle all the path filtering logic. For example, this will give you a filepath that is at most 5 directories down:
#Path("{path:(?:[^/]+/){0,4}[^/]+}")
Then you'd inject that value into a method as expected:
#Path("{path:(?:[^/]+/){0,4}[^/]+}")
/* Other attributes too... */
public Response getMediaFile(#PathParam("path") String path) {
File file=new File(MEDIA_HOME_DIR, path);
if(file.exists()) {
// Process file
}
else {
// No such file
}
}
The regular expression will handle the "five directory" limit, and if the number changes from five in the future it'll be easy to fix. You could easily filter the filenames more carefully too, if you needed to match only .jpg files (for example).
With that solved, you'll just have to serve the media. :)
The JAX-RS Specification tells us about URI Templates:
Template parameters can optionally specify the regular expression used to match their values. The default value matches any text and terminates at the end of a path segment
If you want to match across "the end of a path segment", use a proper regular expression. This one works for you:
#Path("{path:.*}/{filename}")
I have a question about URI template variables.
I need to manage an URI with the form:
http://netlocation:port/application_path/{variable}
the variable can be a path itself, i.e. something like
this/variable/is/a/path
so that the complete URI appears to be
http://netlocation:port/application_path/this/variable/is/a/path
how can I manage that?
Use the "+" operator in order to avoid escaping the "/" character:
http://netlocation:port/application_path/{+foo}
You can try on URI Template Parser Online
You could use query parameters and just encode the path variable in the standard way:
http://netlocation:port/application_path?path=%2Fthis%2Fvariable%2Fisapath
Have you looked at http://static.springsource.org/spring/docs/3.0.x/javadoc-api/org/springframework/web/util/UriTemplate.html ?
How do you encode a path parameter (not form-url-encoded) but just a single URL that's appended in the format:
public String method(#PathParam("url") String url) {
}
There are lots of references to form URL encoding, but I want to simply encode a string as in the above.
Like mentioned in the previous answer URLEncoder can only be used for query paramaters, not path parameters. This matters e.g. for spaces which are a + in the query parameter but a %20 in the path.
org.springframework.web.util.UriUtils.encodePath()
can be used. Also using an org.apache.http.client.utils.URIBuilder would work. setPath is escaping the path part here. Also pure Java by using a constructor of java.net.Uri works.
Why would you want to *en*code it there, if anything wouldn't you want to *de*code it? In any case, you would call the standard URLEncoder.