0

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.

  1. Why does @PathVariable gives me error 400 when using Groovy?
  2. Mkyong uses {name:.+} in his RequestMapping. 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.

Iqbal Djulfri
  • 718
  • 6
  • 14
  • 1
    2.: http://stackoverflow.com/questions/13130829/in-springs-requestmapping-is-parameter-any-different-than-parameter – cfrick Nov 28 '14 at 11:00
  • i quickly tried your code with springboot and a restcontroller and this worked. aren't there any other errors in the log or does the error page hold further clues? – cfrick Nov 28 '14 at 11:11
  • @cfrick thanks for the no 2 answer. Unfortunately, there's no error log. I've checked all of Tomcat's logs and output. The only log is from tomcat localhost access log which tells me I've made a request (/World) from my IP. I want to try to debug this. Can you tell me where should I place the brakepoint in Spring that send error 400? – Iqbal Djulfri Nov 29 '14 at 08:23

1 Answers1

0

After debugging, I finally find what's wrong. It is in my code, not in Spring whatsoever.

in Welcome2Controller.groovy it is written:

@RequestMapping(name = '/{name}', method = RequestMethod.GET)

it should've been

@RequestMapping(value = '/{name}', method = RequestMethod.GET)

Thank you for @cfrick for helping :)

Community
  • 1
  • 1
Iqbal Djulfri
  • 718
  • 6
  • 14