首页 > 其他分享 >SpringBoot+React 前后端分离

SpringBoot+React 前后端分离

时间:2023-04-23 17:35:32浏览次数:52  
标签:const SpringBoot 分离 React file 请求 页面

SpringBoot+React 前后端分离

写个转发数据的小工具,本来只想开个 SpringBoot 服务带个页面,但感觉有点难受,正好之前研究了 React,尝试一下前后端分离。

后端

简单用 SpringBoot 起个服务,写个接口处理请求:

@RestController
@RequestMapping("/data")
public class DataController {

    @Autowired
    HttpRequestService httpRequestService;

    @Autowired
    TestService testService;

    @RequestMapping("/test")
    public List<?> reportTest(@RequestParam("file") MultipartFile file) throws IOException {
        InputStream inputStream = file.getInputStream();
        System.out.println(file.getName());
        List<TestEntity> testEntities = testService.DataListRead(inputStream, file.getOriginalFilename());
        httpRequestService.postTest(JSON.toJSONString(testEntities));
        // 进行文件的读取和处理操作
        return testEntities;
    }
}

我这个方法的具体业务就是接收前端请求传来的文件,调用 Service 解析内容并转发出去。直接返回解析后的对象列表了,这是不太好的,应该封装一个 ResponseBody 才对,但我这就随意了。

后端 SpringBoot 默认的端口是 8080,启动后放着就可以了。

前端

前端在 VSCode 中使用 NPM 初始化一个纯净的React项目,然后按步骤补充几个关键文件:

  1. App.js,应用程序最大的组件;
  2. index.html,页面入口;
  3. index.js,将 App 渲染到页面上;
  4. style.css,让页面好看的(可选)。

首先是 App.js 组件:

import React, { useState } from 'react';
import axios from 'axios';
import './style.css';  // 引入样式文件

function FileUpload() {
  const [file, setFile] = useState(null);
  const [interfaceType, setInterfaceType] = useState(null);

  const handleSubmit = async (e) => {
    e.preventDefault();
    const formData = new FormData();
    formData.append('file', file);

    let url = '';
    switch (interfaceType) {
      case 'test':
        url = 'http://localhost:8080/data/test';
        break;
      case 'vehicle':
        url = 'http://localhost:8080/data/vehicle';
        break;
      case 'battery':
        url = 'http://localhost:8080/data/battery';
        break;
      default:
        return;
    }

    try {
      const res = await axios.post(url, formData, {
        headers: {
          'Content-Type': 'multipart/form-data'
        }
      });
      console.log(res);
      alert('文件上传成功');
    } catch (error) {
      console.error(error);
      alert('文件上传失败');
    }
  };

  return (
    <div>
      {/* <h1>文件上传</h1> */}
      <form onSubmit={handleSubmit}>
        <div>
          <label htmlFor="fileInput">请选择文件:</label>
          <input type="file" id="fileInput" accept=".xls,.xlsx" onChange={(e) => setFile(e.target.files[0])} />
        </div>
        <div>
          <label htmlFor="testOption">测试数据 </label>
          <input type="radio" name="interface" id="testOption" value="test" onChange={(e) => setInterfaceType(e.target.value)} />
        </div>
        <div>
          <label htmlFor="vehicleOption">车辆数据 </label>
          <input type="radio" name="interface" id="vehicleOption" value="vehicle" onChange={(e) => setInterfaceType(e.target.value)} />
        </div>
        <div>
          <label htmlFor="batteryOption">电池数据 </label>
          <input type="radio" name="interface" id="batteryOption" value="battery" onChange={(e) => setInterfaceType(e.target.value)} />
        </div>
        <div>
          <button type="submit">提交</button>
        </div>
      </form>
    </div>
  );
}

export default FileUpload;

仅由一个组件构成,其中使用了 axios 发送请求,参考 AXIOS 文档。

然后是 index.js 文件,将组件渲染到页面上:

import React from 'react';
import ReactDOM from 'react-dom';
import FileUpload from './App';

//ReactDOM.render(<FileUpload />, document.getElementById('root'));
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<FileUpload />);

由于使用 NPM 安装的 React 是18版本的,因此 ReactDOM.render 方法已经被弃用了,需要换成 ReactDOM.createRoot 方法,大同小异。

HTML 页面和 CSS 样式就不用放了,一个是只有个 root 节点,一个我自己都看不懂。

然后在项目路径下使用 npm start 启动项目,React 的默认端口是 3000,打开就可以看到页面了。

跨域问题

此时前端应用和后端服务都已经部署好了,在页面上发起请求尝试,在请求情况中可以看到请求失败了,状态为 CORS 错误,这是由于浏览器的同源策略导致的:

