Building a URL Validation Service with Spring Boot and Regex Patterns
URLs travel through almost every modern application, from link shorteners used in Sydney marketing campaigns to internal tools running inside Melbourne-based banks. A reliable validation layer prevents malformed addresses from reaching downstream services, protects databases from garbage data, and keeps analytics clean. Building such a service in Java gives you type safety, predictable performance, and a familiar ecosystem of libraries.
Spring Boot is a natural fit because it bundles a self-contained HTTP server, dependency injection, and configuration management in a single starter. When paired with carefully crafted regular expressions, the result is a small, fast microservice that other platforms can call over REST. Throughout this walkthrough, the code targets Java 17 and Spring Boot 3.x, the versions most teams in Brisbane and Perth are standardising on this year.
Why URL Validation Matters in Modern APIs
A URL is more than a string. It carries a scheme, an authority, a path, optional query parameters, and fragments, and each part must follow well-defined grammar rules. Accepting raw input without checks lets attackers smuggle in javascript: links, file:// references, or oversized strings that crash parsers downstream. For Australian businesses operating under the Notifiable Data Breaches scheme, weak input handling can become a reportable incident when it leads to phishing or credential theft.
A dedicated validation endpoint also makes life easier for frontend teams in Adelaide or on the Gold Coast who do not want to duplicate regex logic across React and Angular codebases. By centralising the rules, organisations align with the Australian Cyber Security Centre's guidance on input validation as part of the Essential Eight mitigation strategies.
Setting Up the Spring Boot Project
Open Spring Initializr and choose Maven, Java 17, and the latest stable Spring Boot release. Add the Spring Web starter, which brings in Tomcat and Jackson, and optionally Lombok to keep boilerplate down. Once generated, import the project into IntelliJ IDEA or VS Code, the two editors dominating Australian development teams.
The application class only needs the standard @SpringBootApplication annotation. Add a server.port entry to application.properties if you intend to run the service on something other than 8080, for example when integrating with existing CI pipelines in Canberra or Hobart. A simple context path such as /api/v1 keeps URLs tidy when the service sits behind a reverse proxy.
Designing the Validation API Contract
A clean contract makes the service easy to consume. Expose a POST endpoint that accepts a JSON body containing one or more URLs, returning a structured response with per-entry status, error code, and optional reason. Returning HTTP 200 even for invalid entries is common because validation results are business data, not transport errors. Use ISO 8601 timestamps in AEST or AEDT so logs read naturally for on-call engineers monitoring from Sydney.
Document the contract with springdoc-openapi so it shows up in Swagger UI. This step is appreciated by integrators in Perth who often work across multiple time zones and value self-service documentation. Add request size limits to protect against denial-of-service attempts, a sensible default being one kilobyte per URL and fifty URLs per request.
Building the Regex Validation Engine
The core of the service is a regex tuned for the URLs you actually expect. Start with a pattern that recognises http and https schemes, optional www prefixes, subdomains, paths, and query strings. Keep the expression readable by compiling it once as a static Pattern and reusing it across threads. Java's Pattern class is thread-safe once compiled, which keeps the implementation lean.
For stricter requirements, maintain separate patterns: a relaxed one for general web links and a strict one that enforces a specific TLD list, including the Australian .au and .com.au namespaces. Whitelisting the .au domain matters for organisations that only accept local sources, such as government departments checking .gov.au references. Compile each pattern with Pattern.CASE_INSENSITIVE where appropriate and always anchor the match with ^ and $ to avoid partial matches.
Handling Edge Cases and Error Responses
Real traffic contains surprises. URLs may contain percent-encoded characters, IDN domains, or trailing punctuation copied from chat messages. Decide whether to reject or normalise these cases and encode the policy in your service. Return structured errors using an enum such as INVALID_SCHEME, MALFORMED_HOST, or EXCESSIVE_LENGTH so consumers can branch intelligently.
Log validation failures at INFO level with a correlation ID so security teams in Melbourne can trace abusive sources. Avoid logging the full URL when it might contain sensitive tokens or session identifiers. Apply the Australian Privacy Principles by stripping query parameters from logs whenever they could carry personal information.
Testing the Validation Endpoint
Write unit tests with JUnit 5 covering the regex directly, including valid Australian domains, malicious javascript: payloads, and empty strings. Add a slice test using @WebMvcTest to confirm the controller returns the expected JSON shape. For integration confidence, spin up Testcontainers with a small WireMock instance and exercise the endpoint with realistic traffic captured from production logs.
Run the suite through GitHub Actions or GitLab CI, both of which have data centres serving Australian developers with low latency. Aim for at least ninety percent line coverage on the validator package, and gate merges on it. A failing test should block deployment.
Deploying to an Australian Cloud Region
Choose a region close to your users. The AWS Asia Pacific (Sydney) region, coded ap-southeast-2, hosts many SaaS products aimed at the Australian market. Google Cloud's australia-southeast1 in Sydney and Microsoft's Australia East in Sydney are equally solid. Pair the deployment with a managed PostgreSQL instance when persistence is needed.
Containerise the service with a slim JRE base image, push it to a registry, and configure autoscaling for business hours in AEST. Enable health checks so orchestrators can recycle unhealthy instances, and ship logs to a central aggregator where your security operations centre, often based in Canberra or Sydney, can monitor them.
Practical Recommendations for a Production-Ready Validator
- Compile patterns once and reuse them, never recompile per request
- Return structured error codes instead of plain strings to aid client logic
- Apply request size limits and rate limiting before the validation step
- Log with correlation IDs and strip sensitive query parameters
- Keep validation rules in configuration so they can change without redeploys
- Test with malicious payloads alongside happy-path examples