<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      Apache HttpClient5 之順豐快遞

      Apache HttpClient5 之順豐快遞

      概要

      • 由于順豐Java Sdk使用Apache HttpClient版本較低,且不支持maven引用——需要手工導入maven,
        以下使用Java 17、Apache HttpClient5進行重構、加密算法保留與順豐Sdk一致。

      • Java 17:代碼運行環境是Java 17

      • maven:Apache HttpClient5 具體版本如下

      <dependency>
          <groupId>org.apache.httpcomponents.client5</groupId>
          <artifactId>httpclient5</artifactId>
          <version>5.3.1</version>
      </dependency>
      <dependency>
          <groupId>org.apache.httpcomponents.core5</groupId>
          <artifactId>httpcore5</artifactId>
          <version>5.3.5</version>
      </dependency>
      <dependency>
          <groupId>com.alibaba.fastjson2</groupId>
          <artifactId>fastjson2</artifactId>
          <version>2.0.25</version>
      </dependency>
      

      代碼

      • 順豐下單接口(預下單、下單、注冊路由)
      import com.alibaba.fastjson2.JSON;
      import com.yyds.common.controller.BaseController;
      import com.yyds.common.vo.AjaxResult;
      import com.yyds.config.SfConfig;
      import com.yyds.module.sf.dto.ScheduleACourierDto;
      import com.yyds.module.sf.dto.SfPreOrderDto;
      import com.yyds.module.sf.service.SfService;
      import com.yyds.module.sf.vo.SfExpCreateOrderVo;
      import com.yyds.module.sf.vo.BusinessResultVo;
      import com.yyds.utils.HttpClientService;
      import lombok.RequiredArgsConstructor;
      import lombok.extern.slf4j.Slf4j;
      import org.springframework.web.bind.annotation.PostMapping;
      import org.springframework.web.bind.annotation.RequestBody;
      import org.springframework.web.bind.annotation.RequestMapping;
      import org.springframework.web.bind.annotation.RestController;
      
      import java.util.Map;
      
      @Slf4j
      @RestController
      @RequestMapping("/sf")
      @RequiredArgsConstructor
      public class SfController extends BaseController {
      
          // 預下單Code
          private static final String EXP_RECE_PRE_ORDER = "EXP_RECE_PRE_ORDER";
          // 下單Code
          private static final String EXP_RECE_CREATE_ORDER = "EXP_RECE_CREATE_ORDER";
          // 注冊路由Code
          private static final String EXP_RECE_REGISTER_ROUTE = "EXP_RECE_REGISTER_ROUTE";
      
          private final SfConfig sfConfig;
      
          private final SfService sfService;
      
          private final HttpClientService httpClientService;
      
          /**
           * 順豐生成訂單接口
           *
           * @param dto 下單參數
           * @return
           */
          @PostMapping("expCreateOrder")
          public AjaxResult expCreateOrder(@RequestBody ScheduleACourierDto dto) {
              try {
                  // 預下單-校驗是否可以下單
                  SfPreOrderDto preDto = sfService.buildSfPreOrderParam(dto);
                  String preMsgData = JSON.toJSONString(preDto);
                  Map<String, String> preParams = sfService.buildCommonReqParams(EXP_RECE_PRE_ORDER, preMsgData);
                  String preRespResult = httpClientService.post(sfConfig.getCallUrlProd(), preParams);
                  BusinessResultVo preApiResult = sfService.getCommonRespResult(preRespResult);
                  if (!preApiResult.getStatus()) {
                      return error(preApiResult.getMsg());
                  }
      
                  // 下單
                  String createMsgData = sfService.buildSfCreateOrderParam(preDto, dto.getSendStartTm());
                  Map<String, String> createParams = sfService.buildCommonReqParams(EXP_RECE_CREATE_ORDER, createMsgData);
                  String createRespResult = httpClientService.post(sfConfig.getCallUrlProd(), createParams);
                  BusinessResultVo orderVo = sfService.getCreatRespResult(createRespResult);
                  if (!orderVo.getStatus()) {
                      return error(orderVo.getMsg());
                  }
      
                  // 注冊路由
                  String routeMsgData = sfService.buildSfRegRouteParam(orderVo.getWaybillNo());
                  Map<String, String> routeParams = sfService.buildCommonReqParams(EXP_RECE_REGISTER_ROUTE, routeMsgData);
                  String routeRespResult = httpClientService.post(sfConfig.getCallUrlProd(), routeParams);
                  BusinessResultVo routeApiResult = sfService.getCommonRespResult(routeRespResult);
                  if (routeApiResult.getStatus()) {
                      return success(SfExpCreateOrderVo.builder().sfWaybillNo(orderVo.getWaybillNo()).build());
                  }
                  return error();
              } catch (Exception e) {
                  log.error("順豐-expCreateOrder: {}", e.getMessage(),e);
                  throw new RuntimeException(e);
              }
          }
      }
      
      • 順豐下單服務層(參數構造、結果處理、業務處理)具體參數可看順豐官方文檔
      import com.alibaba.fastjson2.JSON;
      import com.alibaba.fastjson2.JSONArray;
      import com.alibaba.fastjson2.JSONObject;
      import com.yyds.config.SfConfig;
      import com.yyds.module.sf.dto.*;
      import com.yyds.module.sf.util.VerifyCodeUtil;
      import com.yyds.module.sf.vo.BusinessResultVo;
      import lombok.RequiredArgsConstructor;
      import lombok.extern.slf4j.Slf4j;
      import org.springframework.beans.BeanUtils;
      import org.springframework.stereotype.Service;
      
      import java.time.LocalDateTime;
      import java.time.format.DateTimeFormatter;
      import java.util.*;
      
      @Slf4j
      @Service
      @RequiredArgsConstructor
      public class SfService {
      
          private final SfConfig sfConfig;
      
          /**
           * 構造請求順豐的公共參數
           *
           * @param serviceCode 業務類型
           * @param msgDataJson 具體參數(json格式)
           * @return 公共參數
           *
           */
          public Map<String, String> buildCommonReqParams(String serviceCode, String msgDataJson) {
      
              log.info("順豐-服務Code:{}-請求參數:{}", serviceCode, msgDataJson);
              Map<String, String> params = new HashMap<>();
      
              String timeStamp = String.valueOf(System.currentTimeMillis());
              params.put("partnerID", sfConfig.getClientCode());  // 顧客編碼 ,對應豐橋上獲取的clientCode
              params.put("requestID", UUID.randomUUID().toString().replace("-", ""));
              params.put("serviceCode",serviceCode);// 接口服務碼
              params.put("timestamp", timeStamp);
              params.put("msgData", msgDataJson);
              String md5key  = msgDataJson + timeStamp + sfConfig.getCheckWord();
              params.put("msgDigest", VerifyCodeUtil.md5EncryptAndBase64(md5key));
              return params;
          }
      
          /**
           * 處理公共響應結果
           *
           * @param result 響應結果(json)
           * @return
           */
          public BusinessResultVo getCommonRespResult(String result) {
      
              JSONObject jsonObject = JSON.parseObject(result);
              log.info("順豐響應結果:{}", jsonObject);
              if (jsonObject.get("apiResultCode") != null && !"A1000".equals(jsonObject.getString("apiResultCode"))) {
                  return BusinessResultVo.builder().status(false).msg("請求順豐失敗!").build();
              }
              JSONObject apiResultData = jsonObject.getJSONObject("apiResultData");
              String errCode = apiResultData.get("errorCode") != null ? apiResultData.getString("errorCode") : "";
              if (apiResultData.getBoolean("success")) {
                  if ("S0000".equals(errCode)) {
                      return BusinessResultVo.builder().status(true).build();
                  }
              } else {
                  if ("S0000".equals(errCode)) {
                      return BusinessResultVo.builder().status(false).msg(apiResultData.getString("errorMsg")).build();
                  }
              }
              return BusinessResultVo.builder().status(false).build();
          }
      
          /**
           * 處理下單的響應結果
           *
           * @param result 響應結果
           * @return 順豐單號
           */
          public BusinessResultVo getCreatRespResult(String result) {
      
              BusinessResultVo resultVo = this.getCommonRespResult(result);
              if (!resultVo.getStatus()) {
                  return resultVo;
              }
              BusinessResultVo paramResultVo = BusinessResultVo.builder().status(false).msg("請求順豐結果異常!").build();
              JSONObject jsonObject = JSON.parseObject(result);
              JSONObject apiResultData = jsonObject.getJSONObject("apiResultData");
              JSONObject msgData = apiResultData.getJSONObject("msgData");
              if (msgData == null) {
                  return paramResultVo;
              }
              JSONArray waybillNoList = msgData.getJSONArray("waybillNoInfoList");
              if (waybillNoList == null || waybillNoList.isEmpty()) {
                  return paramResultVo;
              }
              // 獲取單號列表,waybillType = 1 ,為母單,暫時不需要子單
              Optional<JSONObject> waybillNoOptional = waybillNoList.stream().filter(i -> i instanceof JSONObject)
                      .map(i -> (JSONObject) i)
                      .filter(item -> "1".equals(item.getString("waybillType")))
                      .findFirst();
      
              if (waybillNoOptional.isEmpty()) {
                  return paramResultVo;
              }
              // 獲取母單的單號
              String waybillNo = waybillNoOptional.get().getString("waybillNo");
              if (waybillNo.isEmpty()) {
                  return paramResultVo;
              }
              // 保存順豐相關信息
              // 業務數據相關邏輯省略
              
              return BusinessResultVo.builder().status(true).waybillNo(waybillNo).build();
          }
      
          /**
           * 創建下單的請求參數
           *
           * @param preDto
           * @return
           */
          public String buildSfCreateOrderParam(SfPreOrderDto preDto, String sendStartTm) {
      
              SfCreateOrderDto orderDto = new SfCreateOrderDto();
              BeanUtils.copyProperties(preDto, orderDto);
              orderDto.setLanguage("zh-CN");
              orderDto.setIsReturnRoutelabel("1");
              orderDto.setIsDocall("1");
              orderDto.setSendStartTm(sendStartTm);
      
              CargoDetails cargoDetails = new CargoDetails();
              cargoDetails.setSourceArea("CHN");
              cargoDetails.setName("化妝品");
              cargoDetails.setCurrency("CNY");
      
              orderDto.setCargoDetails(List.of(cargoDetails));
              return JSON.toJSONString(orderDto);
          }
      
          /**
           * 預下單 -校驗是否可以下單
           * @param courierDto 下單參數
           * @return
           */
          public SfPreOrderDto buildSfPreOrderParam(ScheduleACourierDto courierDto) {
      
              SfPreOrderDto dto = new SfPreOrderDto();
              dto.setOrderId(this.getOrderId());
              // 綁定順豐月卡
              dto.setMonthlyCard(sfConfig.getMonthlyCard());
              // 1:順豐特快、2:順豐標快、6:順豐即日
              dto.setExpressTypeId("2");
      
              String[] region = courierDto.getRegion().split("/");
              // 拼接區:如果詳細地址包含則不拼接
              if(!courierDto.getAddress().contains(region[2])){
                  courierDto.setAddress(region[2]+courierDto.getAddress());
              }
              // 拼接市:如果詳細地址包含則不拼接
              if(!courierDto.getAddress().contains(region[1])){
                  courierDto.setAddress(region[1]+courierDto.getAddress());
              }
              // 拼接省:如果詳細地址包含則不拼接
              if(!courierDto.getAddress().contains(region[0])){
                  courierDto.setAddress(region[0]+courierDto.getAddress());
              }
      
              // 寄件人相關
              ContactInfo contactSend = new ContactInfo();
              contactSend.setContactType(1);
              contactSend.setTel(courierDto.getTel());
              contactSend.setMobile(courierDto.getTel());
              contactSend.setProvince(region[0]);
              contactSend.setCity(region[1]);
              contactSend.setCounty(region[2]);
              contactSend.setAddress(courierDto.getAddress());
              contactSend.setContact(courierDto.getCustomerName());
      
              // 收件人相關
              ContactInfo contactReceiveItems = new ContactInfo();
              contactReceiveItems.setContactType(2);
              contactReceiveItems.setTel(sfConfig.getTel());
              contactReceiveItems.setMobile(sfConfig.getTel());
              contactReceiveItems.setProvince(sfConfig.getProvince());
              contactReceiveItems.setCity(sfConfig.getCity());
              contactReceiveItems.setCounty(sfConfig.getCounty());
              contactReceiveItems.setAddress(sfConfig.getAddress());
              contactReceiveItems.setContact(sfConfig.getContact());
              contactReceiveItems.setCompany("YYDS有限公司");
      
              List<ContactInfo> contactInfoList = List.of(contactSend,contactReceiveItems);
              dto.setContactInfoList(contactInfoList);
              return dto;
          }
      
          /**
           * 路由注冊
           *
           * @param waybillNo 順豐單號
           * @return
           */
          public String buildSfRegRouteParam(String waybillNo) {
              SfRegisterRouteDto dto = new SfRegisterRouteDto();
              dto.setType("2");
              dto.setAttributeNo(waybillNo);
              dto.setLanguage("zh-CN");
              dto.setCountry("CN");
              return JSON.toJSONString(dto);
          }
      
          /**
           * 自定義-生成單號
           *
           * @return
           */
          public String getOrderId() {
              String formattedDateTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmssSSS"));
              // 前綴-日期
              return "YYDS-" + formattedDateTime;
          }
      
      }
      
      • VerifyCodeUtil 加密工具類(順豐數據通訊使用)
      import lombok.AllArgsConstructor;
      import org.apache.commons.codec.binary.Base64;
      
      import java.nio.charset.StandardCharsets;
      import java.security.MessageDigest;
      
      @AllArgsConstructor
      public class VerifyCodeUtil {
          
          public static String md5EncryptAndBase64(String str) {
              return encodeBase64(md5Encrypt(str));
          }
      
          private static byte[] md5Encrypt(String encryptStr) {
              try {
                  MessageDigest md5 = MessageDigest.getInstance("MD5");
                  md5.update(encryptStr.getBytes(StandardCharsets.UTF_8));
                  return md5.digest();
              } catch (Exception e) {
                  throw new RuntimeException(e);
              }
          }
      
          private static String encodeBase64(byte[] b) {
              return (new Base64()).encodeAsString(b);
          }
      }
      
      • HttpClientConfig :Http-配置連接池、請求級別、連接資源等
      import org.apache.hc.client5.http.config.ConnectionConfig;
      import org.apache.hc.client5.http.config.RequestConfig;
      import org.apache.hc.client5.http.impl.DefaultHttpRequestRetryStrategy;
      import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
      import org.apache.hc.client5.http.impl.classic.HttpClients;
      import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager;
      import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManagerBuilder;
      import org.apache.hc.client5.http.impl.routing.SystemDefaultRoutePlanner;
      import org.apache.hc.client5.http.io.HttpClientConnectionManager;
      import org.apache.hc.client5.http.ssl.DefaultHostnameVerifier;
      import org.apache.hc.client5.http.ssl.SSLConnectionSocketFactory;
      import org.apache.hc.core5.ssl.SSLContexts;
      import org.apache.hc.core5.util.TimeValue;
      import org.apache.hc.core5.util.Timeout;
      import org.springframework.context.annotation.Bean;
      import org.springframework.context.annotation.Configuration;
      
      import java.net.ProxySelector;
      import java.time.Duration;
      
      @Configuration
      public class HttpClientConfig {
      
          // 連接池最大連接數 - 控制整個連接池允許的最大并發連接數
          private final static int MAX_TOTAL = 100;
      
          // 每個路由(目標主機)的默認最大連接數 - 限制到單個主機的并發連接數
          private final static int DEFAULT_MAX_PER_ROUTE  = 50;
      
          // 連接建立超時時間(毫秒)- 建立TCP連接的最大等待時間
          private final static Duration CONNECT_TIMEOUT = Duration.ofMillis(5000);
      
          // 從連接池獲取連接的超時時間(秒)- 等待連接池分配連接的最大時間
          private final static Duration CONNECTION_REQUEST_TIMEOUT = Duration.ofSeconds(2);
      
          // 響應超時時間(秒)- 等待服務器響應的最大時間
          private final static Duration RESPONSE_TIMEOUT = Duration.ofSeconds(30);
      
          // Socket超時時間(毫秒)- 兩次數據包之間的最大間隔時間
          private final static Duration SOCKET_TIMEOUT = Duration.ofMillis(10000);
      
          // 空閑連接最大存活時間(毫秒)- 超過此時間的空閑連接將被驅逐
          private final static Duration IDLE_EVICT_TIME = Duration.ofMillis(120000);
      
          /**
           * 配置HTTP連接池管理器 (核心Bean)
           * 使用@Bean使其由Spring容器管理單例生命周期
           * Spring容器關閉時自動調用close()釋放連接
           */
          @Bean(destroyMethod = "close")
          public HttpClientConnectionManager httpClientConnectionManager() throws Exception {
              // 創建SSL socket工廠
              SSLConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(
                      SSLContexts.custom().build(),
                      new String[]{"TLSv1.2", "TLSv1.3"}, // 支持的TLS協議版本
                      null, // 支持的密碼套件(null表示使用默認值)
                      new DefaultHostnameVerifier()); // 主機名驗證器
      
              // 配置默認連接配置
              ConnectionConfig connectionConfig = ConnectionConfig.custom()
                      .setConnectTimeout(Timeout.of(CONNECT_TIMEOUT)) // 連接建立超時
                      .setSocketTimeout(Timeout.of(SOCKET_TIMEOUT)) // Socket讀寫超時
                      .build();
      
              // 創建連接池管理器(HTTP 連接會自動使用默認的普通 Socket 工廠(PlainConnectionSocketFactory),無需顯式設置)
              PoolingHttpClientConnectionManager connectionManager = PoolingHttpClientConnectionManagerBuilder.create()
                      .setSSLSocketFactory(sslSocketFactory) // 設置SSL socket工廠
                      .setDefaultConnectionConfig(connectionConfig) // 設置默認連接配置
                      .build();
      
              // 設置連接池參數
              connectionManager.setMaxTotal(MAX_TOTAL); // 設置整個連接池的最大連接數
              connectionManager.setDefaultMaxPerRoute(DEFAULT_MAX_PER_ROUTE); // 設置每個路由的默認最大連接數
              return connectionManager;
          }
      
          /**
           * 配置請求級別的參數
           * 主要設置從連接池獲取連接的超時時間和響應超時時間
           */
          @Bean
          public RequestConfig requestConfig() {
              return RequestConfig.custom()
                      .setConnectionRequestTimeout(Timeout.of(CONNECTION_REQUEST_TIMEOUT)) 
                      // 從連接池獲取連接的超時時間
                      .setResponseTimeout(Timeout.of(RESPONSE_TIMEOUT)) 
                      // 等待服務器響應的超時時間
                      .build();
          }
      
          /**
           * 創建并配置HttpClient實例
           * 使用@Bean注解使其成為Spring管理的Bean
           * destroyMethod = "close"確保Spring容器關閉時自動關閉HttpClient釋放資源
           */
          @Bean(destroyMethod = "close")
          public CloseableHttpClient httpClient(HttpClientConnectionManager manager, RequestConfig reqConfig) {
      
              return HttpClients.custom()
                      .setConnectionManager(manager) 
                  	// 設置連接池
                      .setDefaultRequestConfig(reqConfig)  
                      // 設置請求配置
                      .setRoutePlanner(new SystemDefaultRoutePlanner(ProxySelector.getDefault())) 
                      // 使用系統默認代理
                      .setRetryStrategy(new DefaultHttpRequestRetryStrategy(3, TimeValue.ofSeconds(1))) 
                      // 使用內置的重試策略
                      .evictExpiredConnections() 
                      // 驅逐過期連接
                      .evictIdleConnections(TimeValue.of(IDLE_EVICT_TIME)) 
                      // 驅逐空閑連接
                      .build();
          }
      }
      
      • HttpClientUtil http工具類
      import lombok.RequiredArgsConstructor;
      import lombok.extern.slf4j.Slf4j;
      import org.apache.hc.client5.http.classic.HttpClient;
      import org.apache.hc.client5.http.classic.methods.HttpDelete;
      import org.apache.hc.client5.http.classic.methods.HttpGet;
      import org.apache.hc.client5.http.classic.methods.HttpPost;
      import org.apache.hc.client5.http.classic.methods.HttpUriRequest;
      import org.apache.hc.client5.http.config.RequestConfig;
      import org.apache.hc.client5.http.entity.UrlEncodedFormEntity;
      import org.apache.hc.core5.http.ContentType;
      import org.apache.hc.core5.http.HttpEntity;
      import org.apache.hc.core5.http.NameValuePair;
      import org.apache.hc.core5.http.io.HttpClientResponseHandler;
      import org.apache.hc.core5.http.io.entity.EntityUtils;
      import org.apache.hc.core5.http.io.entity.StringEntity;
      import org.apache.hc.core5.http.message.BasicNameValuePair;
      import org.springframework.stereotype.Service;
      
      import java.io.IOException;
      import java.nio.charset.StandardCharsets;
      import java.time.Instant;
      import java.time.ZoneId;
      import java.time.format.DateTimeFormatter;
      import java.util.List;
      import java.util.Map;
      import java.util.stream.Collectors;
      
      @Slf4j
      @Service
      @RequiredArgsConstructor
      public class HttpClientUtil {
      
          private final RequestConfig requestConfig;
      
          private final HttpClient httpClient;
      
          private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyyMMddHHmmssSSS").withZone(ZoneId.systemDefault());
      
          public String post(String url, StringEntity entity) {
      
              HttpPost httpPost = new HttpPost(url);
              httpPost.setEntity(entity);
              return invoke(httpClient, httpPost);
          }
      
          public String post(String url, List<NameValuePair> parameters) {
              HttpPost httpPost = new HttpPost(url);
              httpPost.setEntity(new UrlEncodedFormEntity(parameters, StandardCharsets.UTF_8));
              return invoke(httpClient, httpPost);
          }
      
          public String postSFAPI(String url, String xml, String verifyCode) {
      
              List<NameValuePair> parameters = List.of(
                      new BasicNameValuePair("xml", xml),
                      new BasicNameValuePair("verifyCode", verifyCode));
              HttpPost httpPost = new HttpPost(url);
              httpPost.setEntity(new UrlEncodedFormEntity(parameters, StandardCharsets.UTF_8));
              return invoke(httpClient, httpPost);
          }
      
          public String get(String url) {
              HttpGet get = new HttpGet(url);
              return invoke(httpClient, get);
          }
      
          public String delete(String url) {
              HttpDelete delete = new HttpDelete(url);
              return invoke(httpClient, delete);
          }
      
          public String post(String url, Map<String, String> params) {
      
              HttpPost httpPost = new HttpPost(url);
              httpPost.setConfig(requestConfig);
              httpPost.addHeader("appCode", params.get("partnerID"));
              httpPost.addHeader("timestamp", FORMATTER.format(Instant.now()));
              httpPost.addHeader("Content-Type", ContentType.APPLICATION_FORM_URLENCODED.withCharset(StandardCharsets.UTF_8).toString());
      
              List<NameValuePair> paramsList = params.entrySet().stream()
                      .map(i->new BasicNameValuePair(i.getKey(),i.getValue()))
                      .collect(Collectors.toList());
              httpPost.setEntity(new UrlEncodedFormEntity(paramsList, StandardCharsets.UTF_8));
              return invoke(httpClient, httpPost);
          }
      
          public static String invoke(HttpClient httpclient, HttpUriRequest httpRequest) {
              try {
                  // 創建一個響應處理器
                  HttpClientResponseHandler<String> responseHandler = resp -> {
                      int statusCode = resp.getCode();
                      HttpEntity entity = resp.getEntity();
                      String body = entity != null ? EntityUtils.toString(entity) : "";
                      if (statusCode >= 200 && statusCode < 300) {
                          return body;
                      }else if (statusCode >= 400 && statusCode < 500) {
                          // 客戶端錯誤
                          log.warn("客戶端錯誤 {}: {}", statusCode, body);
                          throw new RuntimeException("客戶端錯誤: " + statusCode);
                      } else if (statusCode >= 500) {
                          // 服務器錯誤
                          log.error("服務器錯誤 {}: {}", statusCode, body);
                          throw new RuntimeException("服務器錯誤: " + statusCode);
                      } else {
                          // 其他狀態碼
                          log.info("非標準狀態碼 {}: {}", statusCode, body);
                          return body;
                      }
                  };
                  return httpclient.execute(httpRequest, responseHandler);
              } catch (IOException | RuntimeException e) {
                  log.error("HttpClient請求執行失敗: {} {}", httpRequest.getMethod(), httpRequest.getRequestUri(), e);
                  throw new RuntimeException("HTTP請求執行失敗", e);
              }
          }
      }
      
      posted @ 2025-10-10 10:46  Soul-Q  閱讀(16)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 国产黄色精品一区二区三区| 18禁在线一区二区三区| 锡林浩特市| 中文激情一区二区三区四区| 精品无码成人片一区二区| 亚洲一区二区三区色视频| 一区二区中文字幕久久| 深夜视频国产在线观看| 男女性高爱潮免费网站| 久热这里只精品99国产6-99RE视…| 精品久久综合日本久久网| 欧美牲交a欧美牲交aⅴ免费真| 一区二区三区无码免费看| 欧洲人妻丰满av无码久久不卡| 亚洲精品一区二区三区片| 女人张开腿让男人桶爽 | 国产亚洲精品第一综合麻豆| 国产一区二区三中文字幕| 亚洲熟女精品一区二区| 高清无码爆乳潮喷在线观看| 亚洲无人区一码二码三码| 精品国产高清中文字幕| 国产精品伦人视频免费看| 国产亚洲精品久久久久婷婷瑜伽| 国产精品色哟哟成人av| 不卡一区二区国产在线| 成人网站网址导航| 久久精品波多野结衣| 起碰免费公开97在线视频| 少妇激情一区二区三区视频| 色综合久久综合欧美综合网| 91精品国产自产在线蜜臀| 依依成人精品视频在线观看| 久久久久成人片免费观看蜜芽| 亚洲国产成人午夜在线一区| 99RE6在线观看国产精品| 久热这里有精品免费视频| 克什克腾旗| 人成午夜免费大片| 亚洲欧洲日产国码久在线| 四虎亚洲国产成人久久精品|