3

I am working on a spring boot application. In this application, I have created application.properties as a spring bean using the following code

SCENARIO 1

Application.Properties

http.port =8080

ApplicationPropertyHandler

@PropertySource("config/application.properties")
@Component
public class ApplicationPropertyHandler
{
    @Value("${http.port}")
    private String nonSecurePort;

    @Value("${https.port}" required=false)
    private String securePort;

    @Value("${server.servlet.context-path}")
    private String contextPath;

    @Value("${security.key}")
    private String securityKey;


}

SCENARIO 2

When i secure application https.port will write to application.properties

Application.Properties

http.port =8080
https.port=8081

ApplicationPropertyHandler

@PropertySource("config/application.properties")
@Component
public class ApplicationPropertyHandler
{
    @Value("${http.port}")
    private String nonSecurePort;

    @Value("${https.port}" required=false)
    private String securePort;

    @Value("${server.servlet.context-path}")
    private String contextPath;

    @Value("${security.key}")
    private String securityKey;

Scenario 1: I got the below exception

org.springframework.beans.factory.BeanCreationException: Error creating bean with name ApplicationPropertyHandler': Injection of autowired dependencies failed; nested exception is java.lang.IllegalArgumentException: Could not resolve placeholder 'https.port' in value "${https.port}"

Is it possible to run the Scenario 1 without having field https.port in application.properties?

Manikandan
  • 1,195
  • 8
  • 26
arj
  • 887
  • 1
  • 15
  • 37
  • Try to replace your application.properties to resources, not to config folder – Nick Jan 09 '20 at 05:18
  • To Direct Answer, No It is not possible to read property without having it in application property. You must define key with or without value is your choice – Swarit Agarwal Jan 09 '20 at 06:07

5 Answers5

3

I think the real question is what do you do with that ApplicationPropertyHandler?

One possible solution is to not use values at all, it wasn't presented among answers so I add it here.

So, From your question:

  • you have spring boot
  • you maintain application.properties file with the configuration

But then you do all the mapping by yourself (mapping each property to value).

Instead of using @Value (which indeed has default that you can specify after colon ":" like many of our colleagues have stated) consider using the built-in spring boot feature:


@SpringBootAppplication
@EnableConfigurationProperties(MyConfigurationProperties.class)
public class Main {
   public static void main(String [] args){...}
}

@ConfigurationProperties 
public class MyConfigurationProperties {


   public static class Http {
       private int port = 8080; // getters/setters, 0 is a default
   }

   public static class Https {
       private int port = 0; // getters/setters, 0 is a default
   }

   ....
}

This allows:

  • debugging (you can place a breakpoint and see what actually comes to the property)
  • autocompletion when you edit the application.properties file in IDE (if you add a special dependency to the maven/gradle)
  • easily specifying defaults (without SPEL)
  • relaxed binding

In the last spring boot versions you can make this immutable at all but I don't know whether you're on the last version so its kind of beyond the scope of the answer.

Mark Bramnik
  • 39,963
  • 4
  • 57
  • 97
2

You can use null default @value as mentioned:

@Value("${https.port:#{null}}")
private String securePort;

Provided null securePort is injected in case it is absent.

Vishwa Ratna
  • 5,567
  • 5
  • 33
  • 55
Pramod S. Nikam
  • 4,271
  • 4
  • 38
  • 62
1

You can check: Spring @Value annotated method, use default value when properties not available

Or try one of the following:

1) @Value("${https.port:#{null}}")

2) @Value("${https.port:value-by-default-if-property-not-exist}")

First will inject null instead of String, second "value-by-default-if-property-not-exist".

P.S. Should work if your "application.properties" file is in /resources/config folder.

0
@Component
@PropertySource("config/application.properties")
@ConditionalOnProperty("https.port")
public class ApplicationPropertyHandler {

    @Value("${http.port}")
    private String nonSecurePort;

    @Value("${https.port}")
    private String securePort;

    @Value("${security.key}")
    private String securityKey;
}
Jaganath Kamble
  • 506
  • 2
  • 10
0

You may use below code - which will bind securePort variable with empty string if property is not found and if the property is found then the configured value is taken. In both cases the application startup will not be affected

@Value("${https.port:}")
private String securePort;