Problem with differentiation of pathparams - spring-mvc

I have problem with Jax-rs #Path variable, I need to differentiate the following two pathparams
#Path({domain}/{id})
#Path({domain}/{filename})
sample url for both:
1. http://localhost:8080/in.com/lrth09erdfgwe
2. http://localhost:8080/in.com/lrth09erdfgwe.xml
I think we need to use regex in pathparam! I tried it but failed to get it!
I'm using this application in Resteasy integration with spring-mvc.
Plz advice on this issue!
Cheers!

You control the matching of path parameter by putting inside the parameter a colon and then an RE pattern to match it, like this (where the RE is .+[.].+, which matches anything so long as it has at least one dot somewhere in the middle):
#Path("{domain}/{filename:.+[.].+}")
I use this in one of my services (which uses Apache CXF, but I believe this is a feature of all JAX-RS implementations). Have a care though! You can match path separators with this, which can make things very confusing. (I think you might be better to change the structure of the URIs so that there is no ambiguity, e.g., {domain}/id/{id} and {domain}/files/{filename}. I bet your clients will grok that much more rapidly.)

Related

Why is the namespace pattern for CustomData a full http address and index suffix

In UI5, customdata is used to contain additional parameters that are passed to event handlers in the eventControl.data() object. This is akin to jquery data functionality.
In an XML view definition for UI5 we have to define namespaces. In all the documentation and examples I have stumbled across on the web so far, the namespace for customdata has a pattern that references a specific http address AND a specific index number suffix, whereas the pattern for all others I have met thus far has been not included either.
See example below where customdata is the last entry in the list.
<mvc:View
controllerName="sapui5.muSample.controller.Master"
xmlns:mvc="sap.ui.core.mvc"
xmlns:l="sap.ui.layout"
xmlns="sap.m"
xmlns:c="sap.ui.core"
xmlns:app="http://schemas.sap.com/sapui5/extension/sap.ui.core.CustomData/1"
>
If I want to run OpenUI5 entirely from my servers hard drive thus without referring to any external sources, how can I alter the reference to customdata? Or am I misunderstanding and is the use of the http prefix NOT going to invoke communication across the web to the given address? If so I am even more confused.
I would like to understand the reason for the full http reference and index suffix AND know how to replace it with an entirely local reference. I tried to make a local reference but without success and I suspect there is more going on here than I grok.
EDIT: I have learned from the Internet and proven with Fiddler that the web address used in the namespace is not for use in communications. So I guess the clue might be the /1 suffix. Still confused though.
Answering for myself in case it helps someone else and to solicit corrections from community if needed.
I searched the debug source of UI5 for the string "http://schemas.sap.com/sapui5/extension/sap.ui.core.CustomData/1" and found a match in XMLTemplateProcessor-dbg.js wherein there is an if statement seeking this precise string.
My conclusions are:
This is nothing more than a namespace that does not match the general pattern in UI5 namespacing that I have experienced to date. Possibly a 'coded-by-a-separate-team' issue or some similar human cause.
The namespace text is arbitrary and has no meaning other than being a match to that needed in the UI5 code.
In a general namespace context, the /1 suffix would be an indication of version number of the namespace - a way of versioning the namespace over time. But this has no impact in this usage in UI5.
The http prefix, in the UI5 context, has no implication of communication and does not make the client reach out to the specified web address (proven by Fiddler observations).
End.
According to the documentation the difference between this namespace and the other namespaces is intentional. Whatever that means. In general the URI is used to define unique namespace names and is not used by the parser.

Purpose of URI parameters in the path component

