前端与后端终点(Spring Boot和Vue.js)

5

在某种程度上基于这个指南:

https://jaxlondon.com/blog/java-core-languages/put-spring-boot-und-vue-js-practical-use-project-tutorial/

我创建了一个多模块的Maven项目,其中一个子模块是我的后端,另一个子模块是我的前端。当我构建整个项目时,首先构建前端,然后将其dist/资源复制到后端,然后构建后端,最终可以通过java -jar target/backend-1.0.0-SNAPSHOT启动我的Spring Boot后端,并在localhost:8080上访问它。

enter image description here

根据我在后端实现的控制器,这是有道理的:

@RestController
public class GreetingController {

  private static final String template = "Hello, %s!";
  private final AtomicLong counter = new AtomicLong();

  @RequestMapping("/greeting")
  public Greeting greeting(@RequestParam(value = "name", defaultValue = "World") String name) {
    return new Greeting(counter.incrementAndGet(), String.format(template, name));
  }

  @RequestMapping("/")
  public Greeting root(@RequestParam(value = "name", defaultValue = "Root!") String name) {
    return new Greeting(counter.incrementAndGet(), String.format(template, name));
  }
}

如果我访问:http://localhost:8080/index.html,我会进入我的前端界面

enter image description here

目前有以下两个路由:

router.js

Vue.use(Router);

const router = new Router({
    mode: 'history',
    base: process.env.BASE_URL,
    routes: [
        {
            path: '/',
            name: 'home',
            component: HomeRoute
        },
        {
            path: '/myroute',
            name: 'myroute',
            component: MyRoute
        }
    ]
});

export default router;

在例如App.vue中,我有:

<template>
<div class="hello">
    <li>
      <router-link to="/MyRoute">GoToMyRoute</router-link>
    </li>
    <li>
      <router-link to="/">GoToHome</router-link>
    </li>
    <router-view></router-view>
</div>
</template>

我也可以访问,例如:

enter image description here

到目前为止都很顺利。但是如果我尝试直接在浏览器中输入:http://localhost:8080/MyRoute,我会得到以下结果:

enter image description here

我猜测这是因为我的控制器缺少一个后端@RequestMapping来处理/MyRoute

基于以上信息,我的问题如下:

  1. 如果我想直接在浏览器中访问每个vuejs路由,是否需要为每个路由维护一个后端RequestMapping?
  2. 我该如何分离/排序前端和后端的端点?目前似乎没有约定俗成的规则来区分后端端点与纯前端端点/路由。

我对 Vue 不是很熟悉,但我认为在第一种情况下,它使用 URL 重写而不是实际请求 MyRout 端点。但是,如果您尝试直接将此 URL 放入浏览器中,则会出现错误。不确定哪种方式最适合解决这个问题。我认为所有组件名称都应路由到 index.html - Alexey Usharovski
3个回答

4
我建议您这样做:
  1. Have one "ui" controller on your backend which would forward any unmapped routes to your frontend application e.g.:

    @RequestMapping(value = "/**/{[path:[^\\.]*}")
    public String redirect() {
        // Forward to home page so that route is preserved.
        return "forward:/";
    }
    
  2. Other rest endpoints defined in your backend should be defined after some prefix like "/api", or "/rest" (e.g. localhost:8080/api/some-data would return your json data). So every data endpoint will have this prefix.
  3. Every route visible to user (view navigation) should be done on vue.js side as SPA routing. (e.g. localhost:8080/welcome etc.)

我不太确定您所描述的第一点的意义。如果我添加它,当我直接在浏览器中访问“http://localhost:8080/MyRoute”时,我只会得到“forward:/”,而不是那个“Whitelabel Error Page”。但也许这就是重点 - 打印一些有意义的错误消息,而不是通用的Whitelabel消息? - u123
在Spring中,您需要将所有不是API的路径路由到Vue。在Vue中,您可以处理每个路由,例如路由到自定义的404页面等。 - Guts

1
我尝试了以下代码(灵感来自Gus的答案):
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;


@RestController
public class RouterCtrl {
    @RequestMapping("/**/{path:[^.]*}")
    public ModelAndView redirect() {
        return new ModelAndView("forward:/");
    }
}

请考虑:

  1. Your backend endpoints must start with the prefix api/ (or some other distinctive word)

  2. Deal with the 404 not found with Router Vue, something like this:

    Vue.use(Router);
    
    const router = new Router({
        mode: 'history',
        base: process.env.BASE_URL,
        routes: [
            {
                path: '/',
                name: 'home',
                component: HomeRoute
            },
            {
                path: '/myroute',
                name: 'myroute',
                component: MyRoute
            },
            {
                path: '/:catchAll(.*)',
                name: 'notFound',
                component: NotFound
            }
        ]
    });
    
    export default router;
    
我制作了一个简单的gif动画以进行说明:9

0
我建议您把以下代码删除:
@RequestMapping("/")
  public Greeting root(@RequestParam(value = "name", defaultValue = "Root!") String name) {
    return new Greeting(counter.incrementAndGet(), String.format(template, name));
  }

完成上述步骤后,所有路由都将通过index.html进行,然后您的vue路由将接管。

您可以将其他端点放在/api或其他位置后面。


是的,如果我删除该映射,我会直接进入我的前端。但是我仍然无法直接在浏览器中访问http://localhost:8080/MyRoute或http://localhost:8080/myroute,只有当我点击使用<router-link to="/MyRoute">GoToMyRoute</router-link>创建的路由链接时才能访问。 - u123

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接