java实现异步回调返回给前端

JaneYork 2024-07-28 12:03:01 阅读 75

在Java中实现异步回调并将结果返回给前端,通常是在Web应用开发中处理耗时操作时所采用的技术手段,以避免阻塞HTTP请求线程并提高用户体验。以下是一个简单的例子,说明如何通过Spring WebFlux或者Servlet 3.0及以上标准的异步API配合JSON响应的方式实现这一目标。

示例1 - 使用Spring WebFlux(非阻塞IO)

<code>import org.springframework.web.bind.annotation.*;

import reactor.core.publisher.Mono;

@RestController

public class AsyncController {

@GetMapping("/asyncTask")

public Mono<String> asyncTask(@RequestParam("taskId") String taskId) {

return doAsyncTask(taskId).map(result -> {

// 这里假设doAsyncTask返回Mono对象,当异步任务完成时会填充结果

return ResponseEntity.ok().body(result);

});

}

private Mono<YourResultType> doAsyncTask(String taskId) {

return Mono.create(sink -> {

// 创建一个异步任务,在完成后回调

someService.doSomethingAsync(taskId, new SomeCallback(sink));

});

}

class SomeCallback implements AsyncCallback<YourResultType> {

private final MonoSink<YourResultType> sink;

public SomeCallback(MonoSink<YourResultType> sink) {

this.sink = sink;

}

@Override

public void onResult(YourResultType result) {

// 当异步任务完成时,通过sink.success()传递结果

sink.success(result);

}

@Override

public void onError(Throwable error) {

// 如果发生错误,通过sink.error()传递异常

sink.error(error);

}

}

}

// 假设`YourResultType`是你异步任务的结果类型

示例2 - 使用Servlet 3.0异步API(阻塞IO但不阻塞HTTP线程)

import javax.servlet.AsyncContext;

import javax.servlet.ServletException;

import javax.servlet.annotation.WebServlet;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import java.io.IOException;

@WebServlet(urlPatterns = "/asyncTask", asyncSupported = true)

public class AsyncServlet extends HttpServlet {

@Override

protected void doGet(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

final AsyncContext asyncContext = request.startAsync();

Thread taskRunner = new Thread(() -> {

YourResultType result;

try {

// 执行异步任务

result = someService.doSomethingAsync(request.getParameter("taskId"));

} catch (Exception e) {

handleError(asyncContext, e);

return;

}

// 将结果写回响应并结束异步上下文

writeResponse(asyncContext, result);

});

taskRunner.start();

}

private void writeResponse(AsyncContext asyncContext, YourResultType result) {

HttpServletResponse response = (HttpServletResponse) asyncContext.getResponse();

try {

response.setContentType("application/json");

response.getWriter().write(objectMapper.writeValueAsString(result));

asyncContext.complete();

} catch (IOException e) {

handleError(asyncContext, e);

}

}

private void handleError(AsyncContext asyncContext, Throwable error) {

HttpServletResponse response = (HttpServletResponse) asyncContext.getResponse();

try {

response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);

response.getWriter().write(error.getMessage());

asyncContext.complete();

} catch (IOException e) {

// 处理写入错误...

}

}

}

在这两个示例中,核心思想都是启动一个异步任务,然后在任务完成后通过某种机制(如Reactor的MonoSink或Servlet的AsyncContext)将结果返回给前端。前端可以通过AJAX请求获取异步任务的结果,并根据返回的状态进行相应的处理,如展示数据或更新UI。



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。