We know that it is possible to pass parameters in the path component of URIs using the syntax ;param=value. I wonder what this is good for, taking into account that parameters can also be passed in the query component.
The Wikipedia article doesn't even mention the possibility of including parameters in the path component.
Another site mentions this possibility but it also adds that it is almost never used:
Each of the path segments can contain parameters which are separated from the segment by a ; (semi-colon) character e.g.:
http://www.blah.com/some;param1=foo/crazy;param2=bar/path.html
The URL above is perfectly valid, although this ability of path segments to hold parameters is almost never used (I've never seen it personally).
I found an explanation on Stackoverflow "when to use #QueryParam vs #PathParam" but it seems to me that any parameters could be passed in the query component, making path parameters redundant. And above all, I don't have an idea why somebody would use the above syntax to pass parameters in the URI.
The example quoted above also raises the question whether param1 and param2 have anything to do with some and crazy, respectively. Or why is it useful that we can include parameters in the path component?
Thank you in advance.

Can you use a regex in .NET WebApi Route URI For API Versioning

In MVC and WebApi you can add parameter constraints to your routes (see http://www.asp.net/web-api/overview/web-api-routing-and-actions/attribute-routing-in-web-api-2#constraints). You can even use regular expressions for the parameter constraints. However, I'm wondering if it's possible to use regular expressions to handle API versioning where many routes could/should route to the same action.
For example, I'm trying to version my API in the actual URI like this:
/api/v3/SomeResource
Where v3 indicates that it's version 3 of the API. If I'm on version 3 of my API it is likely that many of the actions have been unchanged throughout all three versions and would hence need to respond to:
/api/v1/SomeResource
/api/v2/SomeResource
/api/v3/SomeResource
Therefore, I would like to just be able to put a regex in my route attribute like this:
[Route("api/v(1|2|3)/SomeResource")] but it appears as though it doesn't treat the v(1|2|3) as a regex and instead treats it as a literal. In other words, a request to /api/v1/SomeResource isn't going to this action.
Is it possible to accomplish what I'm trying to accomplish? is there a way to put a regex in my route?
Thanks in advance!
Take a look at this:
[HttpGet, Route("Api/v{version:int:regex(1|2|3)}/SomeResource")]
Reference:
http://sampathloku.blogspot.com/2013/12/attribute-routing-with-aspnet-mvc-5.html
No, it is not possible. Per MSDN.
A URL pattern can contain literal values and variable placeholders (referred to as URL parameters). The literals and placeholders are located in segments of the URL which are delimited by the slash (/) character.
Nor is it particularly useful in this case, because you would typically route each API version to a separate controller. Therefore, each version would require a separate route, not a single route that matches all versions.
The document which you have already linked has a section that specifically covers API versioning (although it doesn't provide much detail).

Force case-sensitive routing in ASP.NET MVC

This question has been asked in a similar but not identical fashion (and not resolved to my satisfaction) previously on Stack Overflow and elsewhere.
Coming from a linux-world, I want to use ASP.NET MVC but avoid identical but differently-cased routes from resolving to the same page. I do not want to force all routes to be 100% lowercase.
e.g. I want /Home/Something to be a valid route and /Home/somethingElse to also be a valid route, but not /Home/something or /home/somethingelse, given two functions called Something and somethingElse in the HomeController.
I can't find any way of doing this from within the RegisterRoutes function, but maybe I'm missing something obvious? I can answer this easily enough by adding code to each Controller function, but I'm obviously trying to avoid doing that.
Optimally, the solution would involve catching all permutations of a particular route, then 301 redirecting any that do not exactly match the case of the controller's function.
I was unable to find any way of doing this after extensive searching. Basically, case-sensitivity and IIS/ASP.NET apparently do not go together.
We're now using a bit of a kludge to solve this. The code has been opensourced (MIT license) on github: NeoSmart Web Toolkit, in particular, this file containing the SEO redirect code.
Using it is easy enough: each GET method in the controller classes needs to add just this one line at the start:
Seo.SeoRedirect(this);
The SEO rewrite class automatically uses C# 5.0's Caller Info attributes to do the heavy lifting, making the code above strictly copy-and-paste.
Ideally, I would love to find a way to turn that line of code into an attribute. For instance, prefixing the controller methods with [CaseSensitive] would automatically have the same effect as writing in that line, but alas, I do not (yet) know how to do this.
I also can't find any way of figuring this out with the Routing class/structures. That's some opaque code!

Using duplicate parameters in a URL

We are building an API in-house and often are passing a parameter with multiple values.
They use: mysite.com?id=1&id=2&id=3
Instead of: mysite.com?id=1,2,3
I favor the second approach but I was curious if it was actually incorrect to do the first?
I'm not an HTTP guru, but from what I understand there's not a definitive standard on the query part of the URL regarding multiple values, it's typically up to the CGI that handles the request to parse the query string.
RFC 1738 section 3.3 mentions a searchpart and that it should go after the ? but doesn't seem to elaborate on its format.
http://<host>:<port>/<path>?<searchpart>
I did not (bother to) check which RFC standard defines it. (Anyone who knows about this please leave a reference in the comment.) But in practice, the mysite.com?id=1&id=2&id=3 way is already how a browser would produce when a form contains duplicated fields, typically the checkboxes. See it in action in this w3schools example page. So there is a good chance that the whatever programming language you are using, already provides some helper functions to parse an input like that and probably returns a list.
You could, of course, go with your own approach such as mysite.com?id=1,2,3, which is not bad at all in this particular case. But you will need to implement your own logic to produce and to consume such format. Now you may or may not need to think about handling some corner cases by yourself, such as: what if the input is not well-formed, like mysite.com?id=1,2,? And do you need to invent yet another separator, if the comma sign itself can also be a valid input, like mysite.com?name=Doe,John|Doe,Jane? Would you reach to a point that you will use a json string as the value, like mysite.com?name=["John Doe", "Jane Doe"]? etc. etc.. Your mileage may vary.
Worth adding that inconsistend handling of duplicate parameters in the URL on the server is may lead to vulnerabilities, specifically server-side HTTP parameter pollution, with a practical example - Client side Http Parameter Pollution - Yahoo! Classic Mail Video Poc.
in your first approach you will get an array of querystring values but in second approach you will get a string of querystring values.
I guess it depends on technology you use, how it becomes convenient. I am currently standing in front of the same question using currency=USD,CHF or currency=USD&currency=CHF
I am using Thymeleaf and using the second option makes it easy to work, I can then request something like: ${param.currency.contains(currency.value)}. When I try to use the first option it seems it takes the "array" like a string, so I need to split first and then do contain, what leads me to a more mess code.
Just my 50 cents :-)

Resources