【问题标题】:How to Set System Properties in Spring MVC如何在 Spring MVC 中设置系统属性
【发布时间】:2018-01-20 09:56:54
【问题描述】:

我正在尝试为 trustStore 和 keyStore 设置系统属性,如下所示:

@WebListener
public abstract class ContextListenerExample implements ServletContextListener {
    public void contextInitialized(ServletContextEvent e){
        System.setProperty("javax.net.ssl.trustStore", "C:\\Users\\trustCert.jks");
        System.setProperty("javax.net.ssl.trustStorePassword", "test123");
        System.setProperty("javax.net.ssl.trustStoreType", "jks");
        System.setProperty("javax.net.ssl.keyStore", "C:\\Users\\keyCert.p12");
        System.setProperty("javax.net.ssl.keyStorePassword", "keystore");
        System.setProperty("javax.net.ssl.keyStoreType", "keystoreType");
  }
}

我遵循了示例here,但是当我运行我的应用程序时,它永远不会到达 contextIntialized 方法。此外,我必须将 ContextListenerExample 类更改为抽象类。是否有其他设置系统属性的方法,或者我缺少一些需要修改的其他文件?

我添加了一个新文件 SslConfiguration 类:

@Configuration
public class SslConfiguration {
    @Value("${C:\\Users\\A21\\src\\main\\java\\org\\test\\certificates\\test.jks}")
    private Resource trustStore;

    @Value("test123")
    private String trustStorePassword;

    @Value("${C:\\Users\\A21\\src\\main\\java\\org\\test\\certificates\\test.p12}")
    private Resource keyStore;

    @Value("teststore")
    private String keyStorePassword;

    @Bean
    RestTemplate restTemplate() throws Exception {
        SSLContext sslContext = new SSLContextBuilder()
                .loadKeyMaterial(
                        keyStore.getFile(),
                        keyStorePassword.toCharArray(),
                        keyStorePassword.toCharArray())
                .loadTrustMaterial(
                        trustStore.getURL(),
                        trustStorePassword.toCharArray(),
                        // use this for self-signed certificates only:
                        new TrustSelfSignedStrategy())
                .build();

        SSLConnectionSocketFactory socketFactory =
                new SSLConnectionSocketFactory(sslContext);
        HttpClient httpClient = HttpClients.custom()
                .setSSLSocketFactory(socketFactory).build();
        HttpComponentsClientHttpRequestFactory factory =
                new HttpComponentsClientHttpRequestFactory(httpClient);
        return new RestTemplate(factory);
    }
}

【问题讨论】:

    标签: java spring spring-mvc truststore


    【解决方案1】:

    抽象类不能被实例化,所以这可能是这段代码永远不会被调用的原因。不要将ContextListenerExample类抽象化,而是尝试实现ServletContextListener接口中声明的另一个方法:

    public void contextDestroyed(ServletContextEvent e) {
      // you can just leave it empty
    }
    

    【讨论】:

    • 这确实让我可以在实现 contextDestroyed 后访问 contextIntialized 中包含的代码,但它似乎没有注册 trustStore。
    • 嗯,这是另一个问题。可能在您指定这些属性的那一刻,Spring 已经初始化了密钥库/信任库。例如,您可以尝试here 描述的不同方法。
    • 不,我尝试将 trustStore 和 keyStore 设置为您链接我的答案页面中提供的资源元素,但没有运气创建“RestTemplate”bean。我已经编辑了我的原始问题以合并我添加到我的项目中的新类。