bclozel/springmvc-router — pull request #1 by electrotype (2012-06-16 14:06:41+00:00)
Title: Querystring param routing

Hi Brian,

Sorry I didn't reply to your last message about using springmvc-router in a sercurity.xml context file, I wanted to do it today but I don't find the thread anymore! Anyway, I think you are right and I could use annotations instead of the way I currently do it.

I made a significant change to your springmvc-router : being able to route using querystring parameters.

I'm currently integrating Spring Social, and it comes with controllers which have their @RequestMapping annotations. I wanted to extract those routes and add them to my application routes.conf file. It worked well except for one thing: some of their actions are routed using a querystring parameter!

With Spring's @RequestMapping, you can specify a "params" argument which will be used for the routing. I'm pretty sure this feature doesn't exist in Play 1.2.X's routing system that you based springmvc-router on. So I decided to implement it..

The new feature is backward compatible, all your tests still run (and I added more tests for the new feature).

It works like this :

```
GET /test [titi !toto tutu=hello tata!=world] testController.test
```
This will only route to TestController#test() if, in the querystring, "titi" is set (any value), "toto" is not present, tutu is set with a value of "hello" and tata is set but its value is not "world".

- The querystring parameters must be inside "[" and "]", following the "path" part of the route definition.

- The querystring parameter values must be urlencoded. For example :

```
GET /test [titi=a%20b] testController.test
```
("a b" would be received in the action, as a @RequestParam(value = "titi"))

- Each querystring parameter must be separated by one or more spaces.

- "tata!=world" means : "tata" must be present in the querystring, but with a value different than "world". If "tata" is not in the querystring at all, the route won't match.

- If a staticArg and a qsParam have the same key, both will be available to the controller. The staticArg as a @PathVariable and the qsParam as a @RequestParam. Ex :

```
GET /test [titi=abc] testController.test(titi:'someStaticVal')

public ModelAndView test(@PathVariable(value = "titi") String titiStaticArg, @RequestParam(value = "titi") String titi) {}

```

- If a staticArg and a qsParam have the same key, to reverse route you have to specify the *staticArg* value as the argument. But the generated url will contain the value of the *qsParam* (as specified in the route definition), except if this qsParam accept any value.. In that case, the generated url will contain the value of the staticArg. Ex :

```
GET /test [titi=abc] testController.test(titi:'someStaticVal')

Map args = new HashMap();
args.put("titi", "someStaticVal");
String url = Router.reverse("testController.test", args).url;

```
Here the url should be : /test?titi=abc

But :

```
GET /test [titi] testController.test(titi:'someStaticVal')

Map args = new HashMap();
args.put("titi", "someStaticVal");
String url = Router.reverse("testController.test", args).url;

```
Here the url should be : /test?titi=someStaticVal

I don't know if you'll want to merge this new feature into your own master, since it's a pretty big change. As you wish! Please note that I didn't test any of the "view" part of your code (Freemarker, Velocity), I don't know if it would have to be modified.

If you see any bug or have any comment, you're very welcome! Thanks.