春季启动:为静态资产提供后备服务

时间:2019-09-26 17:54:32

标签: angular spring spring-boot routing static-files

我的问题是,要在Spring Boot 2 / Spring 5中为Angular 8应用程序提供服务。我想在http://localhost:8080/app下的src/main/resources/app中提供Angular应用程序(静态html,css,js)。基本上这不是问题,因为Spring能够通过将静态资产放入src/main/resources/static/app中来为其提供服务,而这完成了一半的工作...

但是,我希望Spring在该目录下提供静态文件(如果存在),因此从http://localhost:8080/app/subdir/some.jssrc/main/resources/app/subdir/some.js的映射通常可以解决此问题。但是如果文件不存在(404),我想将src/main/resources/app/index.html作为备用(状态为200),但是仅当路径与/app/**匹配时才使用,因为Spring无法理解Angular客户端路由。如果路径与/app/**不匹配,则应提供正常的404。

逻辑上:

if(patch matches: static file)
    => serve static file from `src/main/resources/app/`
if(path matches: /app/** && NOT_FOUND)
    => serve `src/main/resources/app/index.html`
else
    => serve 404 error

难看的骇客,这并不完全有效: 我通过将静态文件放入src/main/resources/static/app并添加如下所示的自定义错误控制器来解决这个问题:

@Controller
class CustomErrorController : ErrorController {

  @RequestMapping("/error")
  fun handleError(request: HttpServletRequest): String {
    val statusCode = request.getAttribute("javax.servlet.error.status_code") as Int
    val uri = request.getAttribute(RequestDispatcher.FORWARD_REQUEST_URI) as String?

    return when {
      statusCode == HttpStatus.NOT_FOUND.value() && uri?.startsWith("/app") ?: false ->
        "forward:/app/index.html"
      else ->
        "error/404.html"
    }
  }

  override fun getErrorPath(): String {
    return "/error"
  }
}

但这似乎是一个丑陋的解决方法,它使用不需要的404状态代码来提供index.html。

上下文信息:

  • 还使用提供服务器端渲染的pebble模板引擎 /app之外的html。
  • 还提供/app之外的其余端点。

恕我直言,应该有某种“干净”的解决方案来做到这一点。 预先感谢。

0 个答案:

没有答案