java - Spring Boot React 在单独的包中

标签 java spring reactjs spring-boot jhipster

我有一个 spring boot、java 8 API,我想添加一个 React 前端,以使 API 操作更易于导航和使用。我用过JHipster生成器来生成 React 应用程序。然后我只是将 Web 部分放入我的应用程序中,但是每当我运行 Spring Boot 应用程序并尝试导航到端口 :8080 时,我都会看到以下页面:

enter image description here

控制台中出现以下错误:

2019-07-15 15:07:21.414  INFO 29145 --- [)-10.15.114.229] o.a.c.c.C.[.[.[/]                                            : Initializing Spring DispatcherServlet 'dispatcherServlet'
2019-07-15 15:07:21.414  INFO 29145 --- [)-10.15.114.229] o.s.w.s.DispatcherServlet                                    : Initializing Servlet 'dispatcherServlet'
2019-07-15 15:07:21.414 DEBUG 29145 --- [)-10.15.114.229] o.s.w.s.DispatcherServlet                                    : Detected StandardServletMultipartResolver
2019-07-15 15:07:21.426 DEBUG 29145 --- [)-10.15.114.229] o.s.w.s.DispatcherServlet                                    : enableLoggingRequestDetails='false': request parameters and headers will be masked to prevent unsafe logging of potentially sensitive data
2019-07-15 15:07:21.426  INFO 29145 --- [)-10.15.114.229] o.s.w.s.DispatcherServlet                                    : Completed initialization in 12 ms
2019-07-15 15:07:25.079 DEBUG 29145 --- [nio-8080-exec-1] o.s.w.s.DispatcherServlet                                    : GET "/", parameters={}
2019-07-15 15:07:25.093 DEBUG 29145 --- [nio-8080-exec-1] s.d.s.w.PropertySourcedRequestMappingHandlerMapping          : looking up handler for path: /
2019-07-15 15:07:25.128 DEBUG 29145 --- [nio-8080-exec-1] o.s.w.s.h.SimpleUrlHandlerMapping                            : Mapped to ResourceHttpRequestHandler ["classpath:/META-INF/resources/", "classpath:/resources/", "classpath:/static/", "classpath:/public/", "/"]
2019-07-15 15:07:25.130 DEBUG 29145 --- [nio-8080-exec-1] o.s.w.s.r.ResourceHttpRequestHandler                         : Resource not found
2019-07-15 15:07:25.131 DEBUG 29145 --- [nio-8080-exec-1] o.s.w.s.DispatcherServlet                                    : Completed 404 NOT_FOUND
2019-07-15 15:07:25.152 DEBUG 29145 --- [nio-8080-exec-1] o.s.w.s.DispatcherServlet                                    : "ERROR" dispatch for GET "/error", parameters={}
2019-07-15 15:07:25.153 DEBUG 29145 --- [nio-8080-exec-1] s.d.s.w.PropertySourcedRequestMappingHandlerMapping          : looking up handler for path: /error
2019-07-15 15:07:25.167 DEBUG 29145 --- [nio-8080-exec-1] o.s.w.s.m.m.a.RequestMappingHandlerMapping                   : Mapped to public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)
2019-07-15 15:07:25.199 DEBUG 29145 --- [nio-8080-exec-1] o.s.w.s.v.ContentNegotiatingViewResolver                     : Selected 'text/html' given [text/html, text/html;q=0.8]
2019-07-15 15:07:25.208 DEBUG 29145 --- [nio-8080-exec-1] o.s.w.s.DispatcherServlet                                    : Exiting from "ERROR" dispatch, status 404

这是我的项目结构:

FooApplication
├── build.gradle
├── api/
    ├── src.main.java.com.foo/
            ├── FooApplication.java
    └── build.gradle
├── web/
    ├── node_modules/
    ├── src.main.webapp/
        ├── app/
            ├── index.tsx
            ├── routes.tsx
            └── app.tsx
        └── index.html
    ├── webpack/
        └── webpack.common.js
    └── build.gradle

这是我的 webpack.common.js 文件:

