跨域問題以及如何手寫一個代理服務實現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 [email protected]
 * @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());
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章