Spring HandlerInterceptor fire and forget
Spring HandlerInterceptor fire and forget
我想知道在 HandlerInterceptor 中触发 HTTP 并忘记 Web 服务调用的最佳方法是什么(或者可能有更合适的方法)。假设我正在处理请求,我想为 HTTP 5XX 产生的每个响应通知一些 API(通过发送请求和请求的响应主体)。当然,通知应该发生在某个工作线程中(即火即忘的方式)。
使用 WebFluxes WebClient 这应该相对容易(使用 .subscribeOn(Schedulers.elastic()))。但是,如果 WebClient 不可用怎么办?
如您所见,例如,在 this related SO question 如何跟踪请求和响应并不总是一项简单的任务。
无论在哪里,为了执行您描述的即发即弃行为,您可以将您的方法注释为 @Async。通过这样做,Spring 将异步调用带注释的方法。
考虑以下使用 RestTemplate
的示例:
@Component
public class ErrorNotificationClient {
private final RestTemplate restTemplate;
public ErrorNotificationClient(RestTemplate restTemplate) {
this.restTemplate = restTemplate;
}
// Use HttpServletRequest and HttpServletResponse if available,
// exceptions, what you consider appropriate and have the ability
// to obtain
@Async
public void notifyError(
HttpServletRequest request,
HttpServletResponse response
) {
// Build your request as form url encoded, json, etc
final String url = "...";
final HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
// Serialize the request and response as necessary
final MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
map.add("request", "...");
map.add("response", "...");
final HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(map, headers);
// Invoke the remote call
final ErrorNotificationResult errorNotificationResult = restTemplate.postForObject(url, request, ErrorNotificationResult.class);
// Consider trace or log the result, for instance
}
}
要启用 Spring 异步处理,您需要在主配置或特定配置中定义 @EnableAsync
注释:
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
@Configuration
@EnableAsync
public class AsyncConfiguration {
}
我想知道在 HandlerInterceptor 中触发 HTTP 并忘记 Web 服务调用的最佳方法是什么(或者可能有更合适的方法)。假设我正在处理请求,我想为 HTTP 5XX 产生的每个响应通知一些 API(通过发送请求和请求的响应主体)。当然,通知应该发生在某个工作线程中(即火即忘的方式)。
使用 WebFluxes WebClient 这应该相对容易(使用 .subscribeOn(Schedulers.elastic()))。但是,如果 WebClient 不可用怎么办?
如您所见,例如,在 this related SO question 如何跟踪请求和响应并不总是一项简单的任务。
无论在哪里,为了执行您描述的即发即弃行为,您可以将您的方法注释为 @Async。通过这样做,Spring 将异步调用带注释的方法。
考虑以下使用 RestTemplate
的示例:
@Component
public class ErrorNotificationClient {
private final RestTemplate restTemplate;
public ErrorNotificationClient(RestTemplate restTemplate) {
this.restTemplate = restTemplate;
}
// Use HttpServletRequest and HttpServletResponse if available,
// exceptions, what you consider appropriate and have the ability
// to obtain
@Async
public void notifyError(
HttpServletRequest request,
HttpServletResponse response
) {
// Build your request as form url encoded, json, etc
final String url = "...";
final HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
// Serialize the request and response as necessary
final MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
map.add("request", "...");
map.add("response", "...");
final HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(map, headers);
// Invoke the remote call
final ErrorNotificationResult errorNotificationResult = restTemplate.postForObject(url, request, ErrorNotificationResult.class);
// Consider trace or log the result, for instance
}
}
要启用 Spring 异步处理,您需要在主配置或特定配置中定义 @EnableAsync
注释:
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
@Configuration
@EnableAsync
public class AsyncConfiguration {
}