支持 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());
}
}
我已经为 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());
}
}