成人午夜视频全免费观看高清-秋霞福利视频一区二区三区-国产精品久久久久电影小说-亚洲不卡区三一区三区一区

第三方接口回調(diào)轉(zhuǎn)發(fā)到不同環(huán)境-創(chuàng)新互聯(lián)

背景:完成完整的業(yè)務(wù),需要第三方異步回調(diào)系統(tǒng)的接口。從而更新業(yè)務(wù)狀態(tài)。但是第三方系統(tǒng)經(jīng)常只能配置一個(gè)回調(diào)接口。但是我們系統(tǒng)有4個(gè)環(huán)境。常常只能在一個(gè)環(huán)境測(cè)試,切換環(huán)境測(cè)試需要去第三方修改回調(diào)接口。

網(wǎng)站建設(shè)哪家好,找成都創(chuàng)新互聯(lián)!專注于網(wǎng)頁設(shè)計(jì)、網(wǎng)站建設(shè)、微信開發(fā)、成都微信小程序、集團(tuán)企業(yè)網(wǎng)站建設(shè)等服務(wù)項(xiàng)目。為回饋新老客戶創(chuàng)新互聯(lián)還提供了西夏免費(fèi)建站歡迎大家使用!

目標(biāo):接口回調(diào)回來后,允許接口轉(zhuǎn)發(fā)到其他環(huán)境

實(shí)現(xiàn)思路:由于回調(diào)接口中是沒有參數(shù)能標(biāo)識(shí)發(fā)到哪個(gè)環(huán)境,因此無法在nginx層面解決。就在具體服務(wù)上做:

  1. 接收請(qǐng)求,找到需要轉(zhuǎn)發(fā)到哪些環(huán)境

  1. 封裝請(qǐng)求,將回調(diào)請(qǐng)求轉(zhuǎn)發(fā)過去(header帶上標(biāo)識(shí):x-forward-from)

  1. 如果請(qǐng)求帶有x-forward-from,則不轉(zhuǎn)發(fā)

  1. 同時(shí)本服務(wù)也接收該請(qǐng)求并處理

這些邏輯都是和接口邏輯不相干的,因此考慮切面等方式處理,最后采用filter處理。邏輯在filter中處理

以下是遇到的相關(guān)問題:項(xiàng)目采取SpringMVC

Q:WebApplicationContext獲取HttpClient的bean失敗

call其他環(huán)境用封裝的HttpClient的bean,它是一個(gè)帶線程池的,filter通過在web.xml進(jìn)行配置生效。如下:

