title: Error 400 when using @PathVariable in Spring 4 Groovy Controller
body: <p>I'm trying to use Groovy as my Controller's language. I choose <a href="http://www.mkyong.com/spring-mvc/gradle-spring-mvc-web-project-example/" rel="nofollow">mkyong's example</a> for this one. However Instead of Gradle, I use Maven. Here are my codes:</p>
  
  <p>pom.xml (dependencies only, changed here to Gradle format for reading purpose)</p>
  
  <pre><code>compile 'org.springframework:spring-webmvc:4.1.2.RELEASE'
  compile 'org.codehaus.groovy:groovy-all:2.3.7'
  providedCompile 'javax.servlet:servlet-api:2.5'
  </code></pre>
  
  <p>WelcomeController.java</p>
  
  <pre><code>@Controller
  public class WelcomeController {
  
    @RequestMapping(value = "/hello/{name:.+}", method = RequestMethod.GET)
    public ModelAndView welcome(@PathVariable("name") String name) {
      ModelAndView model = new ModelAndView();
      model.setViewName("hello/index");
      model.addObject("name", name);
  
      return model;
    }
  }
  </code></pre>
  
  <p>Welcome2Controller.groovy (Groovy implementation of WelcomeController)</p>
  
  <pre><code>@Controller
  class Welcome2Controller {
  
    @RequestMapping(name = '/{name}', method = RequestMethod.GET)
    public def ModelAndView welcome(@PathVariable('name') String name) {
      def model = new ModelAndView(viewName: 'hello/index')
      model.addObject 'name', name
  
      model
    }
  }
  </code></pre>
  
  <p>Welcome2Controller.class decompiled</p>
  
  <pre><code>@Controller
  public class Welcome2Controller implements GroovyObject {
  
    public Welcome2Controller() {
      CallSite[] var1 = $getCallSiteArray();
      MetaClass var2 = this.$getStaticMetaClass();
      this.metaClass = var2;
    }
  
    @RequestMapping(name = "/{name}", method = {RequestMethod.GET} )
    public ModelAndView welcome(@PathVariable("name") String name) {
      CallSite[] var2 = $getCallSiteArray();
      Object model = var2[0].callConstructor(ModelAndView.class, ScriptBytecodeAdapter.createMap(new Object[]{"viewName", "hello/index"}));
      var2[1].call(model, "name", name);
      return (ModelAndView)ScriptBytecodeAdapter.castToType(model, ModelAndView.class);
    }
  
    static {
      // omitted
    }
  }
  </code></pre>
  
  <p>It works just fine when using Java, but I get error 400 when using Groovy. I've tried to change it to use <code>@RequestParam</code> like this:</p>
  
  <pre><code>@RequestMapping(value = '/', method = RequestMethod.GET)
  public def ModelAndView welcome(@RequestParam('name') String name) { /* omitted */ }
  </code></pre>
  
  <p>then change the HTTP request to <code>/?name=World</code> and it works well. I have several questions though.</p>
  
  <ol>
  <li>Why does <code>@PathVariable</code> gives me error 400 when using Groovy?</li>
  <li>Mkyong uses <code>{name:.+}</code> in his <code>RequestMapping</code>. What does <strong><code>:.+</code></strong> means?</li>
  </ol>
  
  <p>Thank you in advance.</p>
  
  <p>edit 1:
  I tried on tomcat 7 and tomcat 8, both giving me the same result</p>
  
  <p>edit 2:
  There's an exception caught in <code>org.springframework.web.servlet.DispatcherServlet</code> the message is <em>org.springframework.web.bind.ServletRequestBindingException: Missing URI template variable 'name' for method parameter of type String</em>. It is caused by Spring unable to get <code>uriTemplateVars</code> in <code>org.springframework.web.servlet.mvc.method.annotation.PathVariableMethodArgumentResolver</code> (returning null value) from the original Servlet Request. Why does Spring missed that while it works just fine in Spring Boot? I'm currently searching for how Spring parse the put the attribute in Servlet Request.</p>