Java API for the Play Framework providing web application development capabilities including form handling, validation, dependency injection, and utility libraries
—
Play Framework provides a comprehensive collection of utility libraries for common web development tasks including cryptographic operations, time parsing, XML/YAML processing, classpath scanning, and content type handling. These utilities are designed for high-performance web applications with security and ease of use in mind.
Comprehensive cryptographic operations including signing, token generation, and AES encryption with application-level key management.
/**
* Cryptographic utilities for signing, encryption, and secure token generation
*/
public class Crypto {
/** Sign message with provided key */
public String sign(String message, byte[] key);
/** Sign message with application secret key */
public String sign(String message);
/** Sign token with timestamp nonce for replay protection */
public String signToken(String token);
/** Extract and verify signed token */
public String extractSignedToken(String token);
/** Generate cryptographically secure random token */
public String generateToken();
/** Generate signed secure token */
public String generateSignedToken();
/** Compare signed tokens in constant time */
public boolean compareSignedTokens(String tokenA, String tokenB);
/** Constant time string comparison to prevent timing attacks */
public boolean constantTimeEquals(String a, String b);
/** AES encrypt with application secret key */
public String encryptAES(String value);
/** AES encrypt with specific private key */
public String encryptAES(String value, String privateKey);
/** AES decrypt with application secret key */
public String decryptAES(String value);
/** AES decrypt with specific private key */
public String decryptAES(String value, String privateKey);
}Usage Examples:
import play.libs.Crypto;
// Token generation and signing
public class AuthService {
public String createSessionToken(String userId) {
String token = Crypto.generateToken();
String signedToken = Crypto.signToken(userId + ":" + token);
return signedToken;
}
public String validateSessionToken(String signedToken) {
try {
String extracted = Crypto.extractSignedToken(signedToken);
String[] parts = extracted.split(":");
return parts[0]; // Return userId
} catch (Exception e) {
return null; // Invalid token
}
}
public String encryptSensitiveData(String data) {
return Crypto.encryptAES(data);
}
public String decryptSensitiveData(String encryptedData) {
return Crypto.decryptAES(encryptedData);
}
}
// CSRF protection
public class CSRFService {
public String generateCSRFToken() {
return Crypto.generateSignedToken();
}
public boolean validateCSRFToken(String token, String expected) {
return Crypto.compareSignedTokens(token, expected);
}
}Comprehensive time parsing utilities including duration parsing and CRON expression handling for scheduling and time-based operations.
/**
* Time utilities for duration parsing and CRON expression handling
*/
public class Time {
/** Parse duration string to seconds (e.g., "3h", "2mn", "45s") */
public static int parseDuration(String duration);
/** Parse CRON expression to next execution date */
public static Date parseCRONExpression(String cron);
/** Get interval in milliseconds to next CRON execution */
public static long cronInterval(String cron);
/** Get interval in milliseconds to next CRON execution from specific date */
public static long cronInterval(String cron, Date date);
}
/**
* CRON expression parser and evaluator with timezone support
*/
public static class Time.CronExpression implements Serializable, Cloneable {
/** Create CRON expression from string */
public CronExpression(String cronExpression) throws ParseException;
/** Check if date satisfies CRON expression */
public boolean isSatisfiedBy(Date date);
/** Get next valid execution time after given date */
public Date getNextValidTimeAfter(Date date);
/** Get next invalid time after given date */
public Date getNextInvalidTimeAfter(Date date);
/** Get interval in milliseconds to next occurrence */
public long getNextInterval(Date date);
/** Get timezone for this expression */
public TimeZone getTimeZone();
/** Set timezone for this expression */
public void setTimeZone(TimeZone timeZone);
/** Validate CRON expression string */
public static boolean isValidExpression(String cronExpression);
}Usage Examples:
import play.libs.Time;
import play.libs.Time.CronExpression;
// Duration parsing
public class SchedulingService {
public void scheduleTask(String durationStr, Runnable task) {
int seconds = Time.parseDuration(durationStr);
scheduler.schedule(task, seconds, TimeUnit.SECONDS);
// Examples:
// "1h" -> 3600 seconds
// "30mn" -> 1800 seconds
// "45s" -> 45 seconds
// "2d" -> 172800 seconds
}
}
// CRON expression handling
public class CronScheduler {
public void scheduleJob(String cronExpression, Runnable job) {
try {
CronExpression cron = new CronExpression(cronExpression);
// Schedule next execution
Date nextRun = cron.getNextValidTimeAfter(new Date());
long delay = nextRun.getTime() - System.currentTimeMillis();
scheduler.schedule(() -> {
job.run();
// Reschedule for next occurrence
scheduleJob(cronExpression, job);
}, delay, TimeUnit.MILLISECONDS);
} catch (ParseException e) {
Logger.error("Invalid CRON expression: " + cronExpression, e);
}
}
public boolean isValidCron(String expression) {
return CronExpression.isValidExpression(expression);
}
}
// Examples of CRON expressions:
// "0 0 12 * * ?" -> Daily at noon
// "0 15 10 ? * MON-FRI" -> Weekdays at 10:15 AM
// "0 0/5 * * * ?" -> Every 5 minutesXPath-based XML processing utilities with namespace support for parsing and extracting data from XML documents.
/**
* XPath parsing utilities with namespace support
*/
public class XPath {
/** Select multiple nodes using XPath with namespaces */
public static NodeList selectNodes(String path, Object node, Map<String, String> namespaces);
/** Select multiple nodes using XPath without namespaces */
public static NodeList selectNodes(String path, Object node);
/** Select single node using XPath with namespaces */
public static Node selectNode(String path, Object node, Map<String, String> namespaces);
/** Select single node using XPath without namespaces */
public static Node selectNode(String path, Object node);
/** Get text content using XPath with namespaces */
public static String selectText(String path, Object node, Map<String, String> namespaces);
/** Get text content using XPath without namespaces */
public static String selectText(String path, Object node);
}Usage Examples:
import play.libs.XPath;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
// XML parsing service
public class XMLService {
public List<String> extractUserNames(Document xmlDoc) {
NodeList userNodes = XPath.selectNodes("//user/name", xmlDoc);
List<String> names = new ArrayList<>();
for (int i = 0; i < userNodes.getLength(); i++) {
names.add(userNodes.item(i).getTextContent());
}
return names;
}
public String extractConfigValue(Document config, String key) {
String xpath = "//config/setting[@name='" + key + "']/@value";
return XPath.selectText(xpath, config);
}
public Map<String, String> extractNamespacedData(Document xmlDoc) {
Map<String, String> namespaces = new HashMap<>();
namespaces.put("ns", "http://example.com/namespace");
NodeList items = XPath.selectNodes("//ns:item", xmlDoc, namespaces);
Map<String, String> data = new HashMap<>();
for (int i = 0; i < items.getLength(); i++) {
Node item = items.item(i);
String id = XPath.selectText("@id", item);
String value = XPath.selectText("ns:value", item, namespaces);
data.put(id, value);
}
return data;
}
}YAML parsing utilities for configuration files and data serialization with classpath resource support.
/**
* YAML parsing utilities for configuration and data files
*/
public class Yaml {
/** Load YAML from classpath resource */
public static Object load(String resourceName);
/** Load YAML from input stream with specific classloader */
public static Object load(InputStream is, ClassLoader classloader);
}Usage Examples:
import play.libs.Yaml;
// Configuration loading
public class ConfigService {
@SuppressWarnings("unchecked")
public Map<String, Object> loadConfig(String configFile) {
Object config = Yaml.load(configFile);
if (config instanceof Map) {
return (Map<String, Object>) config;
}
throw new IllegalArgumentException("Config file is not a valid YAML map");
}
public DatabaseConfig loadDatabaseConfig() {
Map<String, Object> config = loadConfig("database.yml");
return new DatabaseConfig(
(String) config.get("url"),
(String) config.get("username"),
(String) config.get("password")
);
}
}
// Test data loading
public class TestDataLoader {
@SuppressWarnings("unchecked")
public List<User> loadTestUsers() {
Object data = Yaml.load("test-users.yml");
List<Map<String, Object>> userMaps = (List<Map<String, Object>>) data;
return userMaps.stream()
.map(this::mapToUser)
.collect(Collectors.toList());
}
private User mapToUser(Map<String, Object> userMap) {
User user = new User();
user.name = (String) userMap.get("name");
user.email = (String) userMap.get("email");
user.age = (Integer) userMap.get("age");
return user;
}
}Comprehensive classpath scanning utilities for type discovery and annotation-based component scanning.
/**
* Classpath scanning utilities for type discovery and reflection
*/
public class Classpath {
/** Scan types in package using Application context */
public static Set<String> getTypes(Application app, String packageName);
/** Find types annotated with specific annotation using Application */
public static Set<Class<?>> getTypesAnnotatedWith(Application app, String packageName, Class<? extends Annotation> annotation);
/** Scan types in package using Environment */
public static Set<String> getTypes(Environment env, String packageName);
/** Find types annotated with specific annotation using Environment */
public static Set<Class<?>> getTypesAnnotatedWith(Environment env, String packageName, Class<? extends Annotation> annotation);
/** Create Reflections configuration for package scanning */
public static ConfigurationBuilder getReflectionsConfiguration(String packageName, ClassLoader classLoader);
}Usage Examples:
import play.libs.Classpath;
import play.Application;
// Component scanning service
public class ComponentScanner {
public Set<Class<?>> findControllers(Application app) {
return Classpath.getTypesAnnotatedWith(app, "controllers", Controller.class);
}
public Set<Class<?>> findServices(Application app) {
return Classpath.getTypesAnnotatedWith(app, "services", Service.class);
}
public Set<Class<?>> findRepositories(Application app) {
return Classpath.getTypesAnnotatedWith(app, "repositories", Repository.class);
}
}
// Auto-registration service
public class AutoRegistrationService {
public void autoRegisterComponents(Application app, Injector injector) {
// Find all classes annotated with @Component
Set<Class<?>> components = Classpath.getTypesAnnotatedWith(
app, "com.myapp", Component.class);
for (Class<?> componentClass : components) {
try {
Object instance = injector.getInstance(componentClass);
// Register component in some registry
componentRegistry.register(componentClass, instance);
} catch (Exception e) {
Logger.warn("Failed to register component: " + componentClass, e);
}
}
}
}
// Plugin discovery
public class PluginDiscovery {
public List<Plugin> discoverPlugins(Application app) {
Set<Class<?>> pluginClasses = Classpath.getTypesAnnotatedWith(
app, "plugins", PluginMarker.class);
return pluginClasses.stream()
.filter(Plugin.class::isAssignableFrom)
.map(clazz -> {
try {
return (Plugin) clazz.newInstance();
} catch (Exception e) {
Logger.error("Failed to instantiate plugin: " + clazz, e);
return null;
}
})
.filter(Objects::nonNull)
.collect(Collectors.toList());
}
}JSONP content rendering utilities for cross-domain JavaScript communication.
/**
* JSONP content renderer for cross-domain JavaScript responses
*/
public class Jsonp implements Content {
/** Create JSONP response with callback and JSON data */
public Jsonp(String padding, JsonNode json);
/** Get response body */
public String body();
/** Get content type */
public String contentType();
/** Create JSONP content with callback function */
public static Jsonp jsonp(String padding, JsonNode json);
}Usage Examples:
import play.libs.Jsonp;
import play.libs.Json;
// JSONP API controller
public class JsonpController extends Controller {
public Result getUsersJsonp(String callback) {
List<User> users = userService.getAllUsers();
JsonNode usersJson = Json.toJson(users);
// Create JSONP response
Jsonp jsonpContent = Jsonp.jsonp(callback, usersJson);
return ok(jsonpContent);
}
public Result getDataJsonp() {
String callback = request().getQueryString("callback");
if (callback == null) {
callback = "callback"; // Default callback name
}
Map<String, Object> data = new HashMap<>();
data.put("status", "success");
data.put("timestamp", new Date());
data.put("data", getData());
JsonNode dataJson = Json.toJson(data);
return ok(Jsonp.jsonp(callback, dataJson));
}
}// Comprehensive token service
public class TokenService {
private static final long TOKEN_VALIDITY = 3600000; // 1 hour
public String createAccessToken(String userId) {
long expiry = System.currentTimeMillis() + TOKEN_VALIDITY;
String tokenData = userId + ":" + expiry;
return Crypto.signToken(Base64.getEncoder().encodeToString(tokenData.getBytes()));
}
public String validateAccessToken(String token) {
try {
String extracted = Crypto.extractSignedToken(token);
String tokenData = new String(Base64.getDecoder().decode(extracted));
String[] parts = tokenData.split(":");
String userId = parts[0];
long expiry = Long.parseLong(parts[1]);
if (System.currentTimeMillis() > expiry) {
return null; // Token expired
}
return userId;
} catch (Exception e) {
return null; // Invalid token
}
}
public String createRefreshToken(String userId) {
String tokenData = userId + ":" + Crypto.generateToken();
return Crypto.encryptAES(tokenData);
}
public String validateRefreshToken(String refreshToken) {
try {
String decrypted = Crypto.decryptAES(refreshToken);
String[] parts = decrypted.split(":");
return parts[0]; // Return userId
} catch (Exception e) {
return null; // Invalid refresh token
}
}
}// Advanced configuration service using multiple sources
public class ConfigurationManager {
private final Map<String, Object> configuration = new HashMap<>();
public ConfigurationManager() {
loadFromYaml();
loadFromEnvironment();
loadFromSystemProperties();
}
private void loadFromYaml() {
try {
Object yamlConfig = Yaml.load("application.yml");
if (yamlConfig instanceof Map) {
configuration.putAll((Map<String, Object>) yamlConfig);
}
} catch (Exception e) {
Logger.warn("Failed to load YAML configuration", e);
}
}
private void loadFromEnvironment() {
System.getenv().forEach((key, value) -> {
if (key.startsWith("APP_")) {
String configKey = key.toLowerCase().replace("app_", "").replace("_", ".");
configuration.put(configKey, value);
}
});
}
private void loadFromSystemProperties() {
System.getProperties().forEach((key, value) -> {
if (key.toString().startsWith("app.")) {
configuration.put(key.toString(), value);
}
});
}
public String getString(String key, String defaultValue) {
return (String) configuration.getOrDefault(key, defaultValue);
}
public Integer getInt(String key, Integer defaultValue) {
Object value = configuration.get(key);
if (value instanceof String) {
return Integer.parseInt((String) value);
}
return value instanceof Integer ? (Integer) value : defaultValue;
}
}Install with Tessl CLI
npx tessl i tessl/maven-com-typesafe-play--play-java