Spark Framework and relative path - java

I'm using the Spark framework to create a web app and I've been going through the tutorials on their site. At the moment, I'm working on their templates section, however I can't seem to get the project to recognize that my css and my templates are in my resources folder.
I'm using Netbeans and Maven to manage my dependencies.
Can anyone help me figure out how to set up my relative paths/create my project folders appropriately in this environment? I'm a newbie to both Maven and Spark, so go easy please.

Static Files:
If your resources directory looked like this:
resources
└───public
├───css
│ style.css
├───html
│ hello.html
└───templates
template.ftl
You could use staticFiles.location("/public"). This would make /public the root staticFiles directory.
You could then access hello.html like this: http://{host}:{port}/html/hello.html
If you wanted to use an external location on the filesystem, you could use staticFiles.externalLocation(...), which works pretty much the same way above.
Note: staticFiles.externalLocation(...) can be set to your project's resources directory, which means that the files will be automatically refreshed (useful for development)
A more in depth explanation can be found in the spark documentation
Configuring your template engine:
If you have already set the staticFiles location, but spark is still having trouble finding your templates, try this.
Note: These examples are for the FreeMarker engine, though they should apply to other engines with minor tweaking.
After looking through the examples, it seems that by default, a new FreemarkerEngine() looks for templates in spark/template/freemarker, and not your staticFiles location.
You have two options:
1: Move all of your templates to that directory
or
2: Configure your own engine, and pass it instead when defining routes
FreeMarkerEngine freemarker = new FreeMarkerEngine();
Configuration config = new Configuration();
config.setTemplateLoader(
new ClassTemplateLoader(YOUR_CLASS.class, "/templatedir"));
freemarker.setConfiguration(config);

Related

What's Thymeleaf "prefix" relative to?

I'm just starting using Thymeleaf and I'm trying to understand the setPrefix() method in the template resolver. There are cases that I understand, like setPrefix("classpath:/com/package") or setPrefix("file:folder") (relative to working directory).
But I still don't understand what, for example, setPrefix("/views/") refers to. Where Thymeleaf expects the views folder to be? Does the / at the beginning means that is an absolute path? If so, where's the 'root'?
Does it depends of the specific TemplateResolver? In my instance, I'm using the SpringResourceTemplateResolver.
If you are using SpringResourceTemplateResolver, the prefix is relative to the root of the war file (or the web-app base directory when unpacked).
When using Maven as build system, the source folder for this is src/main/webapp. For example, if you setPrefix("/views/") your templates should be put in src/main/webapp/views/.
Hint: Use WEB-INF directory to protect from end-users retrieving the templates directly.

Where to put static files for Spark Web Framework?

Where do I put files when trying to serve static files with the Spark web framework?
I haven't been able to find anything online - I'm beginning to suspect I don't understand anything about class paths, relative paths etc. for an Eclipse and Java project.
This paragraph about static files in Spark refers to /public, but I have no idea where that would be. Using windows, Eclipse Luna and my project is converted to use Maven.
I've tried looking at the code on GitHub, but I'm a little out of my depth trying to find it.
First you have to tell Spark where to search for the static files like this:
Spark.staticFiles.location("/public");
In Spark versions prior to 2.5, you should use:
Spark.staticFileLocation("/public");
Then your project should have a public folder under the resources folder like this
/src/main/resources/public/style.css
For example I added a style.css file there, so you should then access it like this:
http://localhost:4567/style.css
If you want to serve a non-classpath folder, then you should use
Spark.staticFiles.externalLocation("/path/to/dir");
In Spark versions prior to 2.5, you should use:
Spark.externalStaticFileLocation("/path/to/dir");
I put my style sheets below my static content as follows:
staticFileLocation( "/web" );
/web/
|-- index.html
+-- styles/
+
+--- default.css
And the index.html
... <link href="styles/default.css" rel="stylesheet" type="text/css" />
I also have other generated HTML pages as with freemarker. They just collect the path:
/styles/default.css, or
localhost:8081/styles/default.css
Shows the CSS way index gets it.
Source: https://groups.google.com/d/msg/sparkjava/5vMuK_5GEBU/vh_jHra75u0J
Right click your project on Eclipse, select create New -> Package. Give the new package a name, etc.
Put your static resources under that package, so we can be sure they're under your classpath.
In your Main class colde, call staticFileLocation("yourpackagename/");
Place your public directory into src/main/resources
Replace Spark.staticFileLocation("/public"); to Spark.staticFileLocation("public");

How to access common resource files from multiple projects