NotifyMessageForwardFiltercom.lenovo.ofp.payment.front.webapp.filter.NotifyMessageForwardFilterNotifyMessageForwardFilter/notify/*

這種方式,可以看作是new NotifyMessageForwardFilter()。無法通過@Auwired 注入bean,會(huì)報(bào)錯(cuò)。當(dāng)然這個(gè)報(bào)錯(cuò)具體原因是因?yàn)閒ilter調(diào)用時(shí),bean對(duì)象還沒初始化好:web.xml中各個(gè)標(biāo)簽初始化的順序如下:contetxt-param ->listener ->filter ->servlet

用來加載你配置的文件信息配置你的監(jiān)聽服務(wù)過濾器配置你單獨(dú)的一些操作容器初始化
加載順序?yàn)椋篶ontext-param ->listener ->filter ->servlet    加載的順序不受在web.xml中配置的位置影響

springmvc.xml中定義component-scan;而springmvc.xml在servlet中加載;所以filter中找不到servlet才生成的bean

其次是WebApplicationContext獲取的applicationContext,它id是:org.springframework.web.context.WebApplicationContext:/payment-front-webapp,通過BeanDefinitionNames()這個(gè)方法發(fā)現(xiàn),沒有HttpClient的bean,連Controller的bean都沒有。因此才認(rèn)為,至少還有一個(gè)其他的ApplicationContext

而servlet的applicationContext的id是:org.springframework.web.context.WebApplicationContext:/payment-front-webapp/dispatcher

發(fā)現(xiàn)了吧,ApplicationContext不是一個(gè),所以呀,我們要用下面那個(gè)。

A:解決方法:通過上面的分析,我們也知道ApplicationContext除了WebApplicationUtils獲取的那個(gè)外,還存在至少一個(gè)。所以用ApplicationContextAware來獲取。畢竟這個(gè)接口是在服務(wù)啟動(dòng)完成后執(zhí)行的內(nèi)容。獲取的Context更為完整。

@Component
public class ApplicationContextUtils implements ApplicationContextAware {
    public static ApplicationContext APPLICATION_CONTEXT = null;
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        log.info("init ApplicationContextUtils success");
        ApplicationContextUtils.APPLICATION_CONTEXT = applicationContext;
    }
}

Q1:org.apache.http.ProtocolException: Content-Length header already present

A:content-length是根據(jù)內(nèi)容的長(zhǎng)度動(dòng)態(tài)計(jì)算的。因此在請(qǐng)求轉(zhuǎn)發(fā)的時(shí)候,要?jiǎng)h掉

Q2:requestBody無法被重復(fù)讀取

請(qǐng)求轉(zhuǎn)發(fā)到不同環(huán)境,這意味著我們需要封裝http請(qǐng)求,需要讀取body。而body讀取一次后就會(huì)報(bào)錯(cuò)。

A:body無法被重復(fù)讀取原因是body內(nèi)容放在InputStream中,這個(gè)流是只能讀一次的,根據(jù)HttpServletRequestWrapper包裝一下就行了

public class HttpMultiReadServletRequestWrapper extends HttpServletRequestWrapper {
    BufferedReader bufferedReader = null;
    String requestBody = "";
    public HttpMultiReadServletRequestWrapper(HttpServletRequest request) {
        super(request);
        // 用原始的request獲取一次body,然后緩存起來
        this.requestBody = HttpRequestUtils.getRequestBody(request);
    }

    @Override
    public ServletInputStream getInputStream() throws IOException {
        String characterEncoding = getCharacterEncoding();
        characterEncoding = StringUtils.isBlank(characterEncoding) ? "UTF-8" : characterEncoding;
        return new DelegatingServletInputStream(
                new ByteArrayInputStream(requestBody.getBytes(characterEncoding)));
    }

    @Override
    public BufferedReader getReader() throws IOException {
        if (bufferedReader == null) {
            // 需要搭配StringReader才能反復(fù)讀。用inputStream只能讀一次
            bufferedReader = new BufferedReader(new StringReader(requestBody));
            bufferedReader.mark(requestBody.length() + 1);
        } else {
            // 重置之后,bufferedReader就又可以讀了
            bufferedReader.reset();
        }
        return bufferedReader;
    }

    public String getRequestBody() {
        return this.requestBody;
    }
}

HttpRequestUtils的getRequestBody內(nèi)容如下
public static String getRequestBody(HttpServletRequest request) {
    StringBuilder sb = new StringBuilder();
    try {
        BufferedReader br = request.getReader();
        String line;
        while ((line = br.readLine()) != null) {
            sb.append(line);
        }
    } catch (Exception e) {
        log.error("Read notify request body", e);
    }
    return sb.toString();
}

Q3:@Autowired request是代理類,無法加載為了解決requestBody而生成RequestWrapper

A:其實(shí)就是一個(gè)實(shí)現(xiàn)邏輯出錯(cuò)。我們生成RequestWrapper后,應(yīng)當(dāng)在filterChain里面?zhèn)魅隦equestWrapper而不是原來的request。其次是:RequestContextHolder,這個(gè)是在filter之前就設(shè)置了Request,所以有必要,需要更新里面的Request

你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機(jī)房具備T級(jí)流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級(jí)服務(wù)器適合批量采購,新人活動(dòng)首月15元起,快前往官網(wǎng)查看詳情吧

網(wǎng)頁標(biāo)題:第三方接口回調(diào)轉(zhuǎn)發(fā)到不同環(huán)境-創(chuàng)新互聯(lián)
網(wǎng)頁路徑:http://jinyejixie.com/article12/depsdc.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站排名電子商務(wù)、虛擬主機(jī)域名注冊(cè)、關(guān)鍵詞優(yōu)化外貿(mào)建站

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

成都seo排名網(wǎng)站優(yōu)化
明溪县| 花莲县| 张北县| 柳州市| 区。| 东阳市| 岑巩县| 双牌县| 尼木县| 会东县| 吴江市| 唐山市| 曲松县| 丰城市| 云和县| 修文县| 呼和浩特市| 金川县| 黄平县| 乌拉特后旗| 将乐县| 家居| 临武县| 山西省| 呼和浩特市| 珲春市| 卢氏县| 桂林市| 盘山县| 谢通门县| 兖州市| 中江县| 简阳市| 凭祥市| 道孚县| 乳源| 江安县| 寿宁县| 阿拉善右旗| 静乐县| 石河子市|