Java: Elegant Sitemap Generation Using 4 Design Patterns and the Open/Closed Principle

This article demonstrates how to generate website sitemap.xml files in Java by combining four design patterns—Strategy, Factory, Template Method, and Builder—along with the Open/Closed Principle, providing extensible, maintainable code illustrated with enums, configuration classes, and concrete implementations.

Ubiquitous Tech
Ubiquitous Tech
Ubiquitous Tech
Java: Elegant Sitemap Generation Using 4 Design Patterns and the Open/Closed Principle

Sitemap.xml is a file that lists almost all URLs of a website so that search‑engine spiders can crawl the site efficiently. Because a single sitemap file cannot contain more than 50,000 URLs, large sites need a sitemapindex that references multiple child sitemap files.

Enum for Sitemap Types

An enum WebSiteMapBizEnums is introduced to hold the basic information of each sitemap file (main, sku, activity, blog). The enum provides a numeric key, the file name, and a grouping string.

public enum WebSiteMapBizEnums {
    MAIN_SITEMAP(1, "main_sitemap.xml", "main"),
    SKU_SITEMAP(2, "sku_sitemap.xml", "sku"),
    ACTIVITY_SITEMAP(3, "activity_sitemap.xml", "activity"),
    BLOG_SITEMAP(4, "blog_sitemap.xml", "blog");
    private final Integer key;
    private final String fileName;
    private String group;
    WebSiteMapBizEnums(Integer key, String fileName, String group) {
        this.key = key;
        this.fileName = fileName;
        this.group = group;
    }
    public Integer getKey() { return key; }
    public String getFileName() { return fileName; }
    public String getGroup() { return group; }
}

Configuration Properties

A WebSitemapProperties class (bound to the sitemap prefix) stores the output directory and domain name, which are later used by the generator.

@ConfigurationProperties("sitemap")
@Data
public class WebSitemapProperties {
    private String fileDir;
    private String domain;
}

Strategy Pattern

A WebSiteMapLocationStrategy interface defines two methods: getEnumType() to identify the sitemap type and executeBuild() to perform the generation. A concrete MainLocationStrategy shows a typical implementation that queries data, builds URL objects, and writes them to the corresponding file.

public interface WebSiteMapLocationStrategy {
    WebSiteMapBizEnums getEnumType();
    void executeBuild(WebSitemapProperties sitemapProperties);
}

public class MainLocationStrategy implements WebSiteMapLocationStrategy {
    @Override
    public WebSiteMapBizEnums getEnumType() { return WebSiteMapBizEnums.MAIN_SITEMAP; }
    @Override
    public void executeBuild(WebSitemapProperties sitemapProperties) {
        // 1. query DB
        // 2. build URL objects
        // 3. write to sitemap.xml
    }
}

The article lists four ways to register strategies: manual map registration, Java SPI / spring.factories, Spring IOC bean lookup, and reflection. The author adopts the Spring IOC approach, annotating each strategy with @Service and letting the container manage them.

Factory + Open/Closed Principle

A factory class WebSitemapFactory loads all WebSiteMapLocationStrategy beans from the Spring context and stores them in a static map keyed by the enum's numeric key. New sitemap types can be added by creating a new strategy class; no factory code needs to change, satisfying the Open/Closed Principle.

public class WebSitemapFactory {
    private static Map<Integer,WebSiteMapLocationStrategy> registerMap = new HashMap<>();
    public static void initLoad() {
        Map<String, WebSiteMapLocationStrategy> beanMap = SpringContextUtil.getContext().getBeansOfType(WebSiteMapLocationStrategy.class);
        for (WebSiteMapLocationStrategy s : beanMap.values()) {
            registerMap.put(s.getEnumType().getKey(), s);
        }
    }
    public static WebSiteMapLocationStrategy getSiteMapLocationStrategy(Integer key) {
        return registerMap.get(key);
    }
}

Template Method Pattern

An abstract class AbstractLocationStrategy implements the common workflow: pre‑processing, building the WebSitemapGenerator, writing the file, and post‑processing. Subclasses only need to implement doWebSitemapGeneratorBuild() to provide business‑specific data.

public abstract class AbstractLocationStrategy implements WebSiteMapLocationStrategy {
    @Override
    public void executeBuild(WebSitemapProperties props) {
        try {
            processBefore();
            WebSitemapGenerator gen = doWebSitemapGeneratorBuild(props);
            writeData(gen);
            processAfter();
        } catch (Exception e) { e.printStackTrace(); }
    }
    protected abstract WebSitemapGenerator doWebSitemapGeneratorBuild(WebSitemapProperties props) throws Exception;
    private void writeData(WebSitemapGenerator gen) { gen.write(); }
    protected void processBefore() {}
    private void processAfter() {}
}

Builder Pattern via sitemapgen4j

The third‑party library sitemapgen4j (version 1.1.2) provides a builder for WebSitemapGenerator. The builder is used in the concrete strategy to set the domain, output directory, date format, and file‑name prefix.

WebSitemapGenerator generator = WebSitemapGenerator.builder(sitemapProperties.getDomain(), new File(sitemapProperties.getFileDir()))
    .dateFormat(new W3CDateFormat(W3CDateFormat.Pattern.DAY))
    .fileNamePrefix(getEnumType().getFileName())
    .build();

Inside the concrete ArticleLocationStrategy, the author demonstrates querying dummy data, constructing URLs with WebSitemapUrl, and adding them to the generator.

for (Object article : dataList) {
    String url = prefix + "articleId.html";
    WebSitemapUrl.Options opt = new WebSitemapUrl.Options(url);
    opt.lastMod(new Date());
    WebSitemapUrl sitemapUrl = opt.changeFreq(ChangeFreq.DAILY).priority(0.9).build();
    websiteMapGen.addUrl(sitemapUrl);
}

Client Invocation

The main class loads the factory, creates a WebSitemapProperties instance, iterates over all enum values, retrieves the corresponding strategy from the factory, and executes the build.

public class TestBiz {
    public static void main(String[] args) {
        WebSitemapFactory.initLoad();
        WebSitemapProperties props = new WebSitemapProperties();
        for (WebSiteMapBizEnums biz : WebSiteMapBizEnums.values()) {
            WebSiteMapLocationStrategy strategy = WebSitemapFactory.getSiteMapLocationStrategy(biz.getKey());
            if (strategy != null) {
                strategy.executeBuild(props);
            }
        }
    }
}

Conclusion

By layering Strategy, Factory, Template Method, and Builder patterns together, the sitemap generation code becomes highly extensible and adheres to the Open/Closed Principle. Adding a new business type only requires a new strategy implementation, while the surrounding infrastructure remains unchanged—an approach that Java engineers can showcase in interviews and apply to similar code‑generation tasks.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Design PatternsJavaStrategy PatternFactory Patterntemplate methodOpen-Closed PrincipleSitemap
Ubiquitous Tech
Written by

Ubiquitous Tech

A ubiquitous public account for pirate enthusiasts, regularly sharing curated experiences, tech learning, and growth insights. Currently publishing articles on AI RAG customer service, AI MCP technology, and open-source design. Personal free Knowledge Planet: Awakening New World Programmer.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.