1、首先在WebMvcConfig类中注册拦截器拦截指定路径接口
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(n8nInterceptor)
.addPathPatterns("/test/rest/**");
}
2、实现转发
@Slf4j
@Component
public class N8nInterceptor implements HandlerInterceptor {
@Resource
private N8nProxyService n8nProxyService;
@Override
public boolean preHandle(@NotNull HttpServletRequest request, @NotNull HttpServletResponse response, @NotNull Object handler) throws Exception {
log.info("请求路径:{}", request.getRequestURL());
if (shouldForwardToN8n(request)) {
try {
//请求拦截预处理
n8nProxyService.processN8nRequest(request);
// 1. 转发请求并获取原始响应
ResponseEntity<String> n8nResponse = n8nProxyService.forwardToN8nTest(request);
// 2.特定接口业务处理
n8nProxyService.processN8nResponse(request, n8nResponse.getBody(), n8nResponse.getStatusCode());
response.setContentType("application/json;charset=UTF-8");
response.setCharacterEncoding("UTF-8");
// 3. 写入响应内容
try (PrintWriter writer = response.getWriter()) {
writer.write(Objects.requireNonNull(n8nResponse.getBody()));
}
return false;
} catch (Exception e) {
log.error("请求处理失败", e);
response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
response.getWriter().write("{\"error\":\"请求处理失败\"}");
return false;
}
}
return true;
}
private boolean shouldForwardToN8n(HttpServletRequest request) {
String path = request.getRequestURI();
return path.startsWith("/test");
}
}
3、业务逻辑实现
@Slf4j
@Service
public class N8nProxyService {
@Resource
private ObjectMapper objectMapper;
@Resource
RestTemplate restTemplate;
/**
* 请求预处理业务
*/
public void processN8nRequest(HttpServletRequest request) {
}
/**
* 请求转发
*/
public ResponseEntity<String> forwardToN8nTest(HttpServletRequest originalRequest) throws IOException, URISyntaxException {
// 构建转发URL
String url = "http://localhost:8080" + originalRequest.getRequestURI().replace("/test", "") + (originalRequest.getQueryString() != null ? "?" + originalRequest.getQueryString() : "");
log.info("转发路径:{}", url);
//设置请求头
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.add("Cookie", originalRequest.getHeader("Cookie"));
httpHeaders.setContentType(MediaType.APPLICATION_JSON);
Method method = Method.valueOf(originalRequest.getMethod().toUpperCase());
log.info("请求方法:{}", method);
// 根据请求方法选择HttpMethod
HttpMethod httpMethod = HttpMethod.resolve(method.name());
if (httpMethod == null) {
throw new IllegalArgumentException("不支持的http请求方法: " + method);
}
RequestEntity<byte[]> requestEntity = null;
requestEntity = createRequestEntity(originalRequest, url, httpHeaders);
ResponseEntity<String> result = restTemplate.exchange(requestEntity, String.class);
if (result.getStatusCode() == HttpStatus.OK) {
return result;
} else {
log.error("请求转发失败:{}", result);
throw new RuntimeException("请求转发失败");
}
}
/**
* 构造request实体
*/
private RequestEntity<byte[]> createRequestEntity(HttpServletRequest request, String url, HttpHeaders httpHeaders) throws URISyntaxException, IOException {
String method = request.getMethod();
//获取请求方式
HttpMethod httpMethod = HttpMethod.resolve(method);
//处理body部分
InputStream inputStream = request.getInputStream();
byte[] body = StreamUtils.copyToByteArray(inputStream);
return new RequestEntity<byte[]>(body, httpHeaders, httpMethod, new URI(url));
}
/**
* 转发响应业务处理
*/
public void processN8nResponse(HttpServletRequest request, String responseBody, HttpStatus statusCode) {
}
}
2996

被折叠的 条评论
为什么被折叠?



