Java Restlets - Match arbitrarily long URI path parameter - java

Using Restlets you can route URIs using a system based on the URI template specification. I want to be able to route URIs which match the following pattern
http://www.blah.com/something/...arbitrarily long path.../somethingelse/
So, the following two URIs would be matched and routed the same:
http://www.blah.com/something/a/b/c/d/somethingelse/
and:
http://www.blah.com/something/z/y/x/w/v/somethingelse/
How can I achieve this using Restlets?
Cheers,
Pete

The most common way to set up routes is with a Router, like so:
router.attach("/path/to/resource", MyResource.class);
'attach' returns a Route, which has the method setMatchingMode, so you can do this:
router.attach("/path/to/resource", MyResource.class).setMatchingMode(Template.MODE_STARTS_WITH);
This sets the route to match any URL which starts with the supplied pattern.
I hope that's sufficient for your needs. I'm not aware of any built-in way to match URLs with a particular prefix and a particular suffix. But if that's specifically what you need, you could probably implement your own subclass of Template, Route, etc (I'm not sure which would be needed.)
I'm pretty sure that regex-based routing has been discussed on the Restlet mailing list; you may want to search there.

Related

Is there a way to use Google's Custom Methods with Jersey Resources?

I was looking for a way to make my JAX-RS APIs more readable and came across with Google's Custom Methods approach:
https://cloud.google.com/apis/design/custom_methods
I was looking for this because some of my entities perform more actions than I could express with traditional HTTP verbs. Google pattern is to use a colon (:) at the end of the URI, separating the entity/collection from the desired action.
I tried to apply this pattern to a simple Jersey resource, just to test how it could be done. I've got a resource class StudentDetailsResource annotated with #Path("students/{studentId}") and a few methods also annotated with #Path.
If my method has another entity before the custom method, then all is ok. Let's say the enrol method is annotated with
#Path("subjects/{subjectId}:enroll").
The problem rises when the action is right after the Resource Class URI, because #Path uses a URI Template that prefixWithSlash all sub-resources. So if I have a dropout method, the annotation would look like #Path(":dropout"), but the URI template would become /students/{studentId}/:dropout, an this /: would break in the matching phase.
I have read about Jersey Providers and ResourceDelegates, but I couldn't find a way to replace the URI Template default action of prefixWithSlash.
The question is: how can I apply Google's custom method approach or how can I avoid the default prefixWithSlash behaviour with Jersey?
Note: I know this is a silly example and there are other ways to solve this specific case, but I have more complex cases which can benefit from the custom methods.

Oracle SSO URL regex to exclude if URL has an specific param

Currently, we have SSO enabled in our web application and works well. But, when an user is configured in SSO but not in our web application, we are having a redirect loop.
We have noticed that, when this happens, webapp invokes an URL like this:
/login.jsp?errormsg=The+User%3A+SOMEUSER+doesn%27t+exist
And my configuration of enforced URLs is the next:
com.sun.identity.agents.config.notenforced.uri[0] = /
com.sun.identity.agents.config.notenforced.uri[1] = /-*-.jsp
com.sun.identity.agents.config.notenforced.uri[2] = /-*-.jsp*
com.sun.identity.agents.config.notenforced.uri[3] = /-*-.jsp?*
...
com.sun.identity.agents.config.notenforced.uri.invert = true
I enforce all jsps to be validated through SSO. But, what i want to do is to define an URI like:
If an .jsp is being invoked, but it doesn't have errormsg parameter in it, validate session through SSO;
But if an .jsp is being invoked and errormsg parameter is in the URL, don't validate it, let it go.
The thing is, can i use regular expressions on SSO URIs? Because those patterns
/-*-.jsp
as far as i know, aren't regular expressions.
How can i create that filter?
You're right in thinking the not enforced list pattern in AMAgent.properties isn't a regular expression. As it seems you've already discovered, it uses a far more limited wildcard matching syntax.
The answer to the question "Can I use regular expressions on SSO URIs?" seems to be no. Unfortunately what can be done here is very limited as the syntax does not include a way of excluding particular characters or phrases. Without further understanding the requirements, my best suggestion would be to use an exclude list rather than an include list:
com.sun.identity.agents.config.notenforced.uri[0] = /-*-.jsp?errormsg*
...
(with com.sun.identity.agents.config.notenforced.uri.invert = false)
Of course you may need to add many further entries to this list and it may become large but at least it is more compliant with Oracle's advice:
When the not-enforced list is inverted, the number of resources for
which the agent will not enforce access control is potentially very
large. The use of this feature should therefore be used with extreme
caution and only after extensive evaluation of the security
requirements of the deployed applications.

Handling Dot (.) Parameters in Java Jersey

