为包中所有控制器类的 URL 添加前缀

发布于 2024-11-19 19:07:31 字数 816 浏览 0 评论 0 原文

我正在使用 Spring 3.0 开发一个在 Tomcat Apache 6.0 环境上运行的 RESTful 服务。 Spring DispatcherServlet 配置在“/spring/*”。 Spring servlet 处理多个客户端,并在应用程序中拥有许多控制器。我正在为 REST 服务添加一个新的控制器。我希望所有控制器类都有一个像“ws”(Web 服务)这样的标识前缀,以便资源的完整 URL 如下所示:
http://://spring/ws/service1

我发现 Spring 注释的唯一方法是像这样使用 @RequestMapping

@Controller
@RequestMapping("/ws/service1")
public class Service1 {

@RequestMapping(method=RequestMethod.GET)
@ResponseBody
public String getHtml() { ... }  

....
}

:有几十个类,我不想在每个类中添加“/ws”前缀。这样,如果另一个开发人员添加了新服务,他不必记住添加此前缀,而且如果我们决定将前缀名称从“/ws”更改为其他名称,我也不必更改所有文件。我发现 @RequestMapping 注释仅适用于方法或类,而不适用于包级别。

有什么方法可以配置我的所有 REST 控制器都使用前缀访问吗?

请注意,我无法更改 Spring servlet 的 web.xml URL 映射,因为还有其他控制器正在使用该 URL 运行。

I am developing a RESTful service using Spring 3.0 running on Tomcat Apache 6.0 environment. The Spring DispatcherServlet is configured at "/spring/*". The Spring servlet handles multiple clients and has many Controllers in the application. I am adding a new Controller for the REST service. I want all of my controller classes to have a identification prefix like "ws" (web-service) so that the complete URL to a resource looks like this:
http://<server>:<port>/<context>/spring/ws/service1

The only way I found with Spring annotation is to use @RequestMapping like this:

@Controller
@RequestMapping("/ws/service1")
public class Service1 {

@RequestMapping(method=RequestMethod.GET)
@ResponseBody
public String getHtml() { ... }  

....
}

But since I have dozens of classes, I don't want to put "/ws" prefix in each class. So that if another developer adds a new service, he does not have to remember to put this prefix and also if we decide to change the prefix name from "/ws" to something else, I don't have to change all the files. I found that @RequestMapping annotation is only applicable to Methods or Classes and not at the package level.

Is there any way I can configure that all my REST Controllers are accessed with the prefix?

Please note that I can not change the web.xml URL mapping of Spring servlet since, there are other Controllers which are running with that URL.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

椵侞 2024-11-26 19:07:31

您可能想查看约定优于配置< /a> 支持 Spring 3,特别是 ControllerClassNameHandlerMapping。实际上,您不会在 @RequestMapping 中定义 URL 的位置,而是由处理程序的包位置定义。

如果您想让映射的 URL 反映控制器的包名称,那么您应该设置 ControllerClassNameHandlerMappingbasePackage 属性。 文档

设置用于生成路径映射的基础包,包括该包下面的所有子包作为路径元素。
默认值为 null,使用生成路径的短类名,控制器的包未在路径中表示。指定一个像“com.mycompany.myapp”这样的基础包,以包含该基础包内的子包作为路径元素,例如为类名“com.mycompany.myapp.mymodule.BuyForm”生成路径“/mymodule/buyform”。子包层次结构表示为单独的路径元素,例如类名“com.mycompany.myapp.mymodule.mysubmodule.BuyForm”的“/mymodule/mysubmodule/buyform”。

因此,bean 定义的示例可能是

<bean class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping">
    <property name="basePackage" value="com.company.project"/>
</bean>
<context:component-scan base-package="com.company.project.ws"/>

并且您的控制器可能看起来像

package com.company.project.ws;
@Controller
public class Service1 {
    // your controller methods
}

You might want to look at the convention over configuration support of Spring 3, specifically ControllerClassNameHandlerMapping. Effectively you don't define the location of the URL in a @RequestMapping but it's defined by the package location of the handler.

If you want to have the mapped URLs reflect the package name of controller then you should set the basePackage property of the ControllerClassNameHandlerMapping. The documentation says

Set the base package to be used for generating path mappings, including all subpackages underneath this packages as path elements.
Default is null, using the short class name for the generated path, with the controller's package not represented in the path. Specify a base package like "com.mycompany.myapp" to include subpackages within that base package as path elements, e.g. generating the path "/mymodule/buyform" for the class name "com.mycompany.myapp.mymodule.BuyForm". Subpackage hierarchies are represented as individual path elements, e.g. "/mymodule/mysubmodule/buyform" for the class name "com.mycompany.myapp.mymodule.mysubmodule.BuyForm".

So, an example beans definition might be

<bean class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping">
    <property name="basePackage" value="com.company.project"/>
</bean>
<context:component-scan base-package="com.company.project.ws"/>

And your controllers might look like

package com.company.project.ws;
@Controller
public class Service1 {
    // your controller methods
}
七堇年 2024-11-26 19:07:31

我实现的另一种方法(非常基本且简单)是定义多个 Dispatcher servlet,然后为每个 servlet 映射不同的 URL。 Servlet 共享根 Spring 上下文,除此之外,还有自己的 bean 定义。阅读更多内容 Java 文档

所以我的 web.xml 看起来像:

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

<!-- Mappings for BlazeDS requests -->
<servlet-mapping>
    <servlet-name>flex</servlet-name>
    <url-pattern>/spring/messagebroker/*</url-pattern>
</servlet-mapping>

<!-- Second dispatcher servlet for Web Services API -->
<servlet>
    <servlet-name>wsapi</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>wsapi</servlet-name>
    <url-pattern>/spring/ws/*</url-pattern>
</servlet-mapping>

基本上,我保留了现有的调度程序 servlet,只为具有不同 URL 映射的 REST 控制器添加了一个新的 servlet。这样我就可以分别控制这些 servlet 的 URL。此后,我不再需要在每个控制器上添加 URL 前缀。

Another approach (very basic and simple) that I implemented was to define multiple Dispatcher servlets and then map different URLs for each servlet. The servlets share the root Spring context and in addition to that, have their own bean definitions. Read more in this Java doc.

So my web.xml looks like:

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

<!-- Mappings for BlazeDS requests -->
<servlet-mapping>
    <servlet-name>flex</servlet-name>
    <url-pattern>/spring/messagebroker/*</url-pattern>
</servlet-mapping>

<!-- Second dispatcher servlet for Web Services API -->
<servlet>
    <servlet-name>wsapi</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>wsapi</servlet-name>
    <url-pattern>/spring/ws/*</url-pattern>
</servlet-mapping>

Basically, I left the existing dispatcher servlet as it is and added a new servlet only for REST controllers with different URL mapping. So I can control the URL for these servlets separately. After this, I no more need to put the URL prefix on each Controller.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文