Spring MVC多个URL映射到同一个控制器方法

5
假设我们在web.xml中为名为dispatcher的servlet有3个url-pattern(URL模式):
<servlet-mapping>
    <servlet-name>dispatcher</servlet-name>
    <url-pattern>/aaa/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
    <servlet-name>dispatcher</servlet-name>
    <url-pattern>/bbb/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
    <servlet-name>dispatcher</servlet-name>
    <url-pattern>/ccc/*</url-pattern>
</servlet-mapping>

并且一个控制器方法:

@RequestMapping(value = "/xxx", method = RequestMethod.POST)
public String foo() {}

由于@RequestMapping中的路径值不包含Servlet路径,因此当用户请求时

/aaa/xxx
/bbb/xxx
/ccc/xxx

所有请求都将映射到foo方法。如果网站非常复杂,我认为这可能会导致潜在问题。这是Spring Web MVC的缺陷还是我误解了什么?

你将所有三个路径都映射到了同一个名为“dispatcher”的servlet。 - Stefan
对于通过谷歌搜索到这里的人,我认为这个问题的答案:https://dev59.com/SGgt5IYBdhLWcg3w8h_e 解决了我的问题。 - PickBoy
2个回答

9

通过传递多个值,您可以将所有请求映射到一个请求映射。

@RequestMapping(value = {"/aaa/xxx", "/bbb/xxx", "/ccc/xxx"}, method = RequestMethod.POST)
public String foo() {}

只需更改web.xml中的映射,以处理所有类型的请求到dispatcher servlet。

<servlet-mapping>
   <servlet-name>dispatcher</servlet-name>
   <url-pattern>/*</url-pattern>
</servlet-mapping>

根据应用程序的要求或者Web流程,你可以定义不同的控制器。如果需要,你可以将公共的代码移动到实用类中。

@RequestMapping("/aaa")
public class AAAController {
    @RequestMapping(value = "/xxx", method = RequestMethod.POST)
    public String foo() {
        // call to common utility function
    }
    // other methods
}

@RequestMapping("/bbb")
public class BBBController {
    @RequestMapping(value = "/xxx", method = RequestMethod.POST)
    public String foo() {
        // call to common utility function
    }
    // other methods
}

@RequestMapping("/ccc")
public class CCCController {
    @RequestMapping(value = "/xxx", method = RequestMethod.POST)
    public String foo() {
        // call to common utility function
    }
    // other methods
}

在Spring的Web MVC框架文档中了解更多

你也可以编写程序进行配置。

public class MyWebApplicationInitializer implements WebApplicationInitializer {

    @Override
    public void onStartup(ServletContext container) {
        ServletRegistration.Dynamic registration = container.addServlet("dispatcher", new DispatcherServlet());
        registration.setLoadOnStartup(1);
        registration.addMapping("/*");
    }
}

1
谢谢您的回复!实际上,我不希望多种类型的请求映射到同一个控制器方法。我认为您提到的解决方案(将url-mapping更改为“/*”)可以解决这个问题,但是我想知道servlet配置中的url-pattern有什么意义,因为大多数人都会将其设置为“/*”? - PickBoy
这是Spring Web应用程序的常见用例,其中dispatcher servlet作为前置servlet,负责与处理程序映射进行咨询并将请求转发到正确的控制器。您只需要在单独的Spring配置文件中为不同的URL配置处理程序映射,而不是在web.xml中进行配置。 - Braj
1
请阅读有关处理程序映射的不同实现。 - Braj

0
我遇到了这样一种情况,我不能使用/*映射到调度程序servlet,因为我不希望所有静态资源的请求都发送到调度程序servlet。所以我使用了下面的映射到调度程序servlet。
<servlet-mapping>
    <servlet-name>dispatcherServlet</servlet-name>
    <url-pattern>/spring/*</url-pattern>
</servlet-mapping>

将 /spring 添加到您所有的 URL 中,例如:http://localhost:8080/context/spring/common/get/currentuser

您的控制器将如下所示:

@RestController

@RequestMapping("/common")

public class CommonController extends BaseController {

@RequestMapping(method = RequestMethod.GET,value="/get/currentuser")
public @ResponseBody User getUser() throws Exception  {
            // implementation ...

}


}


}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接