I'm trying to use Groovy as my Controller's language. I choose mkyong's example for this one. However Instead of Gradle, I use Maven. Here are my codes:
pom.xml (dependencies only, changed here to Gradle format for reading purpose)
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'
WelcomeController.java
@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;
}
}
Welcome2Controller.groovy (Groovy implementation of WelcomeController)
@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
}
}
Welcome2Controller.class decompiled
@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
}
}
It works just fine when using Java, but I get error 400 when using Groovy. I've tried to change it to use @RequestParam
like this:
@RequestMapping(value = '/', method = RequestMethod.GET)
public def ModelAndView welcome(@RequestParam('name') String name) { /* omitted */ }
then change the HTTP request to /?name=World
and it works well. I have several questions though.
- Why does
@PathVariable
gives me error 400 when using Groovy? - Mkyong uses
{name:.+}
in hisRequestMapping
. What does:.+
means?
Thank you in advance.
edit 1: I tried on tomcat 7 and tomcat 8, both giving me the same result
edit 2:
There's an exception caught in org.springframework.web.servlet.DispatcherServlet
the message is org.springframework.web.bind.ServletRequestBindingException: Missing URI template variable 'name' for method parameter of type String. It is caused by Spring unable to get uriTemplateVars
in org.springframework.web.servlet.mvc.method.annotation.PathVariableMethodArgumentResolver
(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.