react+springboot前后端分离开发Scheduler控件获取远程数据问题

目录

跨域通信

后端代码

前端代码

获取数据无法渲染

渲染时间差

Json格式问题


跨域通信

首先要解决的是跨域问题:react框架默认3000端口,然而springboot是8080端口,所以在后端要添加一个CorsConfig

后端代码

@Configuration
public class CorsConfig {


    @Bean
    public WebMvcConfigurer corsConfigurer() {
        return new WebMvcConfigurerAdapter() {
            @Override
            public void addCorsMappings(CorsRegistry registry) {
                System.out.println("跨域配置");
                registry.addMapping("/api/**")//我前端发起的请求是/api/的格式
                        .allowedOrigins("*")
                        .allowedMethods("GET", "POST", "PUT", "DELETE")
                        .allowedHeaders("*");
            }
        };
    }

}

同时前端也要添加

'Access-Control-Allow-Origin': '*'

请求头来告诉浏览器你要发起跨域请求了

前端代码

useEffect(() => {
        // Fetch schedule data from backend API
        fetch('http://localhost:8080/api/这里写你自己要访问的地址', {
            headers: {
                'Access-Control-Allow-Origin': '*'//就是这个请求头
            }
        })
            .then(response => response.json())
            .then(data => {
                const formattedData = data.map(item => ({//这里是时间格式问题
                    ...item,
                    startTime: new Date(item.startTime),
                    endTime: new Date(item.endTime)
                }));
                setScheduleData(formattedData);
                console.log('成功发送请求:', data);
            })
            .catch(error => console.error(error));
    }, []);

处理完后我发现还是不行,无法跨域访问,在一顿搜素后得知可能是由于浏览器的安全机制导致的。在跨域请求时,浏览器会先发送一个OPTIONS请求来确认服务器是否允许跨域请求,只有在服务器返回正确的响应头后,浏览器才会发送真正的请求。因此,需要在Spring Boot后端中添加对OPTIONS请求的处理,以便正确地响

@CrossOrigin(origins = "*")
@RestController
@RequestMapping("/api")
public class MyController {
 
    @RequestMapping(value = "/myEndpoint", method = RequestMethod.OPTIONS)
    public ResponseEntity handle() {
        HttpHeaders headers = new HttpHeaders();
        headers.add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");
        headers.add("Access-Control-Allow-Headers", "Content-Type");
        headers.add("Access-Control-Max-Age", "3600");
        return new ResponseEntity(headers, HttpStatus.OK);
    }
}

应这些预检请求。

需要将 myEndpoint 替换为自己的请求路径。这个示例中的 /myEndpoint 只是一个示范,大家需要根据自己的实际情况来替换它。通过method不同来重载。
完成上述步骤后就成功获取到了数据了。


获取数据无法渲染

页面依然没有数据,但是通过控制台的输出我知道我获取到了数据,于是我又开始搜索是什么问题。

渲染时间差

找到了一个靠谱的答案说由于fetch请求需要一定的时间,因此在完成请求之前,组件已经被渲染,并且使用了默认的空数组作为数据源。可以将“ScheduleComponent”放在条件语句中,以确保只有在成功获取数据后才会显示组件。

与是我增加了代码

 if (scheduleData.length === 0) {
        return <div>Loading...</div>;
    }

这样子请求完成之前显示一个loading状态,等待数据加载完成后再渲染ScheduleComponent。当scheduleData数组的长度为0时,将显示“Loading...”文本;否则,将显示ScheduleComponent。

但是依然无法正确渲染出来

Json格式问题

于是我觉得应该是数据的问题,如何在一小时的搜索和尝试下发现了问题,

@RestController返回json时Jackson库的默认配置是将属性名转换为小写!!!

然而Scheduler控件中要求的数据都是首字母大写,所以我找到了三种解决方法,其中第三种最简单方便。
 

  1. 使用@JsonProperty注解:使用@JsonProperty注解,可以将Java类的属性与JSON属性名称映射。例如:
    public class MyObject {
       @JsonProperty("myProperty")
       private String myProperty;
    }

    这将将Java属性“myProperty”映射到JSON属性“myProperty”。

  2. 使用@JsonNaming注解:@JsonNaming注解允许指定一个自定义命名策略,在Jackson序列化和反序列化期间使用该策略。例如:
@JsonNaming(PropertyNamingStrategy.UpperCamelCaseStrategy.class)
public class MyObject {
  private String myProperty;
}

这将使用驼峰式命名约定,将Java属性名称转换为JSON属性名称。

        3.配置ObjectMapper:还可以通过配置ObjectMapper来自定义JSON序列化和反序列化期间使用的命名策略。例如:

@Configuration
public class JacksonConfig {

    @Bean
    public ObjectMapper objectMapper() {
        ObjectMapper mapper = new ObjectMapper();
        mapper.setPropertyNamingStrategy(PropertyNamingStrategy.UPPER_CAMEL_CASE);
        return mapper;
    }
}

这将创建一个自定义的ObjectMapper bean,它将使用大写驼峰式命名约定。然后将自动应用于所有使用Jackson库进行序列化和反序列化的Spring Bean。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值