2012-08-08 36 views
5

我正在用Spring構建非常基本的mvc應用程序。它有一個控制器應該在請求主體上調用驗證。問題是,如果我在web.xml中定義映射,它會停止找到正確的控制器,但是當我修改servlet應用程序上下文時,Spring star會動態地創建一些新的綁定,但這次基於註釋的驗證將被忽略。如何在仍然調用基於註解的驗證的同時在web.xml中控制映射?Spring調用錯誤的控制器映射

下面是詳細信息:

控制器:

@Controller 
@RequestMapping("/api") 
public class UserActionsController { 

    @RequestMapping(value="/choice", method = RequestMethod.POST) 
    public @ResponseBody NameValue addUserChoice(@Valid @RequestBody NameValue action) 
    {  
     return action; 
    } 
} 

這是servlet應用程序上下文:

<mvc:annotation-driven/> 

<context:component-scan base-package="com.my.package" /> 

<bean 
    class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver"> 
    <property name="mediaTypes"> 
     <map> 
      <entry key="json" value="application/json" /> 
     </map> 
    </property> 
    <property name="defaultContentType" value="application/json" /> 
    <property name="defaultViews"> 
     <list> 
      <bean 
       class="org.springframework.web.servlet.view.json.MappingJacksonJsonView" /> 
     </list> 
    </property> 
</bean> 

網站XML:

<servlet> 
    <servlet-name>action-api</servlet-name> 
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> 
    <load-on-startup>1</load-on-startup> 
</servlet> 

<servlet-mapping> 
    <servlet-name>action-api</servlet-name> 
    <url-pattern>/*</url-pattern> 
</servlet-mapping> 

上面的配置正在工作。當我嘗試更改web.xml時,問題就開始了,所以控制器只負責「/ api/*」。我將它更改爲<url-pattern>/api/*</url-pattern>。在這種情況下,Spring無法找到正確的控制器。

(DispatcherServlet:819) - DispatcherServlet with name 'action-api' processing POST request for [/api/choice] 
(RequestMappingHandlerMapping:209) - Looking up handler method for path /choice 
(RequestMappingHandlerMapping:219) - Did not find handler method for [/choice] 
(PageNotFound:1080) - No mapping found for HTTP request with URI [/api/choice] in DispatcherServlet with name 'action-api' 
(DispatcherServlet:913) - Successfully completed request 

修改servlet應用程序上下文幫助,Spring現在能夠找到控制器,但不再調用驗證。

<bean 
    class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"> 
    <property name="alwaysUseFullPath" value="true" /> 
    <property name="messageConverters"> 
     <util:list id="beanList"> 
      <bean class="org.springframework.http.converter.StringHttpMessageConverter"/> 
      <bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"/> 
     </util:list> 
    </property> 
</bean> 

<bean 
    class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"> 
    <property name="alwaysUseFullPath" value="true" /> 
</bean> 

<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"> 
    <property name="alwaysUseFullPath" value="true" /> 
</bean> 

這裏是日誌:

(DispatcherServlet:819) - DispatcherServlet with name 'action-api' processing POST request for [/api/choice] 
(RequestMappingHandlerMapping:209) - Looking up handler method for path /choice 
(RequestMappingHandlerMapping:219) - Did not find handler method for [/choice] 
(DefaultAnnotationHandlerMapping:124) - Mapping [/api/choice] to HandlerExecutionChain with handler [[email protected]] and 1 interceptor 
(HandlerMethodInvoker:638) - Reading [com.my.package.model.NameValue] as "application/json" using [org.springf[email protected]2059ef] 
(HandlerMethodInvoker:173) - Invoking request handler method: public com.my.package.model.NameValue com.citypath.dima.controller.UserActionsController.addUserChoice(com.my.package.model.NameValue) 
(AnnotationMethodHandlerAdapter:1037) - Written [[email protected]] as "application/json;charset=UTF-8" using [org.springf[email protected]2059ef] 
(DispatcherServlet:957) - Null ModelAndView returned to DispatcherServlet with name 'action-api': assuming HandlerAdapter completed request handling 
(DispatcherServlet:913) - Successfully completed request 

看起來像春天做對飛一些綁定,但這次驗證被忽略。 我需要2個控制器,比如'/ api'和'/ something'。我如何在web.xml中定義它,以便Spring能夠找到它們並調用驗證?

謝謝。

回答

7

春@Controllers網址始終被解釋相對於春季調度的Servlet處理它們。因此,如果您將調度程序servlet映射到web.xml中的/ api/*,那麼上面的控制器的URL是/ api/api/choice

因此,您可以在web.xml中配置兩個彈簧調度器服務器,一個映射到/ api在web.xml中,一個映射到/ somethingelse在web.xml中,那麼你可以從@RequestMappings刪除/ api

在我的應用程序中,我使用一個調度器Servlet的API和UI,我使用公共靜態在我的各種API控制器中稱爲URL的最終字符串,以構建由API公開的各種資源的路徑。以下是我的API的一個例子。

@Controller 
@RequestMapping(CompanyPermissionsResourceController.PATH) 
public class CompanyPermissionsResourceController extends BaseApiController 
{ 
    public static final String PATH = CompanyResourceController.PATH + "/permissions"; 
+0

謝謝。 '/ api/api/choice'確實幫助我理解Spring爲什麼找不到控制器。如果我沒有在控制器中定義'api'部分,只需在web.xml中,所有的工作都很好。甚至可以在控制器和方法級映射。就像它想要工作一樣。 – Dima 2012-08-08 10:41:26

+0

這個答案幫助我找到了我的問題的根本原因,這是我的@ComponentScan不包括我的控制器的包 – McLovin 2016-03-28 18:13:33

1

你確定你正在post請求/api/choice

@RequestMapping(value="/choice", method = RequestMethod.POST) 

嘗試更改爲

@RequestMapping(value="/choice", method = RequestMethod.GET) 
public @ResponseBody NameValue addUserChoice(@Valid @RequestBody NameValue action) 
{  
    return action; 
} 
+0

正如我所提到的,第一個配置工作。所以在客戶端沒有問題。 (我使用的是Fiddler,完全沒錯) – Dima 2012-08-08 09:39:45

-1

我不認爲它是這樣工作的。將所有路徑/api/choice置於方法級別。

+0

你能解釋爲什麼它不應該起作用嗎?支持控制器級別@RequestMapping。當web.xml沒有指定除/ * – Dima 2012-08-08 09:44:06

+0

之外的任何路徑時,它工作正常。我認爲Spring並沒有將在類級別的RequestMapping的路徑添加到方法級別的RequestMapping。當然,我可能是錯的。我從未嘗試過這種方法。您需要在方法級別定義RequestMapping以使其工作,這是肯定的。如果在類級別上使用路徑參數化RequestMapping,則不必使用路徑進行參數化。問題是:你需要這種方法來做什麼? – 2012-08-08 09:53:05

+0

現在我知道我錯了。 :) – 2012-10-25 07:53:34