SpringBoot实现请求拦截转发

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) {
        
    }
}

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值