我正在开发一个全栈应用程序,将Spring boot v2.7.5作为后端,Angular v15作为前端。我使用IntelliJ IDEA IDE进行开发。在本地,Spring boot在 http://localhost:8080 上运行,Angular在 http://localhost:4200上运行。我使用Gradle将项目构建为单个war文件,并将其部署在外部tomcat服务器上。
项目结构如下:
我有3个build.gradle文件,1个用于前端,1个用于后端,1个用于全局。当我运行全局build.gradle文件时,它会从fronend文件夹调用build.gradle,该文件夹构建angular项目并复制所有构建文件,并将它们放入back end/src/main/resources/static文件夹。接下来,调用后端的build.gradle,这将构建最终的war文件,并部署到外部tomcat服务器上。
我将前端构建文件(index.html,一些.js文件)放入backend/src/main/resources/static的原因是Spring Boot从该位置提供静态内容。更多细节。
因此,添加前端构建文件后,静态目录如下所示:
到目前为止还不错。当我单击登录按钮时,它会在内部调用后端 API 并移动到下一页(主页,即 http://localhost:8080/fe/appInstances)。
我知道这是 spring-boot,因为它正在 java 代码中寻找 http://localhost:8080/fe/appInstances API endpoint的定义。
为了解决这个问题,我创建了以下 IndexController.java 类,该类应将所有前端 rest endpoint重定向到 index.html该索引存在于 main/resources/static 文件夹中。
索引控制器.java
@Controller
public class IndexController {
@GetMapping("/")
public String index() {
return "redirect:/index";
}
@GetMapping("/fe/*")
public String anyFrontEndApi() {
return "index";
}
}
但是现在,我得到了以下关于循环视图路径[index]的Whitelabel错误页面:将再次发送回当前处理程序URL[/fe/index]。
我试过把@Controller改成@RestController,把返回类型改成ModelandView之类的。但是不管怎样,它仍然给我一个关于圆形视图路径的白标错误页面...
@RestController
public class IndexController {
@GetMapping("/")
public String index() {
return "redirect:/index";
}
@GetMapping("/fe/*")
public ModelAndView anyFrontEndApi() {
ModelAndView mv = new ModelAndView();
mv.setViewName("index");
return mv;
}
}
我在这里遗漏了什么吗?有人能帮我解决这个问题吗?
PS:@justthink在这里解决了这种情况。但我不知道如何做反向代理方式。
我们遇到了Angular
和Springboot
的页面刷新情况,我们通过添加下面的Configuration类来解决这个问题,该类扩展了WebMvcConfigrerAdapter
@Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/**/*")
.addResourceLocations("classpath:/static/")
.resourceChain(true)
.addResolver(new PathResourceResolver() {
@Override
protected Resource getResource(String resourcePath, Resource location) throws IOException {
Resource requestedResource = location.createRelative(resourcePath);
return requestedResource.exists() && requestedResource.isReadable() ? requestedResource
: new ClassPathResource("/static/index.html");
}
});
}
}
所以基本上,我们告诉 Springboot
,如果我们有资源,使用相同的资源,如果没有,则将其重定向到 index.html
。
现在,要处理< code>Angular中的路径,这取决于您如何编写< code>routes。如果路径可用,则显示页面,如果不可用,则显示404页面。
希望这有帮助。
更新 1:
< code > WebMvcConfigurerAdapter 已被否决。如果这导致任何问题,那么您可以< code >实现WebMvcConfigurerAdapter而不是扩展类< code >
如果您看到白标错误,则说“此应用程序没有 /error 的显式映射”。
这意味着,如果没有路径与控制器映射中定义的路径匹配,它将请求转发到“/error”路由。因此,我们可以覆盖此默认行为。
Spring提供ErrorController接口来覆盖此功能
import org.springframework.boot.web.servlet.error.ErrorController;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class CustomErrorController implements ErrorController {
@RequestMapping("/error")
public String handleError() {
return "forward:/";
}
}