const webpack = require('webpack');
const {BaseHrefWebpackPlugin} = require('base-href-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
const path = require('path');

const utils = require('./utils.js');

const getTsLoaderRule = env => {
  const rules = [
    {
      loader: 'cache-loader',
      options: {
        cacheDirectory: path.resolve('build/cache-loader')
      }
    },
    {
      loader: 'thread-loader',
      options: {
        // There should be 1 cpu for the fork-ts-checker-webpack-plugin.
        // The value may need to be adjusted (e.g. to 1) in some CI environments,
        // as cpus() may report more cores than what are available to the build.
        workers: require('os').cpus().length - 1
      }
    },
    {
      loader: 'ts-loader',
      options: {
        transpileOnly: true,
        happyPackMode: true
      }
    }
  ];
  if (env === 'development') {
    rules.unshift({
      loader: 'react-hot-loader/webpack'
    });
  }
  return rules;
};

module.exports = options => ({
  cache: options.env !== 'production',
  resolve: {
    extensions: [
      '.js', '.jsx', '.ts', '.tsx', '.json'
    ],
    modules: ['node_modules'],
    alias: {
      app: utils.root('src/main/webapp/app/')
    }
  },
  module: {
    rules: [
      {
        test: /\.tsx?$/,
        use: getTsLoaderRule(options.env),
        include: [utils.root('./src/main/webapp/app')],
        exclude: [utils.root('node_modules')]
      },
      {
        test: /\.(jpe?g|png|gif|svg|woff2?|ttf|eot)$/i,
        loader: 'file-loader',
        options: {
          digest: 'hex',
          hash: 'sha512',
          name: 'content/[hash].[ext]'
        }
      },
      {
        enforce: 'pre',
        test: /\.jsx?$/,
        loader: 'source-map-loader'
      },
      {
        test: /\.tsx?$/,
        enforce: 'pre',
        loader: 'tslint-loader',
        exclude: [utils.root('node_modules')]
      }
    ]
  },
  stats: {
    children: false
  },
  optimization: {
    splitChunks: {
      cacheGroups: {
        commons: {
          test: /[\\/]node_modules[\\/]/,
          name: 'vendors',
          chunks: 'all'
        }
      }
    }
  },
  plugins: [
    new webpack.DefinePlugin({
      'process.env': {
        NODE_ENV: `'${options.env}'`,
        VERSION: `'${utils.parseVersion()}'`,
        DEBUG_INFO_ENABLED: options.env === 'development',
        // The root URL for API calls, ending with a '/' - for example: `"https://www.jhipster.tech:8081/myservice/"`.
        // If this URL is left empty (""), then it will be relative to the current context.
        // If you use an API server, in `prod` mode, you will need to enable CORS
        // (see the `jhipster.cors` common JHipster property in the `application-*.yml` configurations)
        SERVER_API_URL: `''`
      }
    }),
    new ForkTsCheckerWebpackPlugin({tslint: true}),
    new CopyWebpackPlugin([
      {from: './node_modules/swagger-ui/dist/css', to: 'swagger-ui/dist/css'},
      {from: './node_modules/swagger-ui/dist/lib', to: 'swagger-ui/dist/lib'},
      {from: './node_modules/swagger-ui/dist/swagger-ui.min.js', to: 'swagger-ui/dist/swagger-ui.min.js'},
      {from: './src/main/webapp//swagger-ui/', to: 'swagger-ui'},
      {from: './src/main/webapp/static/', to: 'content'},
      {from: './src/main/webapp/favicon.ico', to: 'favicon.ico'},
      {from: './src/main/webapp/manifest.webapp', to: 'manifest.webapp'},
      // jhipster-needle-add-assets-to-webpack - JHipster will add/remove third-party resources in this array
      {from: './src/main/webapp/robots.txt', to: 'robots.txt'}
    ]),
    new HtmlWebpackPlugin({
      template: './src/main/webapp/index.html',
      chunksSortMode: 'dependency',
      inject: 'body'
    }),
    new BaseHrefWebpackPlugin({baseHref: '/'}),
  ]
});

如何让 Spring Boot 在导航到 localhost:8080 时提供 index.html 文件?我知道我必须覆盖一些默认的 Spring Boot 配置才能使其正常工作,但我不清楚哪些配置。

我可以根据要求提供更多文件的详细信息,只是不想在帖子中添加不必要的信息。

最佳答案

请求应用程序入口点的映射、读取文件并返回内容。就我而言,React 代码存储在/tmp/build/index.html 中。简化并忽略错误,它可能看起来像这样:

    @RequestMapping(
            value = "",
            method = RequestMethod.GET)
    public ResponseEntity<String> getIndexContent() {
        final File file = new File("/tmp/build/index.html");
        final String content =
                FileUtils.readFileToString(
                        file,
                        StandardCharsets.UTF_8);
        return ResponseEntity
                .ok()
                .contentType(MediaType.TEXT_HTML)
                .body(content);
    }

关于java - Spring Boot React 在单独的包中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57046856/

相关文章:

java - 如何通过输入整数月份和年份来查找特定月份?

java - Spring data jpa + 连接2个表

java - 如何在 Spring 中验证长 PathParam

javascript - SASS child rule setting inside based on parent 下?

javascript - Redux 存储中的确定性 API 调用结果

javascript - 导航到另一个页面时下一个/链接丢失状态

java - 在java中从末尾提取子字符串到第一个字母

java - Eclipse JNI共享库“架构字宽不匹配”错误的ELF类UnsatisfiedLinkError

java - 创建自定义 Swing 菜单类

java - Spring - Bean 没有被注入(inject)