如何在 Spring 引导项目中设置 web.xml JNDI <env-entry> 的等价物?

How to set equivalent of web.xml JNDI <env-entry> in a Spring Boot project?

关于 ,我想在 JSF/JoinFaces/SpringBoot 应用程序(没有 web.xml)中设置与此 web.xml 配置等效的配置。

<env-entry>
    <env-entry-name>jsf/ClientSideSecretKey</env-entry-name>
    <env-entry-type>java.lang.String</env-entry-type>
    <env-entry-value>[AES key in Base64 format]</env-entry-value>
</env-entry>

有什么指点吗?

本质上 <env-entry> 声明了一个 Web 应用程序上下文属性。

您可以 initialize your servlet context 并在 Spring 引导应用程序中提供等效的 servlet 上下文属性。

为此,如果您的应用程序必须部署在传统的 servlet 容器中,您可以注册一个实现 ServletContextInitializer interface (or WebApplicationInitializer 的 bean。例如:

public class JsfServletContextInitializer implements ServletContextInitializer {

  @Override
  public void onStartup(ServletContext servletContext) throws ServletException {
    servletContext.setAttribute("jsf/ClientSideSecretKey", "[AES key in Base64 format]");
  }

}

不要忘记在您的配置中将其注册为 bean。

如果您正在使用 spring 引导和嵌入式 tomcat 服务器,您可以使用以下配置以编程方式添加 <env-entry>

@SpringBootApplication
public class DemoApplication extends SpringBootServletInitializer {
    
    
    @Bean
    public TomcatServletWebServerFactory tomcatFactory() {
        return new TomcatServletWebServerFactory() {
            @Override
            protected TomcatWebServer getTomcatWebServer(org.apache.catalina.startup.Tomcat tomcat) {
                tomcat.enableNaming(); 
                return super.getTomcatWebServer(tomcat);
            }

            @Override 
            protected void postProcessContext(Context context) {

                // adding <resource-ref>
                ContextResource resource = new ContextResource();
                resource.setName("jdbc/myJndiResource");
                resource.setType(DataSource.class.getName());
                resource.setProperty("driverClassName", "org.postgresql.Driver");

                resource.setProperty("url", "jdbc:postgresql://hostname:port/dbname");
                resource.setProperty("username", "username");
                resource.setProperty("password", "password");
                context.getNamingResources()
                       .addResource(resource); 
                
                // adding <env-entry>
                ContextEnvironment ce = new ContextEnvironment();
                ce.setName("jsf/ClientSideSecretKey");
                ce.setType(String.class.getName());
                ce.setValue("[AES key in Base64 format]");
                context.getNamingResources().addEnvironment(ce); 
                
            }
        };
    }

    public static void main(String[] args) throws NamingException {
        SpringApplication.run(DemoApplication.class, args);
    }

}

一旦定义了 jndi 命名资源,就可以在您的应用程序中使用 InitialContextJndiTemplate 访问它们。

JndiTemplate jndiTemplate = new JndiTemplate();
String str = (String) jndiTemplate.lookup("java:comp/env/jsf/ClientSideSecretKey");

希望这能帮助您解决问题。