【问题标题】:URLConnection created through OkHttp has useCache set to false通过 OkHttp 创建的 URLConnection 将 useCache 设置为 false
【发布时间】:2014-05-21 09:24:50
【问题描述】:

我正在使用 Kohsuke GitHub-API 从我的 Java(服务器端)应用程序连接到 GitHub,并且我想使用 OkHttp's 缓存来自 GitHub 的响应的功能。当我为它编写测试时,这非常有效,但它在应用程序本身中不起作用,我不知道为什么会这样。我设法将问题追溯到创建 URLConnection 对象时,该对象的 useCache 变量设置为 false,但我不知道为什么。它可能与服务器配置或类似的东西有关吗?

我将不胜感激任何想法,甚至向任何方向轻推,因为坦率地说,我没有任何想法......谢谢

提供者:

public class GitHubProvider implements Provider<GitHub> {

@Override
public GitHub get() {
    GitHub gitHub = null;
    HttpResponseCache cache = null;

    OkHttpClient okHttpClient = new OkHttpClient();
    File cacheDir = new File(System.getProperty("java.io.tmpdir"), UUID.randomUUID().toString());

    try {
        cache = new HttpResponseCache(cacheDir, 10L * 1024 * 1024);
    } catch (IOException e) {
        // NOTHING
    }
    okHttpClient.setResponseCache(cache);

    try {
        gitHub = GitHub.connectUsingPassword("user", "password");
    } catch (Exception e) {
        // NOTHING
    }
    gitHub.setConnector(new OkHttpConnector(okHttpClient));

    return gitHub;
}
}

测试(工作):

@RunWith(JukitoRunner.class)
public class SoftwareComponentServiceTest {

public static class Module extends TestModule {
    @Override
    protected void configureTest() {
        bind(GitHub.class).toProvider(GitHubProvider.class);
    }
}

@Inject
GitHub gitHub;

@Test
public void testInjectedGitHubResponseCache() {
    try {
        GHUser ghUser = gitHub.getUser("user");
        GHRepository repository = ghUser.getRepository("repository");

        int limit = gitHub.getRateLimit().remaining;
        repository.getFileContent("README.md");

        assertEquals(limit - 1, gitHub.getRateLimit().remaining);

        repository.getFileContent("README.md");

        assertEquals(limit - 1, gitHub.getRateLimit().remaining);
    } catch (IOException e) {
        e.printStackTrace();
    }
}
}

应用程序中使用的服务(不起作用):

@Singleton
@RequiresAuthentication
public class SoftwareComponentService {

@Inject
GitHub gitHub;

public List<SoftwareComponent> findAll() {
    List<SoftwareComponent> softwareComponentList = new ArrayList<SoftwareComponent>();

    try {
        GHUser ghUser = gitHub.getUser("user");
        List<GHRepository> repositories = ghUser.listRepositories().asList();

        for (int i = 0; i < repositories.size(); i++) {
            GHRepository repository = repositories.get(i);
            if (!repository.getName().startsWith("sc_")) {
                continue;
            }
            softwareComponentList.add(new SoftwareComponent(repository.getName(), repository.getDescription()));
        }
    } catch (IOException e) {
        // NOTHING
    }
    return softwareComponentList;
}
}

【问题讨论】:

    标签: java github-api urlconnection okhttp


    【解决方案1】:

    原因

    创建 URLConnection 对象时将其 useCache 变量设置为 false,因为它的 defaultUseCaches 变量也设置为 false em> 在初始化时由 Tomcat 服务器。 Tomcat 通过它的 JreMemoryLeakPreventionListener 类来做到这一点,因为 reading resources from JAR files using java.net.URLConnections can sometimes result in the JAR file being lockedurlCacheProtection 变量)。他们为解决此问题而实施的解决方法是默认禁用 URLConnection 缓存(!?!?)。

    解决办法

    此解决方法的解决方法是创建一个 dummy URLConnection 并将其 setDefaultUseCaches() 方法用于change the default value of every subsequently created URLConnection(如 Jesse Wilson 所建议)。

    URL url = new URL("jar:file://dummy.jar!/");
    URLConnection uConn = url.openConnection();
    uConn.setDefaultUseCaches(true);
    

    非常感谢 Jesse Wilson 为我指明了正确的方向!

    【讨论】:

      【解决方案2】:

      有一种叫做URLConnection.setDefaultUseCaches() 的疯狂方法可以在全球范围内执行此操作。这是一个像静态方法一样工作的实例方法:它为每个人设置属性。

      【讨论】:

      • URLConnection.setDefaultUseCaches() 方法不是静态方法,遗憾的是我无法访问 OkHttp 用来建立连接的 URLConnection 实例。
      • 是的,那个 API 很糟糕。您应该能够创建 any URLConnection 实例来执行此操作。即使是 JAR URLConnection 也可以做到:getClass().getResource(getClass().getSimpleName() + ".class").openConnection().setDefaultUseCaches(false);
      • 谢谢!我创建了一个虚拟 URLConnection (使用虚拟 .jar 文件)并按照您的建议使用了 setDefaultUseCaches() 方法并且它有效。 URL url = new URL("jar:file://dummy.jar!/"); URLConnection uConn = url.openConnection(); uConn.setDefaultUseCaches(true);我也找到了这种行为的原因——Tomcat enables urlCacheProtection
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-01-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多