突然间想用Java实现一下像ChatGPT一样的打字机输出效果,但是网上搜了相关教程感觉都不够满意。
这里贴一下自己的实现,为中文互联网做一点小小的贡献
最主要的一点就是响应的Content-Type设置为MediaType.TEXT_EVENT_STREAM_VALUE
实现效果如下
然后贴一下自己的代码吧
思路就是把从文件读取的每一个字符重新合并为一个数组,当然,也可以替换成从其他地方获得的字符
通过fromArray()方法将包装好的字符数组一个个按顺序返回,通过delayElements()指定一个延迟时间,从而实现类似ChatGPT的打字机效果
我这里是从resources/static/test.txt读取文件,通过转换后得到Character[]数组,一定要是包装类数组,基本数据类型不行。
感觉代码不够优雅,转换个字符竟然这么麻烦,希望能有大佬指点。
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.Resource;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Flux;import java.io.IOException;
import java.time.Duration;/*** @author Juyss* @version 1.0* @description: TODO* @date 2024/6/11 20:52*/
@RestController
@RequestMapping("/chat")
public class ChatController {@GetMapping(value = "/webflux",produces = MediaType.TEXT_EVENT_STREAM_VALUE)public Flux<Character> chatWebFlux(@RequestParam int delay) throws IOException {//读取文件作为字符串数组数据来源DefaultResourceLoader resourceLoader = new DefaultResourceLoader();Resource resource = resourceLoader.getResource("classpath:static/test.txt");byte[] byteArray = resource.getContentAsByteArray();String s = new String(byteArray);char[] charArray = s.toCharArray();//将基本数据类型的字符数组包装为引用数据类型Character[] characters = String.valueOf(charArray).chars().mapToObj(b -> (char) b).toArray(Character[]::new);//通过fromArray()方法将包装好的字符数组一个个按顺序返回,通过delayElements()指定一个延迟时间,从而实现类似ChatGPT的打字机效果return Flux.fromArray(characters).delayElements(Duration.ofMillis(delay));}
}