跨域问题以及如何手写一个代理服务实现postman功能

写一个代理工具服务,所有的请求经过此服务转发到不同的服务,可以统一处理跨域问题,只要允许这个服务的请求即可。

中转工具: https://blog.csdn.net/xxssyyyyssxx/article/details/72954499

1. 用户浏览器自己放开跨域限制: https://www.jianshu.com/p/2db73311fcbe

2. nginx部分一些对域名的操作: https://segmentfault.com/a/1190000003710973?_ea=663456

3. 使用插件,需要改写插件或者中转服务开发,目前选择中转服务,以下是一个市场上的插件:

ApiDebug工具:https://gitee.com/CrapApi/ApiDebug

4. 跨域的说明,如jsonp只支持get方式 https://blog.csdn.net/wonking666/article/details/79159180

cors方式: http://www.ruanyifeng.com/blog/2016/04/cors.html

浏览器和服务器实现跨域(CORS)判定的原理https://segmentfault.com/a/1190000003710973?_ea=663456

Controller类名上方添加@CrossOrigin 注解通过此方式注解则Controller中的所有通过@RequestMapping注解的方法都可以进行跨域请求。 代码如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

@CrossOrigin()

  @RequestMapping("/demoController")

  @Controller

  public class DemoController {

  @Autowired

  IDemoService demoService;

 

  @RequestMapping(value = "/test", method = RequestMethod.POST)

  @ResponseBody

  public ResultModel test(HttpServletRequest request)

      throws Exception {

    return “right”;

  }

}

Filter,我们在写springMVC的时候,更喜欢的方式是通过@ResponseBody给返回对象进行封装直接返回给前端,这样简单而且容易。 如果使用@ResponseBody就不能使用第一种方法了,所有就使用filter给所有的请求都封装一下

<filter>
    <filter-name>corsBean</filter-name>
    <filter-class>com.ximalaya.mobile.user.filter.HeadersCORSFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>corsBean</filter-name>
    <url-pattern>*</url-pattern>
</filter-mapping>

/**
 * 解决H5页面的跨域问题
 * @author chong.wang@ximalaya.com
 * @date 2020/4/29 下午3:34
 */
public class HeadersCORSFilter implements Filter {


    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        // TODO Auto-generated method stub

    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse servletResponse,
                         FilterChain chain) throws IOException, ServletException {
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers", "x-requested-with,Authorization");
        response.setHeader("Access-Control-Allow-Credentials", "true");
        chain.doFilter(request, servletResponse);

    }

    @Override
    public void destroy() {
        // TODO Auto-generated method stub

    }
}

 

 

 

 

