6

Springを使用して非常に基本的なMVCアプリケーションを構築しています。リクエスト本文で検証を呼び出すコントローラーが1つあります。問題は、web.xmlでマッピングを定義すると、適切なコントローラーの検索が停止することですが、サーブレットアプリケーションコンテキストSpring starを変更すると、その場でいくつかの新しいバインディングが作成されますが、今回はアノテーションベースの検証が無視されます。アノテーションベースの検証を呼び出しながら、web.xmlのマッピングを制御するにはどうすればよいですか?

詳細は次のとおりです。

コントローラー:

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

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

これはサーブレットアプリケーションのコンテキストです。

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

Web 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

サーブレットアプリケーションコンテキストを変更すると、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 [com.my.package.controller.UserActionsController@1f86dbd] and 1 interceptor
(HandlerMethodInvoker:638) - Reading [com.my.package.model.NameValue] as "application/json" using [org.springframework.http.converter.json.MappingJacksonHttpMessageConverter@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 [com.my.package.model.NameValue@166685b] as "application/json;charset=UTF-8" using [org.springframework.http.converter.json.MappingJacksonHttpMessageConverter@2059ef]
(DispatcherServlet:957) - Null ModelAndView returned to DispatcherServlet with name 'action-api': assuming HandlerAdapter completed request handling
(DispatcherServlet:913) - Successfully completed request

Springがその場でバインディングを作成しているように見えますが、今回はバリデーターは無視されます。たとえば、「/api」と「/something」の2つのコントローラーが必要です。Springがそれらを見つけて検証を呼び出すことができるようにweb.xmlでそれを定義するにはどうすればよいですか?

ありがとう。

4

3 に答える 3

8

Spring @Controllers URL は常に、それらを処理する Spring Dispatcher サーブレットに対して相対的に解釈されます。したがって、ディスパッチャー サーブレットを web.xml の /api/* にマップすると、上記のコントローラーへの URL は /api/api/choice になります。

したがって、web.xml で 2 つの Spring Dispatcher サーブレットを構成し、1 つは web.xml で /api にマップされ、もう 1 つは web.xml で /somethingelse にマップされ、@RequestMappings から /api を削除するだけです。

私のアプリでは、API と UI に単一の Dispatcher Servlet を使用しており、さまざまな API コントローラーで URL と呼ばれる public static final String を使用して、API によって公開されるさまざまなリソースへのパスを構築しています。以下は私のAPIの例です。

@Controller
@RequestMapping(CompanyPermissionsResourceController.PATH)
public class CompanyPermissionsResourceController extends BaseApiController
{
    public static final String PATH = CompanyResourceController.PATH + "/permissions"; 
于 2012-08-08T09:53:52.850 に答える
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;
}
于 2012-08-08T09:37:35.967 に答える
-1

私はそれがこのように機能するとは思わない。/api/choiceすべてのパスをメソッド レベルに置きます。

于 2012-08-08T09:41:27.090 に答える