Spring 调用错误的控制器映射 [英] Spring invokes wrong controller mapping

查看:32
本文介绍了Spring 调用错误的控制器映射的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在用 Spring 构建非常基本的 mvc 应用程序.它有一个控制器,应该对请求正文调用验证.问题是,如果我在 web.xml 中定义映射,它会停止找到正确的控制器,但是当我修改 servlet 应用程序上下文时,Spring star 会动态创建一些新绑定,但这次基于注释的验证被忽略.如何在调用基于注释的验证的同时控制 web.xml 中的映射?

I'm building very basic mvc application with Spring. It has one controller that should invoke validation on request body. The problem is that if I define the mapping in web.xml it stops finding the right controller, but when I modify the servlet application context Spring star making some new bindings on the fly but this time annotation based validation is ignored. How can I controll mappings in web.xml while still invoking annotation based validation?

详情如下:

控制器:

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

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

这是 servlet 应用程序上下文:

This is the servlet application context:

<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/*".我将其更改为 /api/*.在这种情况下,Spring 无法找到合适的控制器.

The configuration above is working. The problem starts when I try to change web.xml so the controller will only be responsible for "/api/*". I change it to <url-pattern>/api/*</url-pattern>. In that case Spring cannot find the right controller.

(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 现在能够找到控制器,但不再调用验证.

Modifying the servlet application context helps, Spring now able to find the controller, but validation is not invoked anymore.

<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 会动态地进行一些绑定,但是这次验证器被忽略了.我需要有 2 个控制器,比如/api"和/something".我如何在 web.xml 中定义它以便 Spring 能够找到它们并调用验证?

Looks like Spring making some binding on the fly, but this time validators are ignored. I need to have 2 controllers for, say '/api' and '/something'. How can I define it in web.xml so Spring will be able to locate them and to invoke validation?

谢谢.

推荐答案

Spring @Controllers URL 总是相对于处理它们的 Spring Dispatcher Servlet 进行解释.因此,如果您将调度程序 servlet 映射到 web.xml 中的/api/* 那么上面控制器的 URL 是/api/api/choice

Spring @Controllers URLs are always interpreted relative the the Spring Dispatcher Servlet that handles them. So if you map the dispatcher servlet to /api/* in web.xml then the URL to your controller above is /api/api/choice

因此,您可以在 web.xml 中配置两个 spring 调度程序服务器,一个映射到 web.xml 中的/api,另一个映射到 web.xml 中的/somethingelse,然后您只需从 @RequestMappings 中删除/api

So you can configure two spring dispatcher servelts in web.xml one mapped to /api in the web.xml and one mapped to /somethingelse in web.xml then you can just remove /api from the @RequestMappings

在我的应用程序中,我为 api 和 UI 使用单个 Dispatcher Servlet,并且我在各种 API 控制器中使用称为 URL 的公共静态最终字符串来构建 API 公开的各种资源的路径.下面是我的 API 中的一个示例.

In my app I am using a single Dispatcher Servlet for api and UI and I use public static final String called URL in my various API controllers to build up the paths to the various resources exposed by the API. Below is an example from my API.

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

这篇关于Spring 调用错误的控制器映射的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