user331465
user331465

Reputation: 3094

best way to dynamically populate .js properties from spring boot runtime application.properties?

tldr

How to best "put" runtime application.properties values from a spring boot app in a javascript file

[Admittedly this is probably a stupid question for the experienced spring dev...so please share how to solve this problem "the spring way"]

Context

We have tiny app which a front-end developer put together and "threw over the wall"..It defines a properties file settings.js:

var SERVERROOT = 'http://solr:8983/solr/operations/select/';

referenced by html :

 <script type='text/javascript' src="js/settings.js"></script>

I would like to define the solr path in application.yml at runtime as follows:

app:    
   solr:
      path: 'http://solr:8983/solr/operations/select/'

Question

What is the best way to "populate" this settings.js value from application.properties (or equivalent, i.e. command line arguments, e.g.:

 -Dapp.solr.path=...

)

Possible

I thought about putting 'settings.js' as a thymeleaf template (settings.js.html) and having a spring controller populate the model from application.properties.

I didn't know if a more "native spring" method existed.

Thanks!

Upvotes: 0

Views: 897

Answers (2)

Haseb Ansari
Haseb Ansari

Reputation: 607

The answer of @Wim above is correct but with new spring boot edition use the below code to register your transformer;

@Configuration
    public class WebConfig implements WebMvcConfigurer {

    // inject this via constructor
    private final InjectSolrPathResourceTransformer resourceTransformer;

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/js/**")
            .addResourceLocations("classpath:/public/js/")
            .resourceChain(false)
            .addTransformer(resourceTransformer);
    }
}

Upvotes: 2

Wim Deblauwe
Wim Deblauwe

Reputation: 26878

You could use a ResourceTransformer:

@Component
public class InjectSolrPathResourceTransformer implements ResourceTransformer {
    private final MySetting settings; // inject via constructor

    @Override
    public Resource transform(HttpServletRequest request, Resource resource, ResourceTransformerChain transformerChain) throws IOException {
if (request.getServletPath().equals("/js/settings.js")) {
            byte[] bytes = FileCopyUtils.copyToByteArray(resource.getInputStream());
            String content = new String(bytes, StandardCharsets.UTF_8);
            content = content.replace("var SERVERROOT = SERVERROOT_VALUE",
                                      "var SERVERROOT = '" + settings.getSolrPath() + "'");

            return new TransformedResource(resource, content.getBytes(StandardCharsets.UTF_8));
        } else {
            return resource;
        }
    }
}

This assumes that you change settings.js to be:

var SERVERROOT = SERVERROOT_VALUE

To use the ResourceTransformer, register it in your WebMvcConfigurer:

@Configuration
public class WebConfig implements WebMvcConfigurer {

    // inject this via constructor
    private final InjectSolrPathResourceTransformer resourceTransformer;

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/js/**")
                .addResourceLocations("classpath:/public/js/")
                .addTransformer(resourceTransformer);
    }
}

Upvotes: 3

Related Questions