中转:

    private static Map<String, Object> requestExcute(ApiRequestBody apiRequestBody, String restUrl, Map<String, Object> params, HttpClient httpClient) {
        HttpGet httpGet = null;
        HttpPost httpPost = null;
        HttpPut httpPut = null;
        HttpDelete httpDelete = null;
        Map<String, Object> result = new HashMap<>();
        HttpEntity entity = null;
        HttpResponse response = null;
        Long timeCost = 0L;
        try {
            LocalDateTime beginTime = LocalDateTime.now();

            if (Constant.RequestMode_POST.equalsIgnoreCase(apiRequestBody.getRequestMode())) {
                httpPost = new HttpPost(restUrl);
                handleRquestHeader(apiRequestBody, httpPost);
                response = getPostHttpResponse(apiRequestBody, restUrl, params, httpClient, httpPost);

            } else if (Constant.RequestMode_GET.equalsIgnoreCase(apiRequestBody.getRequestMode())) {
                //get方式参数方式传过来的,进行处理
                restUrl = getRequestGetModeUrl(restUrl, params);
                httpGet = new HttpGet(restUrl);
                handleRquestHeader(apiRequestBody, httpGet);
                log.info("RequestMode_GET  full restUrl:" + restUrl);
                response = httpClient.execute(httpGet);
            } else if (Constant.RequestMode_PUT.equalsIgnoreCase(apiRequestBody.getRequestMode())) {
                //get方式参数方式传过来的,进行处理
                restUrl = getRequestGetModeUrl(restUrl, params);
                httpPut = new HttpPut(restUrl);
                handleRquestHeader(apiRequestBody, httpPut);
                log.info("RequestMode_PUT full restUrl:" + restUrl);
                response = httpClient.execute(httpGet);
            } else if (Constant.RequestMode_DELETE.equalsIgnoreCase(apiRequestBody.getRequestMode())) {
                //get方式参数方式传过来的,进行处理
                restUrl = getRequestGetModeUrl(restUrl, params);
                httpDelete = new HttpDelete(restUrl);
                handleRquestHeader(apiRequestBody, httpDelete);
                log.info("RequestMode_DELETE  full restUrl:" + restUrl);
                response = httpClient.execute(httpGet);
            }

            timeCost = Duration.between(beginTime, LocalDateTime.now()).toMillis();

            if (response == null) {
                handleResponseError(apiRequestBody, result, entity, timeCost, 404);
            }
            int status = response.getStatusLine().getStatusCode();

            log.info("请求restUrl:" + restUrl + "网络状态:status=" + status);

            entity = response.getEntity();

            if (HttpStatus.SC_OK == status) {
                handleResponseOk(apiRequestBody, result, entity, response, timeCost);
            } else {
                handleResponseError(apiRequestBody, result, entity, timeCost, status);
            }

            return result;

        } catch (Exception e) {
            return getProxyResponseError(apiRequestBody, restUrl, params, result, timeCost, e);
        } finally {
            handleCloseIO(httpClient, httpGet, httpPost, httpPut, httpDelete, entity);
        }
    }

    private static HttpResponse getPostHttpResponse(ApiRequestBody apiRequestBody, String restUrl, Map<String, Object> params, HttpClient httpClient, HttpPost httpPost) throws IOException {
        HttpResponse response;
        log.info("POST  restUrl:" + restUrl);
        // 设置参数,form格式
        if (StringUtils.isEmpty(apiRequestBody.getRequestDataJson())) {
            setRequestDataParams(apiRequestBody, params, httpPost);
        } else {
            //处理请求json数据
//                    requestJsonData = requestJsonData.trim().replace("\\\\n","").replace("\\\\\\","y|y").replace("\\\\","").replace("y|y","\\");
            log.info("POST  requestJsonData:" + apiRequestBody.getRequestDataJson());
            handleRequestJsonData(apiRequestBody, httpPost);
        }

        response = httpClient.execute(httpPost);
        return response;
    }

    private static Map<String, Object> getProxyResponseError(ApiRequestBody apiRequestBody, String restUrl, Map<String, Object> params, Map<String, Object> result, Long timeCost, Exception e) {
        e.printStackTrace();
        result.put("ResultCode", 500);
        result.put("timeCost", timeCost);
        result.put("ResultMsg", "请求对应服务,返回异常,请检查请求url以及入参信息,restUrl:" + restUrl + ",requestJsonData:" + apiRequestBody.getRequestDataJson() + ",params:" + JsonUtils.toJson(params));
        return result;
    }

    private static void handleCloseIO(HttpClient httpClient, HttpGet httpGet, HttpPost httpPost, HttpPut httpPut, HttpDelete httpDelete, HttpEntity entity) {
        if (null != entity) {
            try {
                EntityUtils.consume(entity);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        if (null != httpGet && httpGet.isAborted()) {
            httpGet.abort();
        }
        if (null != httpPost && httpPost.isAborted()) {
            httpPost.abort();
        }
        if (null != httpPut && httpPut.isAborted()) {
            httpPut.abort();
        }
        if (null != httpDelete && httpDelete.isAborted()) {
            httpDelete.abort();
        }

        if (null != httpClient) {
            httpClient.getConnectionManager().shutdown();
        }
    }

    private static void handleResponseError(ApiRequestBody apiRequestBody, Map<String, Object> result, HttpEntity entity, Long timeCost, int status) throws IOException {
        String error = new String(EntityUtils.toString(entity).getBytes(apiRequestBody.getOutputCharset()), Constant.ClientOutputCharset);
        String ret = "网络错误:错误代码" + status + Constant.COMMA + error;
        result.put("ResultCode", status);
        result.put("ResultMsg", "FAIL");
        result.put("timeCost", timeCost);
        result.put("Data", ret);
    }

    private static void handleResponseOk(ApiRequestBody apiRequestBody, Map<String, Object> result, HttpEntity entity, HttpResponse response, Long timeCost) throws IOException {
        String ret = "";
        if (entity != null) {
            ret = new String(EntityUtils.toString(entity).getBytes(apiRequestBody.getOutputCharset()), Constant.ClientOutputCharset);
        }
        Header[] cookieHeader = response.getHeaders("Set-Cookie");
        Header[] allHeader = response.getAllHeaders();

        result.put("ResultCode", HttpStatus.SC_OK);
        result.put("ResultMsg", "SUCCESS");
        result.put("timeCost", timeCost);
        result.put("Data", ret);
        result.put("cookieHeader", cookieHeader);
        result.put("allHeader", allHeader);
    }

    private static String getRequestGetModeUrl(String restUrl, Map<String, Object> params) {
        if (params != null) {
            for (Iterator iter = params.keySet().iterator(); iter.hasNext(); ) {
                String name = (String) iter.next();
                String value = String.valueOf(params.get(name));
                if (StringUtils.isNotEmpty(name) && StringUtils.isNotEmpty(value)) {
                    if (restUrl.contains(Constant.QUESTION)) {
                        restUrl = restUrl + Constant.AND + name + Constant.EQUAL + value;
                    } else {
                        restUrl = restUrl + Constant.QUESTION + name + Constant.EQUAL + value;
                    }
                }
            }
        }
        return restUrl;
    }

    private static Map<String, String> handleRquestHeader(ApiRequestBody apiRequestBody, HttpRequestBase httpBase) {
        Map<String, String> headers = new HashMap<>();
        if (StringUtils.isNotEmpty(apiRequestBody.getHeaders())) {
            headers = getHeaders(apiRequestBody, headers);
            // 设置header
            if (headers != null) {
                for (Map.Entry<String, String> entry : headers.entrySet()) {
                    //Post请求
                    if (StringUtils.isNotEmpty(entry.getKey())) {
                        httpBase.addHeader(entry.getKey(), entry.getValue());
                    }
                }
            }
        }

        return headers;
    }

    private static Map<String, String> getHeaders(ApiRequestBody apiRequestBody, Map<String, String> headers) {
        try {
            JSONArray headArray = JSONArray.parseArray(apiRequestBody.getHeaders());
            headers = jsonArray2Map(headArray);
        } catch (Exception e) {
            log.info("POST  parseArray Headers error:" + e.getMessage());
        }
        return headers;
    }

    private static void handleRequestJsonData(ApiRequestBody apiRequestBody, HttpPost httpPost) throws UnsupportedEncodingException {
        StringEntity reqEntity = new StringEntity(apiRequestBody.getRequestDataJson(), Constant.ContentType, apiRequestBody.getInputCharset());
        reqEntity.setContentType(Constant.ContentType);
        reqEntity.setContentEncoding(apiRequestBody.getInputCharset());
        httpPost.setEntity(reqEntity);
    }

    private static void setRequestDataParams(ApiRequestBody apiRequestBody, Map<String, Object> params, HttpPost httpPost) throws UnsupportedEncodingException {
        List<NameValuePair> nvps = new ArrayList<NameValuePair>();
        for (Iterator iter = params.keySet().iterator(); iter.hasNext(); ) {
            String name = (String) iter.next();
            String value = String.valueOf(params.get(name));
            if (value.contains(Constant.SQUARE_BRACKETS_PRE) && value.contains(Constant.SQUARE_BRACKETS_SUFFIX) && value.contains(Constant.COMMA)) {
                String newValue = value.replace(Constant.SQUARE_BRACKETS_PRE, Constant.EMPTY).replace(Constant.SQUARE_BRACKETS_SUFFIX, Constant.EMPTY);
                String[] newValuelist = newValue.split(Constant.COMMA);
                for (int i = 0; i < newValuelist.length; i++) {
                    nvps.add(new BasicNameValuePair(name, newValuelist[i]));
                }
            } else {
                nvps.add(new BasicNameValuePair(name, value));
            }
        }
        httpPost.setEntity(new UrlEncodedFormEntity(nvps, apiRequestBody.getInputCharset()));
    }

    private static Map<String, Object> requestDataConvertToMap(ApiRequestBody apiRequestBody) {
        Map<String, Object> params = new HashMap<>();
        JSONObject formDataJson = (StringUtils.isNotEmpty(apiRequestBody.getRequestData())) ? JSONObject.parseObject(apiRequestBody.getRequestData()) : null;
        if (formDataJson != null) {
            //通过迭代器获取这段json当中所有的key值
            Iterator keys = formDataJson.keySet().iterator();
            //然后通过一个循环取出所有的key值
            while (keys.hasNext()) {
                String key = String.valueOf(keys.next());
                String interfaceTemp = formDataJson.getString(key);
                if (interfaceTemp == null) {
                    continue;
                }
                params.put(key, interfaceTemp);
            }
        }
        return params;
    }

    private static void setConnectParams(ApiRequestBody apiRequestBody, HttpClient httpClient) {
        httpClient.getParams().setParameter(AllClientPNames.CONNECTION_TIMEOUT, 30000);
        httpClient.getParams().setParameter(AllClientPNames.SO_TIMEOUT, 30000);
        httpClient.getParams().setParameter("http.protocol.content-charset", apiRequestBody.getInputCharset());
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值