0

我正在使用 java.net 编写一个应该执行 PATCH 请求的休息客户端。但由于 PATCH 在 java.net 中不是受支持的方法,我使用反射通过更改代码来使其支持

private void updateConnectionToSupportPatchRequest(final HttpURLConnection conn)
    throws ReflectiveOperationException {
    try {
        final Object targetConn;
        if (conn instanceof HttpsURLConnectionImpl) {
            final Field delegateField = HttpsURLConnectionImpl.class.getDeclaredField("delegate");
            delegateField.setAccessible(true);
            targetConn = delegateField.get(conn);
        } else {
            targetConn = conn;
        }
        final Field methodField = HttpURLConnection.class.getDeclaredField("method");
        methodField.setAccessible(true);
        methodField.set(targetConn, "PATCH");
    } catch (final NoSuchFieldException ex) {
        LOGGER.error("NoSuchFieldException: {} ", ex.getMessage());
    }
}

但是当我在 JBoss 中部署使用我的 rest 客户端的应用程序时,我收到了这个错误 -

java.lang.NoClassDefFoundError: sun/net/www/protocol/https/HttpsURLConnectionImpl

我查看了这个错误并看到了这篇文章http://planet.jboss.org/post/dealing_with_sun_jdk_related_noclassdeffounderror_under_jboss

我尝试了帖子中建议的解决方案,但仍然遇到相同的错误。关于如何通过这个问题的任何想法?

PS 我不能使用 Apache HttpClient 或 RestEasy(Jboss) 因为项目中使用了另一个不支持 Apache HttpClient 的 3PP

4

1 回答 1

0

在尝试摆弄 JDK 的内部类之前,您是否尝试过使用解决方法?X-HTTP-Method-Override如果是这种情况,您可以使用实例的getClass- 方法来访问字段并isAssignableFrom用作instanceof.

摆脱指定具体类的另一种方法是尝试获取该字段HttpsURLConnection并在找不到该字段时假设一个非 Https-URLConnection。这可能类似于以下代码:

private void updateConnectionToSupportPatchRequest(final HttpURLConnection conn) 
    throws ReflectiveOperationException {
    try {
        final Object targetConn = conn;
        try {
            final Field delegateField = findField(conn.getClass(), "delegate");
            delegateField.setAccessible(true);
            targetConn = delegateField.get(conn);
        }
        catch(NoSuchFieldException nsfe) {
            // no HttpsURLConnection
        }
        final Field methodField = findField(conn.getClass(), "method");
        methodField.setAccessible(true);
        methodField.set(targetConn, "PATCH");
    } catch (final NoSuchFieldException ex) {
        LOGGER.error("NoSuchFieldException: {} ", ex.getMessage());
    }
}

private Field findField(Class clazz, String name) throws NoSuchFieldException {
    while (clazz != null) {
        try {
            return clazz.getDeclaredField(name);
        }
        catch(NoSuchFieldException nsfe) {
            // ignore
        }
        clazz = clazz.getSuperclass();
    }
    throw new NoSuchFieldException(name);
}

但这可能会在另一个层面上失败,因为 - 显然 - JBoss 中使用的类不是您实现解决方法的类,因此字段和方法的命名可能不同。

于 2017-11-06T11:44:28.713 回答