jeecgboot/JeecgBoot · warning · JeecgBootBizTipException

原始接口路径包含非法字符

Error message

原始接口路径包含非法字符

What it means

Thrown by OpenApiController.validOriginUrl when URLDecoder.decode fails on the originUrl parameter. The method decodes the URL twice (to defeat %252f-style double-encoding bypass) and any malformed percent-encoding (e.g. a stray '%' not followed by two hex digits) makes the decoder raise IllegalArgumentException, which is wrapped into this JeecgBootBizTipException. It is a hard input-validation failure, not retriable.

Source

Thrown at jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/controller/OpenApiController.java:258

        return token;
    }

    /**
     * 校验原始接口路径是否合法:
     *  - 相对路径:必须以 / 开头,不允许 // 和 .. 防止路径穿越
     *  - 完整URL:仅允许 http/https 协议,禁止 file/ftp/gopher/jar/netdoc 等其它协议(用于微服务模式跨模块调用)
     */
    private void validOriginUrl(String originUrl) {
        if (oConvertUtils.isEmpty(originUrl)) {
            throw new JeecgBootBizTipException("原始接口路径不能为空");
        }
        String decoded;
        try {
            decoded = java.net.URLDecoder.decode(originUrl, "UTF-8");
            // 二次解码,防止 %252f 这类双重编码绕过
            decoded = java.net.URLDecoder.decode(decoded, "UTF-8");
        } catch (Exception e) {
            throw new JeecgBootBizTipException("原始接口路径包含非法字符");
        }
        //update-begin---author:scott ---date:20260429  for:【issues/9590】微服务nginx部署openApi接口访问不到-----------
        // 微服务部署时,OpenAPI 配置的接口可能位于其他微服务模块(如 erp 7003),允许 originUrl 直接配置完整 http(s) URL
        String lower = decoded.toLowerCase();
        boolean isFullHttpUrl = lower.startsWith("http://") || lower.startsWith("https://");
        if (!isFullHttpUrl) {
            if (!decoded.startsWith("/")) {
                throw new JeecgBootBizTipException("原始接口路径必须以 / 开头,或填写完整的 http(s) URL");
            }
            if (decoded.startsWith("//") || decoded.startsWith("/\\")) {
                throw new JeecgBootBizTipException("原始接口路径不能以 // 或 /\\ 开头");
            }
            if (lower.contains("://") || lower.startsWith("file:") || lower.startsWith("ftp:") || lower.startsWith("gopher:")
                    || lower.startsWith("jar:") || lower.startsWith("netdoc:")) {
                throw new JeecgBootBizTipException("原始接口路径仅支持相对路径或 http(s) 完整URL");
            }
        } else {
            // 即便是完整URL,也禁止其它危险协议(防止 http://x@file:/... 之类的绕过场景)

View on GitHub (pinned to 96fb33f5ec)

Solutions

  1. URL-encode the originUrl value once before submitting (let the server's single decode pass yield the intended path), or send it fully unencoded if it is a plain relative path like /sys/api.
  2. Remove any literal '%' characters or replace them with their percent-encoded form '%25'.
  3. Validate the value with java.net.URLEncoder / a URL sanity check in the admin UI before the request is sent.

Example fix

// before: originUrl = "/sys/%file"  (malformed %f)
// after:  originUrl = "/sys/%25file"  (valid %25 -> literal %)
Defensive patterns

Strategy: validation

Validate before calling

// Pre-validate the originUrl before calling the OpenAPI config API
private static boolean isOriginUrlDecodable(String s) {
    if (s == null || s.isEmpty()) return false;
    try {
        String d = java.net.URLDecoder.decode(s, "UTF-8");
        java.net.URLDecoder.decode(d, "UTF-8"); // match server's double-decode
        return true;
    } catch (Exception e) {
        return false;
    }
}
if (!isOriginUrlDecodable(originUrl)) {
    // reject / fix the value before submit
}

Prevention

When it happens

Trigger: Saving/updating an OpenAPI config whose origin_url field contains a malformed escape sequence such as '%zz', a lone '%', or invalid UTF-8 byte sequences. Any POST to the openapi config endpoint (add/edit) passes originUrl through validOriginUrl.

Common situations: Operators paste an origin URL copied from a browser address bar that is already decoded but contains a literal '%'; migration scripts that hand-build URLs with unescaped characters; proxy/CDN that re-encodes the path.

Related errors


AI-assisted analysis of jeecgboot/JeecgBoot@96fb33f5ec (2026-08-14). Data as JSON: /api/errors/93b0c9a24cba70ee. Report an issue: GitHub.