【问题标题】:Spring Boot: Let servlet dispatcher address only static content or handlersSpring Boot:让 servlet 调度程序只处理静态内容或处理程序
【发布时间】:2015-10-04 08:17:47
【问题描述】:

对于我的 Spring Boot 应用程序,我混合了托管在 /static 中的静态内容(html、js、css 等),并结合了一个侦听 /api/1.0 调用的 REST Web 服务。 /static 由 Spring Boot 自动处理。对于 api 前缀,我创建了一个新的 servlet 调度程序,用于监听前缀地址:

@Configuration
public class DispatcherConfiguration {

    public static final String API_PREFIX = "/api/1.0/*";

    @Bean
    public DispatcherServlet apiDispatcherServlet() {
         DispatcherServlet dispatcher = new DispatcherServlet();
         return dispatcher;
    }

    /**
     * Setup route for the REST service located at @see API_PREFIX
     * @return Servlet dispatcher
     */
    @Bean
    public ServletRegistrationBean apiDispatcher() {
        DispatcherServlet dispatcher = apiDispatcherServlet();

        ServletRegistrationBean registration = new ServletRegistrationBean(dispatcher, API_PREFIX);
        registration.setName("api");
        registration.setOrder(1);
        return registration;
    }
}

乍一看,这个配置解决了这个问题,因为现在调用 rest-api 使用设置的前缀并被转发到正确的控制器。乍一看,两个 servlet 仍然处理这两种类型的调用,因此静态内容现在也可以在 api 前缀处使用,并且控制器仍然可以在根 url 处访问。这并不是真正的意图。

spring文档在sections 15.12.4 and 15.12.5中提到了一些有趣的配置选项,但是这个结合Spring Boot和非xml配置的应用还不清楚。

我还找到了a post by Daniel,它详细解释了类似的问题,但它的设置比我所拥有的要复杂得多,而且我看不到将他的解决方案应用于我的用例的简单方法。

我已经尝试并测试了各种解决方案,但是关于这方面的文档很少,而且由于所有动态 Bean 加载,很难测试和找出某些东西为什么起作用或不起作用。我现在已经进入了几天,并且肯定被卡住了。

如何使用 java 配置将 servlet 对静态内容和控制器的处理分开?我的应用程序中的所有配置都是在 java 中完成的,所以我正在寻找(最好)一个无 xml 解决方案。

【问题讨论】:

    标签: java spring spring-mvc servlets


    【解决方案1】:

    我认为您不需要该配置。你可以只注释你的控制器类。例如:

    @RestController
    @RequestMapping(value = "/api/1.0")
    public class MyRestController
    .... 
        @RequestMapping(method = RequestMethod.POST)
        public @ResponseBody Foo getFoo(RequestEntity<Bar> request) {
    

    【讨论】:

    • 是的,我已经考虑过了,但缺点是我需要在每个控制器中硬编码 api 前缀。我已经有几十个控制器,为了将来的可维护性和可扩展性,我宁愿集中这些配置。
    • 回想起来,这个答案比我最初想象的要好得多;我完全看错了方向。我为控制器创建了一个抽象超类,它 a) 定义了基本请求映射,b) 允许我对控制器构建的 api 版本进行完整性检查。感谢您的洞察力!我对你的答案投了赞成票。
    【解决方案2】:
    • 不要使用第二个DispatcherServlet
    • 在某处用“/api/1.0”创建一个常量,比如说Constants.API_BASE_URL
    • 用@RequestMapping(value = Constants.API_BASE_URL)注释每个@Controller

    这样,您将拥有一个配置基本 URL 的中心点,并且每个带注释的控制器都将具有与其相关的 URL 映射。

    【讨论】:

      猜你喜欢
      • 2019-09-22
      • 1970-01-01
      • 1970-01-01
      • 2023-02-21
      • 2022-01-12
      • 2018-02-19
      • 1970-01-01
      • 2017-10-20
      • 2015-11-05
      相关资源
      最近更新 更多