如何使用反应路由器和弹簧启动控制器

Sri*_*wda 6 spring-mvc reactjs spring-boot react-router react-redux

这是我的 index.js 文件

import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter } from 'react-router-dom'
import App from './components/App';

ReactDOM.render((
             <BrowserRouter>
                <App />
             </BrowserRouter>
             ), document.getElementById('root')
            );
Run Code Online (Sandbox Code Playgroud)

这是 App.js

import React, { Component } from 'react';
import Main from './Main';

class App extends Component {
render() {
return (
      <div>
        <Main />
      </div>
  );
 }
}

export default App;
Run Code Online (Sandbox Code Playgroud)

这是我的 Main.js 文件

import React, { Component } from 'react';
import { Switch, Route } from 'react-router-dom';
import Home from './Home';
import AdminHome from './AdminHome';

class Main extends Component {
render() {
return (
        <Switch>
          <Route exact path='/admin' component={AdminHome}/>
          <Route exact path='/' component={Home}/>
        </Switch>
  );
 }
}

export default Main;
Run Code Online (Sandbox Code Playgroud)

路由器没有路由到 /admin 但它路由到 / ,当我运行应用程序并点击 url 'localhost:8080/admin' 它说白标错误。

我对如何使用 React 路由器和控制器感到非常困惑,谁能建议我一种方法。

我只是通过为 Spring Boot 控制器中的每个请求返回index.html来实现路由。

Flo*_*zea 14

如果它不是静态资源或不是 api 调用,我会使用过滤器将请求转发到 index.html。

如果静态资源位于 /resources/static 中,则由 spring boot 自动提供服务。我将它们保存在特定文件夹 /resources/static/ rct中以便于过滤。(我不想因为正则表达式而头痛)

反应应用程序的index.html路径:

<script type="text/javascript" src="http://localhost:8080/rct/js/myreactapp.js"></script>
Run Code Online (Sandbox Code Playgroud)

现在过滤器RedirectToIndexFilter.java

@Component
public class RedirectToIndexFilter implements Filter {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Override
    public void doFilter(ServletRequest request,
                         ServletResponse response,
                         FilterChain chain) throws IOException, ServletException {

        HttpServletRequest req = (HttpServletRequest) request;
        String requestURI = req.getRequestURI();

        if (requestURI.startsWith("/api")) {
            chain.doFilter(request, response);
            return;
        }

        if (requestURI.startsWith("/rct")) {
            chain.doFilter(request, response);
            return;
        }

        // all requests not api or static will be forwarded to index page. 
        request.getRequestDispatcher("/").forward(request, response);
    }

}
Run Code Online (Sandbox Code Playgroud)

控制器到服务器index.html

@Controller
public class AppController {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @GetMapping(value = {"/", ""})
    public String getIndex(HttpServletRequest request) {
        return "/rct/index.html";
    }

}
Run Code Online (Sandbox Code Playgroud)

控制器到服务器 api 调用

@RestController
public class ProjectController {

    private final ProjectService projectService;

    public ProjectController(ProjectService projectService) {
        this.projectService = projectService;
    }

    @GetMapping("/api/v1/projects/{id}")
    public ProjectData getProject(@PathVariable Long id) {
        projectService.get(id);
        ...
    }
Run Code Online (Sandbox Code Playgroud)

因此,任何非 api 或 static 的调用都会转发到 index.html。通过转发,您可以根据反应路由器的需要保留网址,但转发到index.html


小智 8

  • 这是之前发布的控制器的更新版本:
@Controller
public class ReactAppController {

    @RequestMapping(value = { "/", "/{x:[\\w\\-]+}", "/{x:^(?!api$).*$}/*/{y:[\\w\\-]+}","/error"  })
    public String getIndex(HttpServletRequest request) {
        return "/index.html";
    }

}

Run Code Online (Sandbox Code Playgroud)


小智 6

将所有不在api您的反应应用程序下的所有内容发送到您的反应应用程序的简单方法是创建一个使用 RegEx 的 API 控制器:

import javax.servlet.http.HttpServletRequest;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class ReactAppController {

    @RequestMapping(value = { "/", "/{x:[\\w\\-]+}", "/{x:^(?!api$).*$}/**/{y:[\\w\\-]+}" })
    public String getIndex(HttpServletRequest request) {
        return "/index.html";
    }

}
Run Code Online (Sandbox Code Playgroud)

这个控制器只是将所有内容重定向到 index.html,允许 react 和 react-router 发挥它的魔力。

RegEx 的工作方式如下:

  • '/' - 匹配根
  • '/{x:[\\w\\-]+}'- 匹配到第二个\。例如。\foo
  • '/{x:^(?!api$).*$}/**/{y:[\\w\\-]+}'- 匹配所有不以api. 例如。\foo\bar?page=1