同源策略(Same origin policy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。在同一个协议,域名,端口号下时,是为同源。

同源策略是浏览器的行为,是为了保护本地数据不被 JS 代码获取回来的数据污染,因此拦截的是客户端发出的请求回来的数据接收,即请求发送了,服务器响应了,但是无法被浏览器接收。

在上面,我们访问的是 3000 端口的前端应用,而前端应用去后端服务 8080 端口请求数据,因此触发了浏览器的跨域请求保护。

当然 CORS 问题是可以解决的,而且解决的办法有很多,我选择最简单的一种,在后端服务的 Controller 上添加注解 @CrossOrigin

@CrossOrigin
@RestController
@RequestMapping("/data")
public class DataController

这样这个 Controller 的请求就支持跨域访问了。但如果有很多地方或者整个项目都要支持跨域访问的话,还是使用 Config 配置的方式好一点。

标签:const,SpringBoot,分离,React,file,请求,页面
From: https://www.cnblogs.com/qiyuanc/p/Back12.html

相关文章

  • 基于SpringBoot+Vue的音乐网站
    本次项目是基于SpringBoot+Vue的前后端分离项目,旨在熟练相关框架,掌握相关技术,拓展个人知识面。音乐来源:本地用户页面:Web项目亮点:根据歌词、音乐旋律、定位时间线(老师的意见)确定好方向,开始项目、收集资料、准备相关的开发环境和软件等。了解项目的结构与逻辑,确定基本功能,需求......
  • springboot~关于md5签名引发的问题
    事实是这样的,我有个接口,这个接口不能被篡改,于是想到了比较简单的md5对url地址参数进行加密,把这个密码当成是sign,然后服务端收到请求后,使用相同算法也生成sign,两个sign相同就正常没有被篡改过。问题的出现接口中的参数包括userId,extUserId,时间,其中extUserId字符编码,中间会有+......
  • springboot集成JWT token验证
    登录模式基于session登录基于session的登录(有回话状态),用户携带账号密码发送请求向服务器,服务器进行判断,成功后将用户信息放入session,用户发送请求判断session中是否有用户信息,有的话放行,没有的话进行拦截,但是考虑到时App产品,牵扯到要判断用户的session,需要sessionID,还要根据sess......
  • Springboot yml配置参数加密 ,jasypt自定义解密器
    原文链接:https://www.cnblogs.com/JCcccit/p/16868137.html前言 最近项目组开始关注一些敏感数据的明文相关的事宜,其实这些东西也是都有非常成熟的解决方案。既然最近着手去解决这些事情,那么也顺便给还未了解的大伙普及一下。Springbootyml配置参数数据加密(数据加密篇......
  • springboot使用mybatis应用clickhouse
    一、clickhouse,说白了还是数据库,不一样的是clickhouse是列式存储,和传统的MySQL行式存储不同的地方在于,查询和所储。1)查询,行式和列式的区别,图形说明说明:理解上来说,行式对于一条数据的完整性索引会更快。而列式对于统计和查询指定数据会更加块。2)数据......
  • Springboot提高
    全局异常处理器未做处理的情况:当我没没有做任何异常处理时,mapper接口操作数据库出错时,会将异常向上抛给ServiceService中的异常会往上抛给controllercontroller会将异常抛给框架响应给浏览器一个JSON格式的数据这个数据并不符合我们统一响应结果的规范如何处理?方案一:......
  • Java__SpringBoot与Vue连接
    SpringBoot与Vue注解RequestMapping("/dir/")创建一个方便前端调用的接口目录/接口函数,前端可以获取到函数返回的数据@RestController@RequestMapping("/dir/")publicclassBotInfoController{@RequestMapping("getinfo/")publicMap<String,String>GetI......
  • react
    React是一个用于构建用户界面的JAVASCRIPT库。React主要用于构建UI,很多人认为React是MVC中的V(视图)。React起源于Facebook的内部项目,用来架设Instagram的网站,并于2013年5月开源。React拥有较高的性能,代码逻辑非常简单,越来越多的人已开始关注和使用它。1.......
  • mysql 主从,django操作读写分离
    目录mysql主从搭建步骤1.准备两台机器2.创建文件夹,文件(目录映射)3编写mysql配置文件(主,从)重要启动mysql容器,并做端口和目录映射连接主库修改新建用户连接从库修改配置django操作多数据库方法1.配置文件2.手动读写分离3.自动读写分离4.配置文件添加新点mysql主从目的: 主要做读......
  • 1 python操作哨兵 、2 python操作集群、3 缓存优化、4 mysql 主从 、5 django使用多数
    目录1python操作哨兵2python操作集群3缓存优化3.1redis缓存更新策略3.2缓存击穿,雪崩,穿透4mysql主从5django使用多数据库做读写分离1python操作哨兵#高可用架构后---》不能直接连某一个主库了---》主库可能会挂掉,后来它就不是主库了#之前学的连接redis的操作,就用不......