1、结合@Async
和 ResponseBodyEmitter
来实现异步的处理和逐行返回数据
import org.springframework.http.MediaType;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyEmitter;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
@Service
public class YourAsyncService {
@Async
public void fetchDataAndSendToClient(ResponseBodyEmitter emitter) {
String apiUrl = "your_model_api_url_here";
try {
URL url = new URL(apiUrl);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST");
connection.setDoOutput(true);
InputStream inputStream = connection.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
String line;
while ((line = reader.readLine()) != null) {
// 将每一行数据转为字符串并发送给前端
emitter.send(line, MediaType.TEXT_PLAIN);
}
reader.close();
emitter.complete();
} catch (IOException e) {
emitter.completeWithError(e);
}
}
}
然后在 YourController
中调用 YourAsyncService
:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyEmitter;
@Controller
@RequestMapping("/api")
public class YourController {
@Autowired
private YourAsyncService yourAsyncService;
@PostMapping("/asyncStreamData")
public @ResponseBody ResponseBodyEmitter asyncStreamData() {
ResponseBodyEmitter emitter = new ResponseBodyEmitter();
yourAsyncService.fetchDataAndSendToClient(emitter);
return emitter;
}
}
这样,fetchDataAndSendToClient
方法中的代码会在一个异步线程中执行,并且 ResponseBodyEmitter
会在这个线程中逐行发送数据给前端。