Я использую Spring MVC для моего сервера REST. Spring.version в моем pom.xml является 3.2.1.RELEASE.spring mvc: ресурс не найден, как только я добавляю переменную третьего пути
Я создал несколько API RESTful и широко использовал 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 соответственно, его успешно найден ресурс:
Код редакции:
@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.
Update: На самом деле, ошибка вернулась и происходит независимо от клиента (почтальона, локон, и т.д.). Таким образом, это определенно проблема на стороне сервера. Вот журналы
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, который должен был поймать все Urls, которые не соответствовали каким-либо другим контроллерам, и сообщить хороший ресурс, который не найден в ответе об ошибке службы 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 «/ **» собирал мой Url перед контроллером, который на самом деле был настроен на получение «/ resourceA/{resourceAId}/resourceB/{resourceBId}/resourceC/{resourceCId}". Удаление DefaultController устранило проблему для меня. Теперь мой вопрос заключается в том, как сохранить функциональность DefaultController, не запуская ее перед моим TenderController.
Показать пример URL, который дает 404, но вы ожидаете, что этот метод будет обработан. –
Добавлены запросы REST (как неудачный, так и успешный). – Fayez
просто для забавы удалите 'value =" "' из RequestMapping по методу. Это не должно меняться, но это не всегда означает, что это не так. – digitaljoel