从 Spring (Vanilla) 迁移到 Spring Boot - 如何在自定义 servlet 映射后保留 url?

问题描述 投票:0回答:1

我正在将使用 Spring MVC (vanilla) 的大型 Web 应用程序迁移到 Spring Boot(版本 3.2.5)。 我的应用程序过去也使用不同的框架,因此,我在 web.xml 文件中明确指定哪些请求应由 Spring 的 DispatcherServlet 处理,如下所示:

<servlet>
  <servlet-name>dispatcher</servlet-name>
  <servlet-class>
    org.springframework.web.servlet.DispatcherServlet
  </servlet-class>
  <load-on-startup>3</load-on-startup>
</servlet> 
<servlet-mapping>
  <servlet-name>dispatcher</servlet-name>
  <url-pattern>*.s</url-pattern>
</servlet-mapping>
<servlet-mapping>
  <servlet-name>dispatcher</servlet-name>
  <url-pattern>*.json</url-pattern>
</servlet-mapping>

因此,所有带有“.s”和“.json”后缀的请求都被定向到 Spring 的 DispatcherServlet。

在 Spring Boot 中,这不再可能,DispatcherServlet 的“”设置为“/”。这并不困扰我,我认为这是正确的政策。但是,在我的应用程序中,内容和代码中有很多对带有“.s”或“.json”后缀的网址的引用。例如。 “https://example.com/article.s?id={id}”。

我希望避免重写所有出现的“article.s”和“article”的控制器代码,并像以前一样由

@Controller
@RequestMapping(value = "/article", params="id")
服务来自“article.s”的请求。 “.json”控制器也存在类似的问题。顺便说一句:在普通 Spring 中,我不必在 @RequestMapping 的定义中添加“.s”或“.json” - Spring MVC 能够理解并忽略请求 url 中的此后缀。这意味着所有控制器的定义如下:
@RequestMapping(value = "/someurl" ...)
not 如下:
@RequestMapping(value = "/someurl.s"...)

我该如何解决这个问题? 也许使用某种 url 重写机制(将所有对“someurl.s”/“someurl.json”的请求重写为“someurl”)?

更新

抱歉,我发现在旧版本的 Spring 中我使用了

setUseSuffixPatternMatch
中的
WebMvcConfigurer.configurePathMatch
方法。在 Spring 6 中,此方法已被弃用,并且没有替代品,很快就会被删除。

public void configurePathMatch(PathMatchConfigurer configurer) {
  configurer.setUseSuffixPatternMatch(true);
}

我想我还能用一段时间。但是,“后缀模式匹配”超出了我的需要。我正在寻找一种将重定向从“.s”和“.json”设置为“*”的方法。

java spring spring-boot
1个回答
0
投票

我找到了一个解决方案,类似于 Spring Github 上的讨论中的解决方案,涉及另一个已弃用的选项 - “尾部斜杠匹配”

@Component
public class ServletRequestWrapperFilter implements Filter {

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
     HttpServletRequestWrapper requestWrapper = new HttpServletRequestWrapper((HttpServletRequest) request) {
            @Override
            public String getRequestURI() {
                String requestURI = super.getRequestURI();
                if (StringUtils.endsWith(requestURI, ".s")) {
                    return StringUtils.removeEnd(requestURI, ".s");
                }
                return requestURI;
            }
        };
        chain.doFilter(requestWrapper, response);
    }
}

Spring 6.2 中很快就会有一个新的过滤器解决“尾部斜杠匹配”问题,“后缀模式匹配”可能可以通过类似的方式解决。

© www.soinside.com 2019 - 2024. All rights reserved.