我有一个我正在构建并尝试使用AssetBundle服务的react应用,例如:
#3
我还添加了配置
#1
因此不会与我的API发生冲突。
这仅适用于我的React应用的登录页面。每当我尝试路由/ login / dashboard时,都不会从UI找到该页面。因此,我尝试添加更多的捆绑包来解决路由问题:
@Override
public void initialize(final Bootstrap<PersonalWebsiteConfiguration> bootstrap) {
bootstrap.addBundle(new SwaggerBundle<PersonalWebsiteConfiguration>() {
protected SwaggerBundleConfiguration getSwaggerBundleConfiguration(final PersonalWebsiteConfiguration configuration) {
return configuration.swaggerBundleConfiguration;
}
});
bootstrap.addBundle(new AssetsBundle("/build", "/", "index.html"));
}
现在,只有仪表板正在工作。有谁知道如何为具有多个路由/页面的React构建提供服务。
答案 0 :(得分:0)
对于单页应用程序,您需要每个客户端路由都返回index.html(以支持浏览器重新加载或登陆/以外的路径) 据我所知,Dropwizard AssetBundle无法做到这一点,即使用index.html服务所有路由。 参见类似的(旧的)question。
您可以自己实现servlet过滤器,也可以使用this one之类的社区插件。
我必须说另一种方法对我来说更好,不要完全使用dropwizard服务静态资产,而只能将其用作后端API。 对API和静态资产使用CDN路由或其他子域。这样,您可以在www.mydomain.com上拥有静态资产,并在api.mydomain.com上拥有API(或使用相同的域,并基于路径前缀,例如/ api路由到后端或静态资源)
答案 1 :(得分:0)
您可以添加过滤器以实现该功能。 有关实现此类过滤器的dropwizard插件,请参见https://github.com/xvik/dropwizard-guicey-ext/tree/master/guicey-spa。 以下独立示例代码位于Kotlin中。
class SinglePageAppFilter : Filter {
override fun doFilter(servletRequest: ServletRequest,
servletResponse: ServletResponse,
chain: FilterChain) {
val request = servletRequest as HttpServletRequest
val response = servletResponse as HttpServletResponse
if (request.requestURI == "/" || request.requestURI.startsWith("/api")) {
chain.doFilter(servletRequest, servletResponse)
} else {
val wrapper = ResponseWrapper(response)
chain.doFilter(servletRequest, wrapper)
val sc = wrapper.sc
if (sc == HttpServletResponse.SC_NOT_FOUND) {
request.getRequestDispatcher("/").forward(request, response)
} else if (sc != null) {
response.sendError(sc)
}
}
}
override fun init(filterConfig: FilterConfig) {}
override fun destroy() {}
}
class ResponseWrapper(response: HttpServletResponse) : HttpServletResponseWrapper(response) {
var sc: Int? = null
override fun sendError(sc: Int) {
this.sc = sc
}
}
class MyApplication : Application<MyConfiguration>() {
override fun initialize(bootstrap: Bootstrap<MyConfiguration>) {
bootstrap.addBundle(AssetsBundle("/assets", "/", "index.html"))
}
override fun run(configuration: MyConfiguration, environment: Environment) {
environment.servlets().addFilter("SinglePageAppFilter", SinglePageAppFilter())
.addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST), true, "/*")
}
}