WSO2 API Manager自定义Handler拦截API请求失败求助
首先,你的CustomAPIProxyHandler存在几个关键问题,导致WSO2 AM没有触发后端服务调用,同时配置环节也有需要修正的地方。下面是逐一排查和修复的步骤:
1. 核心问题:handleRequest返回false终止请求流程
在Synapse Handler的规范中,handleRequest方法返回false会立即终止整个请求处理链——后续的默认API代理逻辑根本不会执行,这就是你只收到原参数、没触发后端调用的最直接原因。
你需要把返回值改为true,让Synapse继续执行后续的Handler和代理流程:
public boolean handleRequest(MessageContext messageContext) { // 你的校验逻辑... return true; // 改为true,允许流程继续向下执行 }
2. 缺失异常处理,无法排查运行时错误
你的代码没有任何异常捕获逻辑,WSO2的Synapse容器会静默处理未捕获的异常,导致你看不到任何错误日志,甚至无法判断Handler是否真的被执行了。
必须添加异常处理,并使用WSO2的日志工具记录错误:
import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; public class CustomAPIProxyHandler extends AbstractHandler { private static final Log log = LogFactory.getLog(CustomAPIProxyHandler.class); public boolean handleRequest(MessageContext messageContext) { try { // 你的原有逻辑... } catch (Exception e) { log.error("Error executing CustomAPIProxyHandler", e); // 可选:如果校验失败可以返回false终止请求,否则返回true继续流程 return true; } return true; } }
3. 错误序列化MessageContext,无法正确传递用户参数
你直接把MessageContext序列化为JSON,这会包含大量Synapse内部的上下文数据,而非用户的实际请求参数。你需要从MessageContext中提取真正的请求体或查询参数:
提取JSON请求体示例:
import org.apache.synapse.transport.passthru.util.RelayUtils; import org.apache.axiom.om.OMElement; // 在handleRequest方法内: // 构建完整的请求消息体 RelayUtils.buildMessage(messageContext.getEnvelope()); OMElement payload = messageContext.getEnvelope().getBody().getFirstElement(); String requestBody = payload.getText(); // 获取JSON格式的请求体
提取URL查询参数示例:
import org.apache.synapse.rest.RESTConstants; import java.util.Map; Map<String, String> queryParams = (Map<String, String>) messageContext.getProperty(RESTConstants.REST_QUERY_PARAMS); // 遍历处理查询参数 for (Map.Entry<String, String> entry : queryParams.entrySet()) { log.info("Query param: " + entry.getKey() + " = " + entry.getValue()); }
4. 部署与配置验证
JAR部署位置
确保你的JAR文件放在WSO2 AM的repository/components/lib目录下(如果是OSGi bundle,也可以放在repository/components/dropins),然后必须重启WSO2 AM,否则新的类不会被加载。
Velocity模板配置修正
你的velocity_template.xml有语法错误:最后多了一个#end,正确的模板应该是:
<?xml version="1.0" encoding="UTF-8"?> <handlers xmlns="http://ws.apache.org/ns/synapse"> <handler class="org.wso2.carbon.test.CustomAPIProxyHandler" /> #foreach($handler in $handlers) <handler class="$handler.className"> #if($handler.hasProperties()) #set ($map = $handler.getProperties() ) #foreach($property in $map.entrySet()) <property name="$!property.key" value="$!property.value" /> #end #end </handler> #end </handlers>
修改后需要重新发布API,因为velocity模板只在API发布时生成对应的Synapse配置。
验证Handler是否被加载
查看WSO2 AM的启动日志(repository/logs/wso2carbon.log),搜索你的Handler类名CustomAPIProxyHandler,如果看到类似Added handler class org.wso2.carbon.test.CustomAPIProxyHandler的日志,说明Handler被成功加载。
修改后的完整Handler示例
import java.io.IOException; import org.apache.http.HttpResponse; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.HttpClientBuilder; import org.apache.synapse.MessageContext; import org.apache.synapse.rest.AbstractHandler; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.synapse.transport.passthru.util.RelayUtils; import org.apache.axiom.om.OMElement; public class CustomAPIProxyHandler extends AbstractHandler { private static final Log log = LogFactory.getLog(CustomAPIProxyHandler.class); private static final String VALIDATION_SERVICE_URL = "http://localhost:8085/drm/checkKpi"; public boolean handleRequest(MessageContext messageContext) { try { // 构建完整请求体 RelayUtils.buildMessage(messageContext.getEnvelope()); OMElement payload = messageContext.getEnvelope().getBody().getFirstElement(); String requestBody = payload.getText(); // 调用本地校验服务 HttpClient httpClient = HttpClientBuilder.create().build(); HttpPost post = new HttpPost(VALIDATION_SERVICE_URL); StringEntity entity = new StringEntity(requestBody, "UTF-8"); post.setEntity(entity); post.setHeader("Content-type", "application/json"); HttpResponse response = httpClient.execute(post); // 根据校验服务响应决定是否终止请求 int statusCode = response.getStatusLine().getStatusCode(); if (statusCode != 200) { log.error("Validation service returned error: " + statusCode); return false; // 校验失败,终止请求 } } catch (Exception e) { log.error("Error executing custom proxy handler", e); return true; // 异常时允许流程继续,或根据需求返回false } return true; // 校验通过,继续执行后端调用 } public boolean handleResponse(MessageContext messageContext) { return true; } }
最后验证步骤
- 替换修改后的Handler代码,重新打包JAR。
- 将JAR放入
repository/components/lib,重启WSO2 AM。 - 修改
velocity_template.xml,移除多余的#end。 - 重新发布你的API(或创建新API)。
- 使用Postman调用API,同时查看WSO2日志,确认Handler被执行且后端服务被调用。
内容的提问来源于stack exchange,提问作者Nina Lukic

