【问题标题】:Error 400 when using @PathVariable in Spring 4 Groovy Controller在 Spring 4 Groovy 控制器中使用 @PathVariable 时出现错误 400
【发布时间】:2014-11-28 10:11:16
【问题描述】:

我正在尝试使用 Groovy 作为我的 Controller 的语言。我为此选择mkyong's example。但是,我使用 Maven 而不是 Gradle。这是我的代码:

pom.xml(仅依赖关系,此处更改为 Gradle 格式以供阅读)

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(WelcomeController 的 Groovy 实现)

@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 反编译

@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
  }
}

在使用 Java 时运行良好,但在使用 Groovy 时出现错误 400。我尝试将其更改为像这样使用@RequestParam

@RequestMapping(value = '/', method = RequestMethod.GET)
public def ModelAndView welcome(@RequestParam('name') String name) { /* omitted */ }

然后将HTTP请求更改为/?name=World,它运行良好。不过我有几个问题。

  1. 为什么@PathVariable 在使用 Groovy 时会出现错误 400?
  2. Mkyong 在他的RequestMapping 中使用{name:.+}:.+ 是什么意思?

提前谢谢你。

编辑 1: 我尝试了 tomcat 7 和 tomcat 8,都给了我相同的结果

编辑 2: org.springframework.web.servlet.DispatcherServlet 中捕获到一个异常,消息是 org.springframework.web.bind.ServletRequestBindingException:缺少字符串类型的方法参数的 URI 模板变量“名称”。这是由于Spring无法从原始Servlet请求中获取org.springframework.web.servlet.mvc.method.annotation.PathVariableMethodArgumentResolver中的uriTemplateVars(返回空值)。为什么 Spring 在 Spring Boot 中运行良好时却忽略了这一点?我目前正在寻找Spring如何解析将属性放入Servlet Request。

【问题讨论】:

  • 我很快用 springboot 和一个 restcontroller 尝试了你的代码,这很有效。日志中没有其他错误还是错误页面有进一步的线索?
  • @cfrick 感谢您的第二个答案。不幸的是,没有错误日志。我检查了所有 Tomcat 的日志和输出。唯一的日志来自 tomcat localhost 访问日志,它告诉我我已经从我的 IP 发出请求(/World)。我想尝试调试这个。你能告诉我应该在哪里放置发送错误 400 的 Spring 中的刹车点吗?

标签: java spring spring-mvc groovy spring-4


【解决方案1】:

经过调试,终于找到问题所在了。它在我的代码中,而不是在 Spring 中。

在 Welcome2Controller.groovy 中是这样写的:

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

应该是的

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

感谢@cfrick 的帮助:)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-06-14
    • 1970-01-01
    • 2019-03-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多