問題メモ:class path resource[xx]cannot be resolved to absolute file path because

4171 ワード

問題の説明
テストサービスのバージョンはSpring Cloud Dalstonです.SR 5 Spring Bootでhttpsを構成する場合、コードは以下の通りです.
    @Bean
    @ConditionalOnExpression("#{ ${self.https.enable:false}}")
    public EmbeddedServletContainerFactory servletContainer() {
        TomcatEmbeddedServletContainerFactory tomcat = new TomcatEmbeddedServletContainerFactory();
        tomcat.addAdditionalTomcatConnectors(createSslConnector());
        return tomcat;
    }

    private Connector createSslConnector() {
        Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
        Http11NioProtocol protocol = (Http11NioProtocol) connector.getProtocolHandler();

        ClassPathResource resource = new ClassPathResource(".keystore");
        try {
            connector.setScheme("https");
            connector.setSecure(true);
            connector.setPort(port);
            protocol.setSSLEnabled(true);
            protocol.setKeystoreFile(resource.getFile().getAbsolutePath());
            protocol.setKeystorePass(keystorePass);
            protocol.setKeyAlias(keyAlias);
            protocol.setKeyPass(keyPass);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return connector;
    }


以上のコードは、ideaでサービスを実行するときに正常に実行できます.ただし、サービスをjarを実行可能なパッケージにパッケージ化し、jarサービスでサービスを実行すると、次のエラーが発生します.
java.io.FileNotFoundException: class path resource [.keystore] cannot be resolved to absolute file path because it does not reside in the file system: jar:file:/D:/tmp/interface
e-1.0-SNAPSHOT.jar!/BOOT-INF/classes!/.keystore
        at org.springframework.util.ResourceUtils.getFile(ResourceUtils.java:215)
        at org.springframework.core.io.AbstractFileResolvingResource.getFile(AbstractFileResolvingResource.java:53)

パッケージ化後Springがresourceを使用できないため、上記の問題が発生しました.getFile()JARのパスのファイルにアクセスするにはresourceを使用する必要があります.getInputStream().
修正コード:resource.getInputStream()は、証明書ファイルを取得して一時ファイルに格納し、最後にHttp 11 NioProtocolインスタンスがこの一時ファイルのパスを介して値を入力することで、このHttp 11 NioProtocolインスタンスが証明書ファイルを取得できます.
private Connector createSslConnector() {
      Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
      Http11NioProtocol protocol = (Http11NioProtocol) connector.getProtocolHandler();

      ClassPathResource resource = new ClassPathResource(".keystore");
      //  
      String tempPath =System.getProperty("java.io.tmpdir") + System.currentTimeMillis()+".keystore";
      File f = new File(tempPath);
      logger.info(".keystore " + tempPath);

      try {
          //  key 
          IOUtils.copy(resource.getInputStream(),new FileOutputStream(f));
          connector.setScheme("https");
          connector.setSecure(true);
          connector.setPort(port);
          protocol.setSSLEnabled(true);
          //  
          protocol.setKeystoreFile(f.getAbsolutePath());
          protocol.setKeystorePass(keystorePass);
          protocol.setKeyAlias(keyAlias);
          protocol.setKeyPass(keyPass);
      } catch (IOException e) {
          e.printStackTrace();
      }

      return connector;
  }