Properties Files
Properties files store key-value pairs, with keys being unique. They typically use the .properties extension.
Reading Properties Files
import java.io.FileReader;
import java.util.Properties;
import java.util.Set;
public class PropertiesReader {
public static void main(String[] args) throws Exception {
Properties props = new Properties();
System.out.println("Initial properties: " + props);
// Load properties from a file
props.load(new FileReader("path/to/users.properties"));
System.out.println("Properties after loading: " + props);
// Retrieve a value by key
System.out.println("Value for 'username': " + props.getProperty("username"));
// Iterate through all keys and values
Set<String> keys = props.stringPropertyNames();
for (String key : keys) {
System.out.println(key + ": " + props.getProperty(key));
}
// Using lambda for iteration
props.forEach((key, value) -> System.out.println(key + " --> " + value));
}
}
Writing Properties Files
import java.io.FileWriter;
import java.io.IOException;
import java.util.Properties;
public class PropertiesWriter {
public static void main(String[] args) throws IOException {
Properties props = new Properties();
props.setProperty("database.url", "jdbc:mysql://localhost:3306/mydb");
props.setProperty("database.user", "admin");
props.setProperty("database.password", "secret123");
// Store properties to a file with a comment
try (FileWriter writer = new FileWriter("path/to/config.properties")) {
props.store(writer, "Application Configuration");
}
System.out.println("Properties written to config.properties");
}
}
Extensible Markup Language (XML)
XML is a markup language using tags, which can be user-defined. It enforces a single root element and allows elements to have attributes. Files containing XML data typically have a .xml extension.
Syntax Rules
Special characters like <, &, ', and " must be escaped using predefined entities:
<for<>for>&for&'for'"for"
CDATA sections (<![CDATA[...content...]]>) allow including raw character data without escaping:
<data>
<![CDATA[
This is some raw text containing < and & symbols.
5 > 2 is true.
]]>
</data>
Reading XML with DOM4J
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import java.util.List;
public class Dom4jReader {
public static void main(String[] args) throws Exception {
SAXReader saxReader = new SAXReader();
Document document = saxReader.read("path/to/data.xml");
Element root = document.getRootElement();
System.out.println("Root element: " + root.getName());
// Get all direct children named 'item'
List<Element> items = root.elements("item");
for (Element item : items) {
System.out.println("Item Name: " + item.getName());
// Get a specific sub-element's text content
System.out.println(" Sub-item name: " + item.elementText("subName"));
// Get an attribute
Attribute idAttribute = item.attribute("id");
if (idAttribute != null) {
System.out.println(" Attribute 'id': " + idAttribute.getValue());
}
// Get all text content within the element, trimming whitespace
Element details = item.element("details");
if (details != null) {
System.out.println(" Details (trimmed): " + details.getTextTrim());
}
}
}
}
Writing XML
Generating XML programmatically often involves string manipulation and I/O operations.
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
public class XmlWriter {
public static void main(String[] args) {
StringBuilder xmlContent = new StringBuilder();
xmlContent.append("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n");
xmlContent.append("<catalog>\n");
xmlContent.append(" <book id=\"bk101\">\n");
xmlContent.append(" <title>The Lord of the Rings</title>\n");
xmlContent.append(" </book>\n");
xmlContent.append("</catalog>\n");
try (BufferedWriter writer = new BufferedWriter(new FileWriter("path/to/catalog.xml"))) {
writer.write(xmlContent.toString());
System.out.println("XML file 'catalog.xml' created successfully.");
} catch (IOException e) {
System.err.println("Error writing XML file: " + e.getMessage());
throw new RuntimeException(e);
}
}
}
XML Constraints
XML documents can be constrained using Document Type Definitions (DTD) or XML Schema (XSD) to enforce structure and data types.
Logging
Logging systems record application execution information to various destinations like the console, files, or databases. They allow enabling or disabling logging without modifying source code.
Logback Configuration
Logback is a popular logging framework. It requires slf4j-api, logback-core, and logback-classic libraries. The logback.xml configuraton file should be placed in the src directory.
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class LogbackExample {
// Logger instance for this class
private static final Logger logger = LoggerFactory.getLogger(LogbackExample.class);
public static void main(String[] args) {
try {
logger.info("Starting main method...");
performDivision(10, 0);
logger.info("Division completed successfully.");
} catch (ArithmeticException e) {
logger.error("An arithmetic error occurred during division.", e);
} catch (Exception e) {
logger.error("An unexpected error occurred.", e);
}
}
public static void performDivision(int numerator, int denominator) {
logger.debug("Attempting to divide {} by {}", numerator, denominator);
int result = numerator / denominator;
System.out.println("Result: " + result);
logger.debug("Division result: {}", result);
}
}
logback.xml Example
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!-- Console Appender -->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<target>System.out</target>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<!-- Rolling File Appender -->
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
<charset>utf-8</charset>
</encoder>
<file>logs/application.log</file> <!-- Log file path -->
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>logs/archive/app-%i-%d{yyyy-MM-dd}.log.gz</fileNamePattern>
<maxFileSize>10MB</maxFileSize> <!-- Max file size before rolling -->
</rollingPolicy>
</appender>
<!-- Root Logger Configuration -->
<root level="ALL">
<appender-ref ref="CONSOLE" />
<appender-ref ref="FILE" />
</root>
</configuration>
Log Levels
Log levels control the verbosity of logging, ordered from least to most severe:
| Level | Description |
|---|---|
| TRACE | Detailed trace information about program execution. |
| DEBUG | Debugging information, typically used during development. |
| INFO | Inforrmational messages about significant events. |
| WARN | Warning messages indicating potential issues. |
| ERROR | Error messages indicating critical failures. |
The level attribute in the configuration (e.g., level="INFO") determines which messages are logged. Messages with a level equal to or higher than the configured level will be processed.