0. Introduction
Although this is a "very academical" post, I don't like it as it is too verbose and difficult to understand. So I prefer using this approach to use properties.To show formatted text Hilite is used
Getting a property from a property file is rather simple in Java. But it is a very resource consuming practice to create a Properties class every time a property is read (and accessing a file).
So a good choice is to use a singleton instance.
To achieve this post, the help of these post have been greatly appreciated:
- Baeldung, Mykong. (For accessing property files)
- Ivo Woltring, Piotr Nowicki (For singletons)
A Singleton is very similar to an application scoped bean, so the second approach will be used. the use of Weld is very important as a context and dependency manager container.
The steps of this tutorial are:
Our file in "config/application.properties" in the src/main/resources folder is
To localize the path of the file the Config class is used.
To make this easier a xhtml file is supplied (beanprop.xhtml) in webapp folder
Let's run the project as a server application and point to http://localhost:8080/JSFv02/beanprop.jsf in the browser where:
- JSFv02 is the name of our project
- beanprop.jsf references to the beanprop.xhtml file in the webapp folder
Here is the result
The steps of this tutorial are:
- Create an Eclipse Maven project as the one created in the last post, or use it.
- Create an Interface to define an annotation of Property.
- Create the Producer (but Ivo and Piotr have distinguished the data type of property)
- Creating the property files (application.properties)
- Using in an example
Let's begin with the second step.
1. Creation of the Property Annotation (Interface)
Our code is:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | package org.ximodante.utils.property; import javax.enterprise.util.Nonbinding; import javax.inject.Qualifier; import java.lang.annotation.Retention; import java.lang.annotation.Target; import static java.lang.annotation.ElementType.FIELD; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.ElementType.PARAMETER; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; /** * Represents an property key to be injected */ @Qualifier @Retention(RUNTIME) @Target({TYPE, METHOD, FIELD, PARAMETER}) public @interface Property { @Nonbinding String value() default ""; @Nonbinding boolean required() default true; } |
Brief explanations:
@Retention (RUNTIME) for accessing during Runtime
@target indicates in which part of the code can be used
@Nonbinding: "If a member has this qualifier, it will not be used during type-safe resolution and its value will have no meaning". This is what says, Ken Finnegan
@Retention (RUNTIME) for accessing during Runtime
@target indicates in which part of the code can be used
@Nonbinding: "If a member has this qualifier, it will not be used during type-safe resolution and its value will have no meaning". This is what says, Ken Finnegan
2. The Producer class
Ivor and Piotr have made a "fine" producer, analyzing the property type. I cannot improve this class So a copy-paste is made, but some modifications are made:- @ApplicationScoped annotation for making it quite similar to a singleton.
- Some additional System.out.println sentences to see whether the property file is accessed and to evaluate how many times the property file is opened
- An additional class Config is accessed to know where is the property file. The file is in "config/application.properties" in the src/main/resources folder
- Should implement Serializable or else Weld complaints
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 | package org.ximodante.utils.property; import java.io.FileInputStream; import java.io.IOException; import java.io.Serializable; import java.util.Properties; import javax.annotation.PostConstruct; import javax.enterprise.context.ApplicationScoped; import javax.enterprise.inject.Produces; import javax.enterprise.inject.spi.InjectionPoint; import org.ximodante.jsf.config.Config; @ApplicationScoped public class PropertyProducer implements Serializable{ private static final long serialVersionUID = 1L; private Properties properties; @Property @Produces public String produceString(final InjectionPoint ip) { return this.properties.getProperty(getKey(ip)); } @Property @Produces public int produceInt(final InjectionPoint ip) { return Integer.valueOf(this.properties.getProperty(getKey(ip))); } @Property @Produces public boolean produceBoolean(final InjectionPoint ip) { return Boolean.valueOf(this.properties.getProperty(getKey(ip))); } private String getKey(final InjectionPoint ip) { return (ip.getAnnotated() .isAnnotationPresent(Property.class) && !ip.getAnnotated() .getAnnotation(Property.class) .value().isEmpty()) ? ip.getAnnotated() .getAnnotation(Property.class) .value() : ip.getMember() .getName(); } @PostConstruct public void init() { this.properties = new Properties(); String path = Thread.currentThread().getContextClassLoader().getResource("").getPath() + Config.getPropertyFile(); System.out.println("PROPERTIES.PATH=" + path); try { //this.properties.load(stream); this.properties.load(new FileInputStream(path)); } catch (final IOException e) { throw new RuntimeException("XXXXXXXX: Configuration could not be loaded!"); } } } |
3. The application.properties file
Our file in "config/application.properties" in the src/main/resources folder is1 2 3 4 | webEnvironment=true comment=This is a test commennt kk=Other property greet.first=Good Morning! |
To localize the path of the file the Config class is used.
1 2 3 4 5 6 7 8 9 10 | package org.ximodante.jsf.config; import lombok.Getter; public class Config { @Getter private static final String PropertyFile="config/application.properties"; } |
4. Using in a bean.
The source code for a simple bean is1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | package org.ximodante.utils.property; import java.io.Serializable; import javax.faces.view.ViewScoped; import javax.inject.Inject; import javax.inject.Named; import lombok.Getter; @Named @ViewScoped public class TestPropertyBean implements Serializable{ private static final long serialVersionUID = 1L; // the name of the attribute (greet1= does NOT match // the property name ("greet.fist") @Inject @Property("greet.first") @Getter private String greet1; // the name of the attribute (comment) DOES match // the property name so no attribute is passed to // the annotation @Property @Inject @Property @Getter private String comment; } |
To make this easier a xhtml file is supplied (beanprop.xhtml) in webapp folder
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | <html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core" xmlns:p="http://primefaces.org/ui"> <h:head> </h:head> <h:body> <h:form> <p:panel header="Keyboard Demo"> <p:keyboard value="#{testPropertyBean.comment}"/> <p:keyboard value="#{testPropertyBean.greet1}"/> </p:panel> <p:commandButton value="Submit"/> </h:form> </h:body> </html> |
Let's run the project as a server application and point to http://localhost:8080/JSFv02/beanprop.jsf in the browser where:
- JSFv02 is the name of our project
- beanprop.jsf references to the beanprop.xhtml file in the webapp folder
Here is the result
No hay comentarios:
Publicar un comentario