In one of my projects I have resources stored in /src/test/resources (typical maven directory structure). Those resources are being used by an utility class stored in the project.
The utility class itself is being used from other projects (other projects depend on this one). I would access the resource like that:
final InputStream inputStreamDobs =
ClassLoader.class.getResourceAsStream("/dbunit/clear_db.xml");
but since I use it from different projects the path is not correct - it is relative to current project that is being built/tested, not the one where utility class and resources are.
Any thought how to approach this?
I need to avoid absolute paths - would like to have a way of defining relative path to the utility class.
I also don't want to replicate resources over multiple projects. Cheers.
EDIT:
To give a context I have a definition of tables in XML file that needs to be cleared after Integration Tests (clear whole DB schema). Integration Tests sits in multiple project, but the clear script and resource file is the same for all of them and sits in common parent project.
EDIT2:
Bonus question: I would like to access common DTD file (let's call it tables.dtd) that need to be accessed from XML files from multiple other projects. (it will sit in common parent project).
Currently I have it duplicated over multiple project, and I refer to it from XML using directive:
<!DOCTYPE dataset SYSTEM "src/test/resources/dbunit/dobs.dtd">
How to point it to a file in different project?
You wrote
... but since I use it from different projects the path is not correct - it is relative to current project that is being built/tested, not the one where utility class and resources are
...
Relative paths are not the problem here. You use an absolute path in your example, but even if you would use a relative one, this would refer to the package or directory structure. getResourceAsStream would pick them up as long as the classpath is correct. The real problem is that you are referring to test resources in another project. But test resources and classes are not contained in the project artifact, so they are not accessible from modules that include this as a dependency. If you need these resources for tests in several projects, I would suggest that you create a new project (let's say "projectxyz-testresources") with these resouces contained in src/main/resources and add this as a dependency with scope "test" where relevant.
EDITED TO ADD:
If you don't want to use a separate project for test resources, you can create a test-jar containing test classes and resources using goal jar:test-jar and include this as a test dependency. You may want to configure the jar plugin in your pom to execute this goal on regular builds.
Your runtime classpath shouldn't reference src/test/resources. Maven will copy everything over to target so you should be able to get it with "/dbunit/clear_db.xml"
Have you tried using "classpath:" prefix? You shouldn't have to specify full paths to resources if they are available on the classpath. For example:
<mvc:resources location="classpath:/META-INF/web-resources/" mapping="/resources/**" />
/META-INF/web-resources/ comes from Spring MVC's JAR which is one of the project's dependencies. The project doesn't need to know how to get to that resource "directly" instead it uses the classpath.
I think you can use 2 below plugins for this purpose.
if your project is web project, you can create 2 web projects, one of them contains config files and another project is your main project, now on you can overlay projects with maven-war-plugin
There are many types for overlay, you can visit this page for more information
maven-war-plugin overlay
for jar files you can merge them to single one with maven-assembly-plugin
maven-assembly-plugin
We had a similar instance in which, we had some configuration files that were used across multiple modules in big multi module maven project.
So what we did was split the conf files into a separate module, that just jars up the config files.
And then whatever module needed those files could declare the dependency to the config files modules and just use the jar files with the config files and unzip them to use them.
You could do something similar for the test resources. Create a module with just the resources and then put them into the relevant path.
In this case, I would suggest to program a maven plugin for this task, so that this so variable path may be configured via properties.
You will also benefit from the Project object.
/**
* Location of the file.
*/
#Parameter(defaultValue = "${basedir}/src/main/java", property = "sourceFolder", required = true)
private File sourceFolder;
#Parameter(defaultValue = "${basedir}/src/test/java", property = "testFolder", required = true)
private File testFolder;
#Parameter(defaultValue = "${project}", property = "project", readonly = true, required = true)
private MavenProject project;
Can you try using Maven Overlays? We had faced similar situation in the past, and very much resolved using overlays. Usually, overlays are used to share common resources across multiple web applications.
Maybe one of these approaches:
Either: You outsource the xml files AND the java classes (like the utility class) that need access to them into a seperate library which you can then include into your several other projects (conveniently as maven dependencies).
Or: You put these xml files into a seperate VCS-tree or repository and you include them in your project tree (e.g. as an "external" in SVN). So you can update this reference seperately in your projects, but you only have to maintain one source file.

Relative URL to images in css (Zkoss)

I developed a component in ZK 7.0.0 with own molds, styles etc. The component should be build in one jar file, which I can copy in WEB-INF/lib folder to replace standart ZK components.
Folder structure:
src/
src/main/resources/web/images/
src/main/resources/web/js/
In ".css.dsp" files I use statements likes:
background-image:url(${c:encodeURL('/images/in2.png')}
And it's refer to 'domen/webapp/images/in2.png'. (physical path: /webapp/images/in2.png). But I need get images from jar file.
So how can I write relative path to images in css files?
You are faced with the case that is somewhat similar to this one.
To reference a URI that points to a file on the classpath you should use a special prefix ~./:
background-image:url(${c:encodeURL('~./images/in2.png')}
Some more details could be found in the docs for methods WebApp.getResource or Execution.locate.
Real world examples can be seen in ZK source files.

Integrate BIRT in existing webapp

I would like to add the BIRT reporting engine to an existing webapp in Tomcat. I don't need the BIRT viewer, I really only want to be able to run the reports from a url like http://localhost:8080/birt/output?__report=test.rptdesign&sample=my+parameter and use the different export options pdf, xls, doc, html.
The integration guides I've found so far all include the viewer and writing my own servlets to handle different formats.
I was hoping someone knew simply which servlet mappings from the report-engine web.xml file I needed and which jars I would need to include from the lib directory for this barebones BIRT implementation in existing webapp.
I was hoping someone knew simply which servlet mappings from the
report-engine web.xml file I needed and which jars I would need to
include from the lib directory for this barebones BIRT implementation
in existing webapp.
I didn't necessarily want to write my own servlet I just wanted to integrate the existing reporting runtime from its own standalone webapp (here under the "runtime" button) into my existing webapp, so that I don't have to distribute 2 webapps to support running BIRT reports. Sorry if that wasn't clearer.
I did work this out though, in the simplest possible fashion, in case anyone has a similar question (using BIRT runtime 3.7.1):
All you need is the following servlet mapping added to your own webapp\web-inf\web.xml file:
<!-- Engine Servlet -->
<servlet>
<servlet-name>EngineServlet</servlet-name>
<servlet-class>org.eclipse.birt.report.servlet.BirtEngineServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>EngineServlet</servlet-name>
<url-pattern>/output</url-pattern>
</servlet-mapping>
Include all jars from the web-inf\lib directory of the runtime into your own webapp\web-inf\lib directory.
You can then run .rptdesign files using the output BIRT report url from your own webapp, and specifying whatever format you want, e.g.:
http://localhost:8080/myOwnWebapp/output?__report=test.rptdesign&__format=pdf
http://localhost:8080/myOwnWebapp/output?__report=test.rptdesign&__format=html
http://localhost:8080/myOwnWebapp/output?__report=test.rptdesign&__format=xls
http://localhost:8080/myOwnWebapp/output?__report=test.rptdesign&__format=doc
http://localhost:8080/myOwnWebapp/output?__report=test.rptdesign&__format=ppt
As i understand you, you are trying to generate a birt report form a servlet where you have the *.rptdesign in somewhere location.
Good, look at the following code
this.bundle = ResourceBundle.getBundle("com.tts.mersal.resources.MersalResources");
this.config = new EngineConfig();
this.config.setEngineHome(bundle.getString("BIRT_ENGINE_HOME"));
this.config.setLogConfig(bundle.getString("BIRT_LOGGING_FOLDER_PATH"), Level.ALL);
Platform.startup(config);
this.factory = (IReportEngineFactory)Platform.createFactoryObject(IReportEngineFactory.EXTENSION_REPORT_ENGINE_FACTORY);
this.engine = factory.createReportEngine( config );
this.engine.changeLogLevel(Level.ALL);
ContentReader contentReader = Repository.getServiceRegistry(FacesContext.getCurrentInstance()).getFileFolderService().getReader(MersalOutboundReportDialogBean.this.dialogReportNode.getNodeRef());
IReportRunnable report = MersalOutboundReportDialogBean.this.getEngine().openReportDesign(contentReader.getContentInputStream());
ReportDesignHandle designHandle = (ReportDesignHandle)report.getDesignHandle();
OdaDataSource source = (OdaDataSource)designHandle.getModule().findDataSource(DATA_SOURCE_NAME);
source.setProperty(source.getPropertyDefn("FILELIST"), buildUrl((String)source.getProperty(designHandle.getModule(), "FILELIST")));
IRunAndRenderTask runAndRenderTask = MersalOutboundReportDialogBean.this.getEngine().createRunAndRenderTask(report);
HTMLRenderOption render = new HTMLRenderOption();
render.setOutputFileName("G:/Render.html");
render.setOutputFormat("html");
runAndRenderTask.setRenderOption(render);
runAndRenderTask.run();
runAndRenderTask.close();
As you can see the first thing you must prepare the birt engine and then get an instance of report from type IReportRunnable, so you can after that set the location of the output by using therender option which will be changed based on your request.
You have multiple chocies, HTMLRenderOption, PDFRenderOption and others.
I hope that will serve you.
Thanks.

Categories

Resources