I want to format my REST interface as follows:
myurl.com/resources/{resourceId}
I optionally want people to be able to provide the following variations to specify return formats:
myurl.com/resources.json/{resourceId}
I am using Jersey to provide my REST services. What is the best way to handle these parameters?
Should a create a separate class with a different #PATH notation, or can I have a single class and parse out that parameter? Are there any built in annotations that might handle this, similar to #PathParam or #QueryParam?
There already is a mechanism for this (as #digitaljoel already stated) - HTTP Accept header.
Jersey doesn't have any direct support for your usecase, but there is something similar - media type mapping feature, see
http://jersey.java.net/nonav/apidocs/1.12/jersey/com/sun/jersey/api/core/ResourceConfig.html#PROPERTY_MEDIA_TYPE_MAPPINGS
and
http://jersey.java.net/nonav/apidocs/1.12/jersey/com/sun/jersey/api/core/ResourceConfig.html#getMediaTypeMappings%28%29
Unfortunately for you it handles only URLs which have this "param" at the end, but it should not be very hard to take UriConnegFilter sources (http://java.net/projects/jersey/sources/svn/content/trunk/jersey/jersey-server/src/main/java/com/sun/jersey/api/container/filter/UriConnegFilter.java?rev=5698) and modify it to suit your needs.

Replacement for <servlet-mapping> in web.xml & Spring MVC

Because my URLs are really complex and each of the parts between the slashes depends on the content of my database, I suppose the is not sufficient for me. I suppose I need to write some URL parser, which goes through the url parts between the slash and calls some kind of handler.
Is there a way how to write such URL parser, which would get string and return an object, representing the current request, that would replace the ? I only managed to find simple tutorials which use only the url-routing defined by web.xml.
Thanks
Spring is extremely flexible, so you can customize URL parsing. Take a look on this tutorial http://static.springsource.org/spring/docs/3.0.0.M3/spring-framework-reference/html/ch16s11.html, pay attention on DefaultAnnotationHandlerMapping and AnnotationMethodHandlerAdapter. It seems you should study how do they work and override some of the functionality.
But before you are starting, think again. Do you really need this and #RequestMapping does not satisfy you? Really, you can use path variable {myvar} into the URL pattern definition. The variables may be of different types including enums. I used this and found very convenient. You can for example create enum MyType ONE, TWO; define abstract method on enum level and override it for each element. Then you can use path variable of type MyType into the request mapping and call this method directly from the method marked with #RequesteMapping annotation.

Do I need to make a custom regex pattern for this in PrettyFaces

Do I need to make a custom regex pattern to match URLs when I have the following mapping (example):
<url-mapping id="approvedQuestions">
<pattern>/questions/approved/#{viewOption}/</pattern>
<view-id>/approved.xhtml</view-id>
</url-mapping>
where the viewoption-portion should also match when the user does NOT end the URL with '/'?
And is it possible to supply some kind of default value if the don't add the viewOption portion at all?
And if I the viewOption is a enum, is it possible to lowercase the parameter? Now I have to write uppercase in to make it work.
You can use a custom regex to do this type of, but I recommend using a url-rewrite rule to append a trailing slash if one is missing. You should pick one URL (with or without the '/' at the end) otherwise you are actually serving up the same resources with two distinct addresses, and you will be punished by search engines and other crawlers.
To do this, I would use a rewrite rule such as the following:
<rewrite match="/questions/approved/[^/]+" trailingSlash="append" />
This will cause the server to detect when a '/' is missing from the end of the URL, and it will redirect the request to the proper location, with a '/' at the end.
In order to address your enum issue, this is a bit more complicated. We don't typically recommend binding values directly into enumerations. In this case, you are not actually binding into an enum (I'm guessing,) but are actually binding the literal string URL value into the request scoped EL context. This value is then being extracted somewhere else in your application, and that is where the conversion into an ENUM is taking place.
Until PrettyFaces 4 comes out, I recommend instead binding the value into a String location, then using an action method to do the loading of the correct value yourself, like so:
<url-mapping id="approvedQuestions">
<pattern>/questions/approved/#{params.viewOption}/</pattern>
<view-id>/approved.xhtml</view-id>
<action>#{params.loadViewOption}</action>
</url-mapping>
If you want to try a more advanced URL-rewriting tool, also from OCPsoft, you can use "Rewrite" (http://ocpsoft.com/rewrite/), which is a Java-based URL-rewriting tool, but does not have as much integration with JSF.
PrettyFaces 4 will be based on rewrite as a core, at which point, all of the features you currently use will also be available with the ability to do something more like this, which is what you want if I am not mistaken:
.addRule(Join.path("/questions/approved/{viewOption}").to("/approved.xhtml")
.where("viewOption")
.matches("[^/]+/?")
.transformedBy(TrailingSlash.append())
.transformedBy(To.upperCase())
You would need to create your own transformers because they haven't been defined in the library yet, but that's the general idea. It's much more powerful than what's currently possible with PrettyFaces, but does not provide the same JSF navigation integration, and is a little trickier to configure.
I hope this helps,
~Lincoln

Categories

Resources