Loading velocity template inside a jar file

前端 未结 5 901
耶瑟儿~
耶瑟儿~ 2020-12-23 19:48

I have a project where I want to load a velocity template to complete it with parameters. The whole application is packaged as a jar file. What I initially thought of doing

相关标签:
5条回答
  • 2020-12-23 20:12

    Final code, developed using the ideas presented in both answers above:

    VelocityEngine ve = new VelocityEngine();
    ve.setProperty(RuntimeConstants.RESOURCE_LOADER, "classpath");
    ve.setProperty("classpath.resource.loader.class", ClasspathResourceLoader.class.getName());
    
    ve.init();
    
    final String templatePath = "templates/" + templateName + ".vm";
    InputStream input = this.getClass().getClassLoader().getResourceAsStream(templatePath);
    if (input == null) {
        throw new IOException("Template file doesn't exist");
    }
    
    InputStreamReader reader = new InputStreamReader(input);
    
    VelocityContext context = new VelocityContext();
    
    if (properties != null) {
        stringfyNulls(properties);
        for (Map.Entry<String, Object> property : properties.entrySet()) {
            context.put(property.getKey(), property.getValue());
        }
    }
    
    Template template = ve.getTemplate(templatePath, "UTF-8");
    String outFileName = File.createTempFile("report", ".html").getAbsolutePath();
    BufferedWriter writer = new BufferedWriter(new FileWriter(new File(outFileName)));
    
    if (!ve.evaluate(context, writer, templatePath, reader)) {
        throw new Exception("Failed to convert the template into html.");
    }
    
    template.merge(context, writer);
    
    writer.flush();
    writer.close();
    
    0 讨论(0)
  • 2020-12-23 20:12

    To make Velocity look for the templates in classpath:

    VelocityEngine ve = new VelocityEngine();
    ve.setProperty(RuntimeConstants.RESOURCE_LOADER, "classpath");
    ve.setProperty("classpath.resource.loader.class",ClasspathResourceLoader.class.getName());
    ve.init();
    
    0 讨论(0)
  • 2020-12-23 20:21

    Maybe I have an old version, this is the only thing that worked for me

    ve.setProperty(RuntimeConstants.RESOURCE_LOADER, "class"); 
    ve.setProperty("classpath.resource.loader.class", 
    ClasspathResourceLoader.class.getName());
    
    0 讨论(0)
  • 2020-12-23 20:30

    If you want to use resources from classpath, you should use resource loader for classpath:

    ve.setProperty(RuntimeConstants.RESOURCE_LOADER, "classpath"); 
    ve.setProperty("classpath.resource.loader.class", ClasspathResourceLoader.class.getName());
    
    0 讨论(0)
  • 2020-12-23 20:30

    Unless JAR is exploded, you can't read the resource in JAR as file. Use an input stream.

    See following code snippets,

        InputStream input = classLoader.getResourceAsStream(fileName);
        if (input == null) {
            throw new ConfigurationException("Template file " +
                    fileName + " doesn't exist");           
        }
    
        InputStreamReader reader = new InputStreamReader(input);            
            Writer writer = null;
    
            try {
                writer = new OutputStreamWriter(output);        
    
                // Merge template
                if (!engine.evaluate(context, writer, fileName, reader)) 
                    ......
    
    0 讨论(0)
提交回复
热议问题