带有单页角度重定向的弹簧靴2

2022-09-01 13:29:46

我有一个带有Spring Boot的单页Angular应用程序。它看起来像下面这样:

src
  main
  java
    controller
       HomeController
       CustomerController
       OtherController
  webapp
    js/angular-files.js
    index.html

Spring Boot 正确默认为 webapp 文件夹,并提供索引.html文件。

我想做的是:

  1. 对于每个以覆盖开头的本地 REST 请求,并重定向到默认 webapp/index.html。我计划为弹簧控制器提供任何东西。/api/api

  2. 有没有办法在所有控制器前面加上API前缀,这样我就不必每次都编写API?例如:

    @RequestMapping(“/api/home”) 可以在代码@RequestMapping(“/home”) 中写速记

@RequestMapping("/api/other-controller/:id") can write shorthand  @RequestMapping("/other-controller/:id")

我正在寻找每个API请求,例如1)http://localhost:8080/api/home API保留API并解析更正控制器并返回JSON,但是如果有人输入 http:///localhost/some-url 或 http:///localhost/some-other/123/url 等URL,那么它将提供索引.html页面并保留URL。

enter image description here

替代方法:尝试添加#ErrorViewResolver:Springboot/Angular2 - 如何处理HTML5网址?


答案 1

如果您厌倦了尝试通过遵循这么多相互冲突的解决方案来解决此问题 - 请看这里!!

经过几个小时尝试遵循数十个堆栈溢出和博客文章的所有分散建议,我终于找到了最小的PURE spring boot + angular 6应用程序,在非根页面上刷新后.html始终重定向到索引,同时维护所有端点路径。否 ,否 ,不做任何更改 ,无需自定义修改,只需简单:REST API@EnableWebMvc@ControllerAdviceapplication.propertiesResourceHandlerRegistry

非常重要的先决条件

*必须*将的输出包含在Spring的文件夹中。您可以通过 .在此处学习:使用 maven 将多个资源目录复制到独立的目标目录ng buildresources/staticmaven-resources-plugin

法典

@Controller
@SpringBootApplication
public class MyApp implements ErrorController {

    public static void main(String[] args) {
        SpringApplication.run(MyApp.class, args);
    }

    private static final String PATH = "/error";

    @RequestMapping(value = PATH)
    public String error() {
        return "forward:/index.html";
    }

    @Override
    public String getErrorPath() {
        return PATH;
    }
}

推理

  • 在构建时将 ng-build 的输出包含在 in 中,允许 Spring 视图重定向 () 成功。似乎spring无法重定向到资源文件夹之外的任何内容,因此,如果您尝试访问站点根目录的页面,它将不起作用。resources/static"forward:/index.html"
  • 使用默认功能(即不添加或更改)导航以自动为索引提供服务.html(如果它包含在文件夹中),因此无需在此处进行更改。@EnableWebMvcapplication.properties/resources/static
  • 使用默认功能(如上所述),在 Spring Boot 应用路由到和实现时遇到的任何错误都会将该行为覆盖到 ( 您猜对了 - 允许接管路由的路由。/errorErrorControllerindex.htmlAngular

言论


答案 2

对于每个不以 /api 开头的本地 REST 请求,请覆盖并重定向到默认 webapp/index.html。我计划向弹簧控制器提供任何/api。

更新 15/05/2017

让我为其他读者重新表述您的查询。(如果误解,请纠正我)

使用
Spring Boot 的背景信息,并从类路径提供静态资源

要求
所有非 api 请求都应重定向到 。404index.html

非 API - 表示 URL 不以 开头的请求。
API - 404 应像往常一样抛出。/api404

示例响应
- 将引发
- 将服务器索引.html
- 将重定向到/api/something404/index.html/somethingindex.html

我的解决方案

如果任何处理程序对给定资源不可用,则让 Spring MVC 引发异常。

将以下内容添加到application.properties

spring.mvc.throw-exception-if-no-handler-found=true
spring.resources.add-mappings=false

添加如下ControllerAdvice

@ControllerAdvice
public class RedirectOnResourceNotFoundException {

    @ExceptionHandler(value = NoHandlerFoundException.class)
    public Object handleStaticResourceNotFound(final NoHandlerFoundException ex, HttpServletRequest req, RedirectAttributes redirectAttributes) {
        if (req.getRequestURI().startsWith("/api"))
            return this.getApiResourceNotFoundBody(ex, req);
        else {
            redirectAttributes.addFlashAttribute("errorMessage", "My Custom error message");
            return "redirect:/index.html";
        }
    }

    private ResponseEntity<String> getApiResourceNotFoundBody(NoHandlerFoundException ex, HttpServletRequest req) {
        return new ResponseEntity<>("Not Found !!", HttpStatus.NOT_FOUND);
    }
}

您可以根据需要自定义错误消息。

有没有办法在所有控制器前面加上api前缀,这样我就不必每次都写api。

为此,您可以创建一个并将请求映射路径设置为BaseController/api

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RequestMapping("/api")
public abstract class BaseController {}

并扩展此内容,并确保不要使用BaseController@RequestMapping

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class FirstTestController extends BaseController {
    @RequestMapping(path = "/something")
    public String sayHello() {
        return "Hello World !!";
    }

}

上一个答案

您可以创建一个重定向到 /index 的筛选器.html如果请求路径未启动,则使用 /api

// CODE REMOVED. Check Edit History If you want.