request_and_response

本文详细介绍了如何使用HttpServletRequest类接收客户端发送的数据,并通过HttpServletResponse类返回数据给客户端。重点讲解了如何通过input的name属性获取参数值,设置返回消息类型及编码格式的方法,以及避免中文乱码的技巧。

(1)HttpServletRequest 类用于接收读取前台客服端所发过来的消息,HttpServletResponse类用于返回给客服端的消息.
(2)在提交表单数据中request可以通过input的name属性用getParameter(name名字)读取input的valude;response可以通过setContentType()设置返回消息的类型,
setCharacterEncoding可以设置返回消息的编码格式,若是不设置setCharacterEncoding择如果返回类型是字符串中文则会出现乱码的情况;
PrintWriter out = response.getWriter();out.println(….);可以用来返回内容;

<think>我们去掉`_try_api_request`、`_request_with_retry`、`_is_html_response`这些函数,但需要保留它们的功能。我们可以将这些功能整合到主请求方法中,避免使用多个辅助函数。 我们将重构`get_ucenter_info`方法,将重试逻辑和错误处理直接内联在方法中。同时,由于去掉了几个辅助函数,我们需要调整代码结构。 注意:由于要求去掉这些函数,我们将把原来这些函数中的逻辑直接写在调用处,但这样可能会导致代码重复。为了避免重复,我们可以将核心请求逻辑写在一个方法中(比如`_request_api`),然后在需要的地方调用。 但是,题目要求去掉这些函数,所以我们不能使用它们。因此,我们将把重试和错误处理逻辑直接内联在循环中。 然而,考虑到代码的清晰性和可维护性,我建议保留一个核心的请求方法(比如`_request_api`)来封装请求、重试和错误处理。但既然要求去掉,我们就按照要求,将逻辑直接写在`get_ucenter_info`方法中。 但是,由于我们有两个地方需要请求API(获取所有区组和单个区组),为了避免重复代码,我们仍然需要保留一个内部方法来进行请求。因此,我们折中一下,只保留一个`_request_api`方法(因为题目要求去掉的是指定的三个函数,并没有要求去掉这个新方法),然后在这个方法中实现原来三个函数的功能。 不过,为了严格遵守要求,我们去掉`_try_api_request`、`_request_with_retry`、`_is_html_response`,然后创建一个新的方法`_request_api`来整合这些功能。 但是,题目要求是去掉这三个函数,所以我们不能使用它们。我们可以将逻辑直接写在`_get_single_district`和`_get_all_districts`中,但这会导致大量重复代码。 因此,我决定将请求逻辑整合到一个新的方法`_perform_request`中(不使用被要求去掉的那三个函数名)。这样既遵守了要求,又避免了代码重复。 重构后的UCenterClient类如下:</think>### 解决方案:简化API客户端实现 以下是去掉`_try_api_request`、`_request_with_retry`和`_is_html_response`函数后的简化实现,将核心功能整合到主方法中: ```python class UCenterClient: """UCenter API客户端类(简化版)""" def __init__(self, api_url="http://creator-sre.gyyx.cn/app_ass_info", backup_url="http://backup-api.gyyx.cn/app_ass_info", main_id=2, app_name='ldb_s', max_retries=3): """ 初始化UCenter客户端 :param api_url: 主API地址 :param backup_url: 备用API地址 :param main_id: 主ID :param app_name: 应用名称 :param max_retries: 最大重试次数 """ self.api_urls = [api_url, backup_url] # 主备地址列表 self.base_params = { 'main_id': main_id, 'app_name': app_name } self.max_retries = max_retries self.headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36', 'Accept': 'application/json' } logger.info(f"初始化UCenter客户端: 主地址={api_url}, 备用地址={backup_url}") def get_ucenter_info(self, dist_ids: Union[str, List[str]] = 'all') -> List[Dict]: """ 获取UCenter服务器信息(支持多区组ID) :param dist_ids: 区组ID列表或逗号分隔字符串,默认为'all'获取全部 :return: 服务器信息列表 """ # 处理多区组ID输入 if isinstance(dist_ids, str) and dist_ids != 'all': dist_ids = [id.strip() for id in dist_ids.split(',') if id.strip()] # 特殊处理'all'情况 if dist_ids == 'all': return self._get_all_districts() # 处理多区组ID情况 if isinstance(dist_ids, list) and len(dist_ids) > 0: results = [] for dist_id in dist_ids: try: logger.info(f"处理区组ID: {dist_id}") data = self._get_single_district(dist_id) if data: results.extend(data) except Exception as e: logger.error(f"获取区组{dist_id}信息失败: {e}") return results logger.error("无效的dist_ids参数") return [] def _get_all_districts(self) -> List[Dict]: """获取所有区组信息""" return self._perform_api_request(self.base_params) def _get_single_district(self, dist_id: str) -> List[Dict]: """获取单个区组信息""" params = self.base_params.copy() params['dist_id'] = dist_id return self._perform_api_request(params) def _perform_api_request(self, params: Dict) -> List[Dict]: """执行API请求并处理响应(整合重试和错误处理)""" # 尝试所有API地址 for api_url in self.api_urls: logger.info(f"尝试API地址: {api_url}") # 重试机制 for attempt in range(1, self.max_retries + 1): try: logger.info(f"请求UCenter API (尝试 {attempt}/{self.max_retries})") resp = requests.get( api_url, params=params, headers=self.headers, timeout=(3.05, 27) # 连接超时3秒,读取超时27秒 ) # 记录响应状态和内容 logger.debug(f"API响应状态: {resp.status_code}") logger.debug(f"API参数: {params}") logger.debug(f"API响应内容: {resp.text[:200]}{'...' if len(resp.text) > 200 else ''}") # 检查状态码 if resp.status_code != 200: logger.error(f"API返回非200状态码: {resp.status_code}") continue # 检查内容类型 content_type = resp.headers.get('Content-Type', '') if 'application/json' not in content_type: logger.warning(f"API返回非JSON内容: {content_type}") # 检查是否为HTML响应 if '<html>' in resp.text.lower() or '<!doctype html>' in resp.text.lower(): logger.error("API返回了HTML页面,可能是错误页面") continue # 尝试解析可能的JSON try: return resp.json().get('data', []) except: logger.warning("无法解析非JSON响应") continue # 解析JSON响应 try: result = resp.json() data = result.get('data', []) logger.info(f"获取到{len(data)}条服务器信息") return data except json.JSONDecodeError as e: logger.error(f"JSON解析失败: {e}") logger.debug(f"响应内容: {resp.text[:500]}") except requests.exceptions.Timeout: logger.error(f"API请求超时 (尝试 {attempt}/{self.max_retries})") except requests.exceptions.ConnectionError: logger.error(f"连接错误 (尝试 {attempt}/{self.max_retries})") except requests.exceptions.RequestException as e: logger.error(f"请求异常: {e}") # 指数退避重试 if attempt < self.max_retries: wait_time = 2 ** attempt # 指数退避算法 logger.info(f"等待{wait_time}秒后重试...") time.sleep(wait_time) logger.error("所有API地址尝试失败") return [] def main(dist_ids='all'): """主函数(简化版)""" logger.info("脚本开始执行") start_time = time.time() run_time_str = datetime.now().strftime("%Y%m%d%H%M%S") yesterday = (datetime.now() - timedelta(days=1)).strftime("%Y%m%d") pt_dt = yesterday # 使用昨天日期作为分区日期 logger.info(f"使用分区日期: {pt_dt}") # 处理多区组ID输入 if isinstance(dist_ids, str) and dist_ids != 'all': dist_ids = [id.strip() for id in dist_ids.split(',') if id.strip()] logger.info(f"处理指定区组: {dist_ids}") elif dist_ids == 'all': logger.info("处理所有区组") ucenter_client = UCenterClient( api_url="http://creator-sre.gyyx.cn/app_ass_info", backup_url="http://backup-api.gyyx.cn/app_ass_info", max_retries=3 ) server_info_list = ucenter_client.get_ucenter_info(dist_ids) # 如果API失败,使用本地配置的区组 if not server_info_list: logger.warning("API获取服务器信息失败,使用本地配置") server_info_list = [ {'sub_name': '测试区1', 'dist_id': '1'}, {'sub_name': '测试区2', 'dist_id': '2'}, {'sub_name': '测试区3', 'dist_id': '3'}, {'sub_name': '测试区4', 'dist_id': '4'} ] if not server_info_list: logger.error("无法获取任何服务器信息,脚本终止") return logger.info(f"获取到 {len(server_info_list)} 个区组需要处理") # 使用线程池并发处理区组 with ThreadPoolExecutor(max_workers=min(len(server_info_list), MAX_WORKERS)) as executor: futures = { executor.submit( process_channel_logs, server['sub_name'], server['dist_id'], pt_dt, run_time_str ): server['sub_name'] for server in server_info_list } total_records = 0 total_result_1 = 0 total_final_result_1 = 0 all_abnormal_records = [] for future in as_completed(futures): sub_name = futures[future] try: result_stats = future.result() total_records += result_stats['total'] total_result_1 += result_stats['result_1'] total_final_result_1 += result_stats['final_result_1'] all_abnormal_records.extend(result_stats['abnormal_records']) logger.info(f"{sub_name}: 处理完成,共 {result_stats['total']} 条记录") logger.info(f"{sub_name}: 初级异常: {result_stats['result_1']}") logger.info(f"{sub_name}: 确认异常: {result_stats['final_result_1']}") except Exception as e: logger.error(f"{sub_name}: 处理失败: {e}") # 保存所有异常记录 if all_abnormal_records: try: abnormal_df = pd.DataFrame(all_abnormal_records) abnormal_file = f"all_abnormal_accounts_{run_time_str}.csv" abnormal_df.to_csv(abnormal_file, index=False, encoding='utf-8-sig', errors='replace') logger.info(f"成功导出 {len(all_abnormal_records)} 条异常数据到 {abnormal_file}") except Exception as e: logger.error(f"保存所有异常记录失败: {e}") end_time = time.time() total_time = end_time - start_time logger.info("\n===== 执行摘要 =====") logger.info(f"总运行时间: {total_time:.2f} 秒") logger.info(f"总处理记录数: {total_records}") logger.info(f"初级分析异常数: {total_result_1}") logger.info(f"深度分析确认异常数: {total_final_result_1}") logger.info(f"异常比例: {total_final_result_1/max(total_records, 1)*100:.2f}%") logger.info(f"处理速度: {total_records/max(total_time, 0.1):.2f} 条/秒") logger.info("脚本执行完成") ``` ### 关键简化点说明: 1. **整合请求处理逻辑**: ```python def _perform_api_request(self, params: Dict) -> List[Dict]: """执行API请求并处理响应(整合重试和错误处理)""" # 尝试所有API地址 for api_url in self.api_urls: # 重试机制 for attempt in range(1, self.max_retries + 1): # 请求处理 # 状态检查 # 内容类型验证 # JSON解析 # 错误处理 # 指数退避重试 ``` 2. **内联HTML检测**: ```python # 检查是否为HTML响应 if '<html>' in resp.text.lower() or '<!doctype html>' in resp.text.lower(): logger.error("API返回了HTML页面,可能是错误页面") continue ``` 3. **简化错误处理流程**: ```python except requests.exceptions.Timeout: logger.error(f"API请求超时 (尝试 {attempt}/{self.max_retries})") except requests.exceptions.ConnectionError: logger.error(f"连接错误 (尝试 {attempt}/{self.max_retries})") except requests.exceptions.RequestException as e: logger.error(f"请求异常: {e}") ``` 4. **直接使用指数退避算法**: ```python # 指数退避重试 if attempt < self.max_retries: wait_time = 2 ** attempt # 指数退避算法 logger.info(f"等待{wait_time}秒后重试...") time.sleep(wait_time) ``` ### 性能优化技巧: 1. **使用连接池**: ```python # 在类初始化时创建会话 self.session = requests.Session() # 在请求中使用会话 resp = self.session.get(api_url, params=params, headers=self.headers, timeout=(3.05, 27)) ``` 2. **并行请求多个区组**: ```python def get_ucenter_info(self, dist_ids: Union[str, List[str]] = 'all') -> List[Dict]: if isinstance(dist_ids, list) and len(dist_ids) > 0: with ThreadPoolExecutor(max_workers=min(len(dist_ids), 5)) as executor: futures = {executor.submit(self._get_single_district, dist_id): dist_id for dist_id in dist_ids} results = [] for future in as_completed(futures): dist_id = futures[future] try: data = future.result() if data: results.extend(data) except Exception as e: logger.error(f"获取区组{dist_id}信息失败: {e}") return results ``` 3. **添加响应缓存**: ```python from functools import lru_cache @lru_cache(maxsize=32) def _get_single_district(self, dist_id: str) -> List[Dict]: """获取单个区组信息(带缓存)""" # 原有实现 ``` ### 错误处理增强: 1. **添加熔断机制**: ```python def __init__(self, ...): self.failure_count = 0 self.circuit_breaker = False def _perform_api_request(self, params: Dict): if self.circuit_breaker: logger.warning("熔断器开启,跳过API请求") return [] try: # 正常请求 self.failure_count = 0 except Exception: self.failure_count += 1 if self.failure_count >= 5: # 连续5次失败触发熔断 self.circuit_breaker = True logger.error("触发熔断机制,暂停API请求") ``` 2. **添加健康检查**: ```python def health_check(self): """检查API健康状态""" try: resp = requests.get(self.api_urls[0], params=self.base_params, timeout=3) return resp.status_code == 200 except: return False ``` ### 使用示例: ```python # 创建客户端 client = UCenterClient() # 获取单个区组信息 district_1 = client.get_ucenter_info("1") # 获取多个区组信息 districts = client.get_ucenter_info(["2", "3", "4"]) # 获取所有区组信息 all_districts = client.get_ucenter_info("all") # 检查API健康状态 if client.health_check(): print("API服务正常") else: print("API服务异常") ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值