spring mvc:只要我添加第三个路径变量,就找不到资源
我为我的REST服务器使用Spring MVC。我的pom.xml中的spring.version版本是3.2.1.RELEASE。spring mvc:只要我添加第三个路径变量,就找不到资源
我已经创建了大量RESTful API并广泛使用了PathVariables。它工作正常。
但它似乎打破了以下情况。如果我有类似以下的内容,我的REST请求找不到资源。
@Controller
@RequestMapping(value = { "/resourceA/{resourceAId}/resourceB/{resourceBId}/resourceC/{resourceCId}" })
public class TenderController {
@RequestMapping(value = "", method = RequestMethod.POST)
@ResponseBody
public Tender capture(
@PathVariable long resourceAId,
@PathVariable long resourceBId,
@PathVariable long resourceCId,
@RequestBody Map<String, Object> requestBody) {
...
}
}
编辑:
这里是我的样品没有REST请求:
POST /resourceA/1/resourceB/2/resourceC/3 HTTP/1.1
Host: localhost:8080
Content-Type: application/json
Cache-Control: no-cache
{ "bodyParam1": 400, "bodyParam2": 0 }
但是,如果我放弃{resourceCId}从Java代码,并相应地调整我的REST请求,它成功查找资源:
修订的Java代码:
@RequestMapping(value = { "/resourceA/{resourceAId}/resourceB/{resourceBId}/resourceC" })
新的(成功)REST请求:
POST /resourceA/1/resourceB/2/resourceC HTTP/1.1
Host: localhost:8080
Content-Type: application/json
Cache-Control: no-cache
{ "bodyParam1": 400, "bodyParam2": 0 }
所以基本上只要我有3个路径变量,事情似乎分崩离析。关于可能发生在这里的任何想法?我偶然发现了一个Spring MVC错误?我猜不是,因为3个路径变量应该是一个非常常见的情况(几乎不符合角落案例)。
更新: 这似乎是我的HTTP客户端(铬邮递员),而不是我的服务器代码的问题。当我通过curl发送相同的请求时,我能够获得预期的结果。
更新: 事实上,无论客户端(邮递员,卷发等),错误已经回来并且正在发生。所以这绝对是一个服务器端问题。以下是日志
01:35:39.409 [http-bio-8080-exec-5] DEBUG o.s.web.servlet.DispatcherServlet - DispatcherServlet with name 'mvc-dispatcher' processing POST request for [/resourceA/1/resourceB/1/resourceC/1]
01:35:39.411 [http-bio-8080-exec-5] DEBUG o.s.w.s.m.m.a.RequestMappingHandlerMapping - Looking up handler method for path /resourceA/1/resourceB/1/resourceC/1
01:35:39.414 [http-bio-8080-exec-5] DEBUG o.s.w.s.m.m.a.RequestMappingHandlerMapping - Returning handler method [public void com.sample.controller.DefaultController.unmappedRequest()]
01:35:39.414 [http-bio-8080-exec-5] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Returning cached instance of singleton bean 'defaultController'
01:35:39.422 [http-bio-8080-exec-5] DEBUG o.s.w.s.m.m.a.ExceptionHandlerExceptionResolver - Resolving exception from handler [public void com.sample.controller.DefaultController.unmappedRequest()]: com.sample.exception.APIException: Url pattern is invalid.
01:35:39.423 [http-bio-8080-exec-5] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Returning cached instance of singleton bean 'globalControllerExceptionHandler'
01:35:39.423 [http-bio-8080-exec-5] DEBUG o.s.w.s.m.m.a.ExceptionHandlerExceptionResolver - Invoking @ExceptionHandler method: public com.sample.model.ErrorInfo com.sample.controller.GlobalControllerExceptionHandler.handleAPIException(com.sample.exception.APIException)
01:35:39.460 [http-bio-8080-exec-5] DEBUG o.s.w.s.m.m.a.RequestResponseBodyMethodProcessor - Written [[email protected]] as "application/json;charset=UTF-8" using [org.springf[email protected]2ae18b1a]
01:35:39.460 [http-bio-8080-exec-5] DEBUG o.s.web.servlet.DispatcherServlet - Null ModelAndView returned to DispatcherServlet with name 'mvc-dispatcher': assuming HandlerAdapter completed request handling
01:35:39.460 [http-bio-8080-exec-5] DEBUG o.s.web.servlet.DispatcherServlet - Successfully completed request
找到什么导致了问题:
因此,与许多不同的东西摆弄左右后,我发现是什么原因导致这个问题。我有一个DefaultController.java,它旨在捕获所有与其他控制器不匹配的Url,并报告在我的REST服务的错误响应中找不到的好资源。 DefaultController具有以下代码:
package com.sample.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import com.sample.exception.APIException;
import com.sample.exception.APIException.Code;
@Controller
public class DefaultController {
@RequestMapping("/**")
public void unmappedRequest() {
throw new APIException(Code.INVALID_URL_PATTERN,
"There is no resource for this path");
}
}
这对我来说很好。但在这种情况下,这个DefaultController“/ **”在实际设置为接收“/ resourceA/{resourceAId}/resourceB/{resourceBId}/resourceC/{resourceCId}”的控制器之前选择了我的Url。删除DefaultController为我解决了这个问题。现在我的问题是如何保留DefaultController的功能,而不会触发TenderController。
我相信这可能是一个春天的bug,可能会在某些时候被修复。进入完全相同的问题。在我们的例子中,我们能够通过用普通的vanilla servlet替换处理未映射请求的Default Spring Controller来处理这些404s - 关于如何做到这一点的详细信息是here。
欢迎使用*,请将链接的关键点添加到您的帖子中。 –
显示一个给出404的示例URL,但您希望通过此方法处理。 –
添加了REST请求(包括失败的以及成功的请求)。 – Fayez
只是为了好玩,从方法的RequestMapping中删除'value =“”''。它不会有什么不同,但这并不意味着它不会。 – digitaljoel