尝试使用Open Liberty和React创建WEB应用

请使用Open Liberty官方页面上提供的以下示例来创建一个Web应用程序。
https://openliberty.io/guides/rest-client-reactjs.html

“Open Liberty是什么?” (What is Open Liberty?)

    • 高速で効率的なクラウドネイティブJavaマイクロサービスを構築するための軽量なオープンフレームワークです。

 

    • 要するにJava製のアプリケーションサーバーです。

 

    Open Liberty 公式ページ:https://openliberty.io/

环境

    • Windows11 + WSL2(Ubuntu 20.04.5)

 

    • Mavenインストール済み

 

    • ブラウザはEdge

 

    • node v16.13.2

 

    openjdk 17.0.8

克隆存储库并确认完成品。

将存储库克隆并切换到目录中。

git clone https://github.com/openliberty/guide-rest-client-reactjs.git
cd guide-rest-client-reactjs

在其中包含了两个文件夹,一个是”finish”,另一个是”start”。在”finish”文件夹中存放着样品的完成品。
请转到”finish”文件夹,并确认完成品。

cd finish
mvn liberty:run

在浏览器中打开http://localhost:9080/,您可以看到以下的屏幕。

react-table.png

尝试运行未完成的Web应用程序。

我們先切換到start目錄,然後執行mvn liberty:dev命令。這次即使在瀏覽器打開http://localhost:9080/,只會顯示一個空白頁面。但是,訪問http://localhost:9080/artists會返回JSON數據。

image.png

需要从http://localhost:9080/artists接收JSON数据,并使其能够在React中显示。

React部分的实现

首先,创建一个index.js文件。这个文件将作为React应用的入口点。

import React from 'react';
import ReactDOM from 'react-dom';
import './Styles/index.css';
import App from './Components/App';

ReactDOM.render(<App />, document.getElementById('root'));

此外,按照以下方式创建App.js文件。

import React from 'react';
import {ArtistTable} from './ArtistTable';

function App() {
  return (
      <ArtistTable/>
  );
}

export default App;

创建ArtistTable.js文件。此组件用于创建表格。

import React, { useEffect, useMemo, useState } from 'react';
import { useTable, usePagination, useSortBy } from 'react-table';
import '../Styles/table.css'

export function ArtistTable() {

  const [posts, setPosts] = useState([]);


  const data = useMemo(() => [...posts], [posts]);

  const columns = useMemo(() => [{
    Header: 'Artist Info',
    columns: [
      {
        Header: 'Artist ID',
        accessor: 'id'
      },
      {
        Header: 'Artist Name',
        accessor: 'name'
      },
      {
        Header: 'Genres',
        accessor: 'genres',
      }
    ]
  },
  {
    Header: 'Albums',
    columns: [
      {
        Header: 'Number of Tracks',
        accessor: 'ntracks',
      },
      {
        Header: 'Title',
        accessor: 'title',
      }
    ]
  }
  ], []
  );

  const tableInstance = useTable(
    {
      columns,
      data,
      initialState: { pageIndex: 0, pageSize: 4 }
    },
    useSortBy,
    usePagination
  )

  const {
    getTableProps,
    getTableBodyProps,
    headerGroups,
    prepareRow,
    page,
    canPreviousPage,
    canNextPage,
    pageOptions,
    pageCount,
    gotoPage,
    nextPage,
    previousPage,
    setPageSize,
    state: { pageIndex, pageSize }
  } = tableInstance;


  return (
    <>
      <h2>Artist Web Service</h2>
      <table {...getTableProps()}>
        <thead>
          {headerGroups.map(headerGroup => (
            <tr {...headerGroup.getHeaderGroupProps()}>
              {headerGroup.headers.map((column) => (
                <th {...column.getHeaderProps(column.getSortByToggleProps())}>
                  {column.render('Header')}
                  <span>
                    {column.isSorted
                      ? column.isSortedDesc
                        ? ' ?'
                        : ' ?'
                      : ''}
                  </span>
                </th>
              ))}
            </tr>
          ))}
        </thead>
        <tbody {...getTableBodyProps()}>
          {page.map((row, i) => {
            prepareRow(row)
            return (
              <tr {...row.getRowProps()}>
                {row.cells.map(cell => {
                  return <td {...cell.getCellProps()}>{cell.render('Cell')}</td>
                })}
              </tr>
            )
          })}
        </tbody>
      </table>
      <div className="pagination">
        <button onClick={() => previousPage()} disabled={!canPreviousPage}>
          {'Previous'}
        </button>{' '}
        <div class="page-info">
          <span>
            Page{' '}
            <strong>
              {pageIndex + 1} of {pageOptions.length}
            </strong>{' '}
          </span>
          <span>
            | Go to page:{' '}
            <input
              type="number"
              defaultValue={pageIndex + 1}
              onChange={e => {
                const page = e.target.value ? Number(e.target.value) - 1 : 0
                gotoPage(page)
              }}
              style={{ width: '100px' }}
            />
          </span>{' '}
          <select
            value={pageSize}
            onChange={e => {
              setPageSize(Number(e.target.value))
            }}
          >
            {[4, 5, 6, 9].map(pageSize => (
              <option key={pageSize} value={pageSize}>
                Show {pageSize}
              </option>
            ))}
          </select>
        </div>
        <button onClick={() => nextPage()} disabled={!canNextPage}>
          {'Next'}
        </button>{' '}
      </div>
    </>
  );
}

无法接收JSON数据,因此需要进行以下操作:导入axios并添加GetArtistsInfo函数。GetArtistsInfo函数使用axios从http://localhost:9080/artists接收数据。


import React, { useEffect, useMemo, useState } from 'react';
import axios from 'axios';
import { useTable, usePagination, useSortBy } from 'react-table';
import '../Styles/table.css'

export function ArtistTable() {

  const [posts, setPosts] = useState([]);

  const GetArtistsInfo = async () => {
    const response = await axios.get('http://localhost:9080/artists')
      .then(response => {
        const artists = response.data;
        for (const artist of artists) {
          const { albums, ...rest } = artist;
          for (const album of albums) {
            setPosts([...posts, { ...rest, ...album }]);
            posts.push({ ...rest, ...album });
          }
        };
      }).catch(error => { console.log(error); });
  };
  const data = useMemo(() => [...posts], [posts]);

  const columns = useMemo(() => [{
    Header: 'Artist Info',
    columns: [
      {
        Header: 'Artist ID',
        accessor: 'id'
      },

// 以下省略・・・・・

当以上的所有事情都结束之后,返回到start目录下,并执行以下命令。执行这个命令会进行构建。

mvn process-resources

让我们访问 http://localhost:9080。将会显示如下的页面。

image.png

結論

我们可以使用 Open Liberty 和 React 来实现一个简单的网络服务。大家也可以试试看!

广告
将在 10 秒后关闭
bannerAds