2014-02-18 44 views
0

我爲我的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。

+0

顯示一個給出404的示例URL,但您希望通過此方法處理。 –

+0

添加了REST請求(包括失敗的以及成功的請求)。 – Fayez

+0

只是爲了好玩,從方法的RequestMapping中刪除'value =「」''。它不會有什麼不同,但這並不意味着它不會。 – digitaljoel

回答

0

我相信這可能是一個春天的bug,可能會在某些時候被修復。進入完全相同的問題。在我們的例子中,我們能夠通過用普通的vanilla servlet替換處理未映射請求的Default Spring Controller來處理這些404s - 關於如何做到這一點的詳細信息是here

+0

歡迎使用stackoverflow,請將鏈接的關鍵點添加到您的帖子中。 –