实现接口转发Filter

实现接口转发Filter

package com.quanzhi.api.operation.common.web.filter;

import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
import com.quanzhi.api.operation.biz.service.impl.SysConfigServiceImpl;
import com.quanzhi.api.operation.common.util.dto.MonitorConfigDto;
import com.quanzhi.api.operation.common.util.utils.DataUtil;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.http.*;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.stereotype.Component;
import org.springframework.util.MultiValueMap;
import org.springframework.util.StreamUtils;
import org.springframework.web.client.RestTemplate;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.util.Collections;
import java.util.List;

@WebFilter
@Component
@Log4j2
@Order(3)
public class MonitorForwardFilter implements Filter {

    @Autowired
    private SysConfigServiceImpl sysConfigService;

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException{

        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse resp = (HttpServletResponse) response;
        String requestUrl = req.getRequestURI();

        // 获取需要处理的请求列表
        List<String> urls = getUrls();

        // 需要处理的请求列表,如果包含进行转发
        if (urls.contains(requestUrl)) {

           // 1.处理请求链接
            String url = manageUrl(req);

            log.info("MonitorForwardFilter is forwarding " + url);

            // 将请求转发,得到的结果和响应头返回客户端
            forwardUrl(url, req, resp);

        } else {
            chain.doFilter(request,response);
        }
    }


    private List<String> getUrls() {

        Object configByName = sysConfigService.getConfigByName("forwardList");

        if (DataUtil.isNotEmpty(configByName)) {
            return JSON.parseArray(JSON.toJSONString(configByName), String.class);
        }

        return Lists.newArrayList();
    }

    private void forwardUrl(String url, HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException {
        // 3、请求类型
        String method = req.getMethod();
        HttpMethod httpMethod = HttpMethod.resolve(method);//method
        // 4、请求头
        MultiValueMap<String, String> headers = parseRequestHeader(req);//header
        // 5、请求体
        byte[] body = parseRequestBody(req);//body

        //  6、封装发singhttp请求
        RequestEntity requestEntity = new RequestEntity(body, headers, httpMethod, URI.create(url));
        RestTemplate restTemplate = new RestTemplate();
        //编码格式转换
        restTemplate.getMessageConverters().set(1,new StringHttpMessageConverter(StandardCharsets.UTF_8));
        ResponseEntity<String> result = restTemplate.exchange(requestEntity, String.class);


        String resultBody = result.getBody();
        HttpHeaders resultHeaders = result.getHeaders();
        MediaType contentType = resultHeaders.getContentType();
        if (contentType != null) {
            resp.setContentType(contentType.toString());
        }
        resp.setCharacterEncoding("UTF-8");// 在getWriterz之前执行,否则不生效
        PrintWriter writer = resp.getWriter();
        writer.write(resultBody);
        writer.flush();
    }

    private String manageUrl(HttpServletRequest req) {
        String requestUrl = req.getRequestURI();
        String queryString = req.getQueryString();//地址栏参数
        if (queryString != null) {
            // 地址有参数,拼接
            requestUrl = requestUrl + "?" +queryString;
        }
        // 2、拼接转发的IP和端口
        MonitorConfigDto monitorConfigDto = getMonitorIp();

        String[] split = requestUrl.split("/app-operation");

        String url = "";

        try {
            if (DataUtil.isNotEmpty(split)) {
                url = split[1];
            } 
        }catch (IndexOutOfBoundsException e) {
            url = "";
        }
        return "http://" + monitorConfigDto.getIp() + ":"+ monitorConfigDto.getPort() + url;
    }

    private MonitorConfigDto getMonitorIp() {

        Object monitorConfig = sysConfigService.getConfigByName("monitorConfig");

        if (DataUtil.isNotEmpty(monitorConfig)) {
            return JSON.parseObject(JSON.toJSONString(monitorConfig), MonitorConfigDto.class);
        }

        return new MonitorConfigDto();
    }


    /**
     * request body
     * @param request
     * @return
     * @throws IOException
     */
    private byte[] parseRequestBody(HttpServletRequest request) throws IOException {
        InputStream inputStream = request.getInputStream();
        return StreamUtils.copyToByteArray(inputStream);
    }

    /**
     * request header
     * @param request
     * @return
     */
    private MultiValueMap<String, String> parseRequestHeader(HttpServletRequest request) {
        HttpHeaders httpHeaders = new HttpHeaders();
        List<String> headerNames = Collections.list(request.getHeaderNames());
        for(String headerName : headerNames) {
            List<String> headerValues = Collections.list(request.getHeaders(headerName));
            for (String headerValue : headerValues) {
                httpHeaders.add(headerName, headerValue);
            }
        }
        return httpHeaders;
    }

}
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值