支持 NextJS 路由 Spring Boot app 而无需任何代理

Supporting NextJS routing over Spring Boot app without any proxy

我已经为 Spring 启动应用程序提供服务的 NextJS 应用程序创建了构建。 根页面 /(即 index.html)可以正常打开,NextJS 从那里通过它的链接处理客户端导航,因此例如从根 / 我可以到达 /user/edit(实际上是 edit.html).

到目前为止一切都很好。但现在如果用户决定重新加载页面,或尝试通过 typing/pasting link 打开此页面。 /user/edit 将给出 404,因为 spring 仅将其标识为 /user/edit.html.

我试过了

@Configuration
public class WebConfiguration implements WebMvcConfigurer {
  @Override
  public void addResourceHandlers(ResourceHandlerRegistry registry) {
    //This works totally fine.
    registry.addResourceHandler("/**/*.css").addResourceLocations("classpath:static/");
    
    
    //This has not impact.
    registry.addResourceHandler("/**[^.]+$").addResourceLocations("classpath:static/**.html");
  }
}

我知道“classpath:static/**.html”没有多大意义来解决。但是,如果可以通过这种方法或任何其他方法实现,那将不胜感激。 我只需要修改任何不是来自 /api 并且没有扩展名的请求路径相同的 + '.html '

我不想编写自己的控制器来处理静态内容服务,而且我没有 SSR,所以我不想使用 Thymeleaf,除非它是最后一个选项,我也不想更改我所有的 NextJS路线例如/user/edit.html -> /user/edit/index.html.

我花了很多时间搜索和尝试不同的东西,我相信 Spring 足够开放,可以将它作为我不知道的配置放在某个地方。任何帮助将不胜感激。

提前致谢。

好的,所以我想到了一个简单的解决方案。共享以便为他人节省时间。

您需要 3 个文件。从技术上讲,您可以将第一个两个合并为一个,但只是更简洁的解决方案。

public abstract class PathForwardHandlerInterceptor implements HandlerInterceptor {

    abstract protected String provideAlternative(String path);

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
        final String alternative = provideAlternative(request.getServletPath());
        if (alternative != null) {
            request.getRequestDispatcher(alternative).forward(request, response);
            return false;
        }
        return HandlerInterceptor.super.preHandle(request, response, handler);
    }
}
public class ExtensionAppendInterceptor extends PathForwardHandlerInterceptor {
    @Override
    protected String provideAlternative(String path) {
        return ("/".equals(path) || path.contains(".")) ? null : path + ".html";
    }
}
@Configuration
public class WebConfiguration implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new ExtensionAppendInterceptor());
    }

}