I'm new to Spark Java framework and I'm trying to render my html file using Freemarker template engine. But I'm not able to render my css and js files.
My project structure is as follows:
./pom.xml
./src/main/java/Spark.java
./src/main/resources/css/bootstrap.css
./src/main/resources/js/bootstrap.min.js
./src/main/resources/js/app.js
./src/main/resources/templates/search.ftl
The main method is as follows:
public static void main(String[] args) {
BasicConfigurator.configure();
staticFileLocation("/css");
staticFileLocation("/Content/Images");
staticFileLocation("/fonts");
staticFileLocation("/js");
final Configuration configuration = new Configuration();
configuration.setClassForTemplateLoading(Spark.class, "/");
get("/searchview", (request, response) -> {
StringWriter writer = new StringWriter();
try {
Template searchTemplate = configuration.getTemplate("templates/search.ftl");
searchTemplate.process(null, writer);
} catch (Exception e) {
halt(500);
}
return writer;
});
}
And now when I enter url: localhost:4567/searchview, my HTML page gets rendered but the css and js is not.
In my console it says: INFO spark.http.matching.MatcherFilter - The requested route [/css/bootstrap.min.css] has not been mapped in Spark
What am I missing?
Your subsequent staticFileLocation calls will override your previously set static file locations. Create a folder called public under your src/main/resources and then place your css, fonts, js and any other static folders under there. Finally set your static file location by staticFileLocation("/public").
Related
In my Spring Camel app, I try to move or delete a file base on the destinationFolder property. If destinationFolder=null, I want the file to be deleted. If destinationFolder!=null, I want the file to be moved to destinationFolder.
String destinationFolder;
//In the Camel routeBuilder:
from("file://C:/folder1?move=" + destinationFolder)
What will happen in destinationFolder is null? Does the file get move to default location?
When I set destinationFolder=null, I see the file is deleted in folder1.
If you set the move option then the file component will move the file, you cannot set it to null and then have it automatic delete the file. By default the file is moved to a folder named .camel.
So either set delete=true or set move to some folder name to move the files.
First, you should know when to use "move", "delete" &"noop" and how it will works in Apache camel
Note :1) If your destination path is not existed then file will delete automatically.
Note :2) If you are not used "noop=true" in Camel URL then file file will delete(if your destination path is null)
Reference : - enter link description here
Basic Test Code:
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.impl.DefaultCamelContext;
public class SFTPTest {
public static void main(String[] args) throws Exception {
DefaultCamelContext ctx = null;
try{
ctx = new DefaultCamelContext();
ctx.addRoutes(new RouteBuilder() {
#Override
public void configure() throws Exception {
String filepath = "file:///camelexample/?fileName=test.txt&move=null";
from(filepath)
.log("File processed");
}
});
ctx.start();
Thread.sleep(5000);
ctx.stop();
}catch (Exception e){
System.err.println("Exception is : "+e.getLocalizedMessage());
}finally {
try{
ctx.stop();
}catch (Exception e){
System.err.println("Exception is : "+e.getLocalizedMessage());
}
}
}
}
I have this code:
private static final String EMAIL_INLINEIMAGE_TEMPLATE_NAME = "templateemail.html";
#Bean
public TemplateEngine emailTemplateEngine() {
templateEngine = new SpringTemplateEngine();
templateEngine.addTemplateResolver(this.htmlTemplateResolver());
)
templateEngine.setTemplateEngineMessageSource(this.messageSource);
return templateEngine;
}
private static ITemplateResolver htmlTemplateResolver() {
final ClassLoaderTemplateResolver templateResolver = new ClassLoaderTemplateResolver();
templateResolver.setOrder(Integer.valueOf(0));
templateResolver.setPrefix("classpath:/templates/");
templateResolver.setSuffix(".html");
templateResolver.setTemplateMode(TemplateResolver.DEFAULT_TEMPLATE_MODE);
templateResolver.setCharacterEncoding("UTF-8");
templateResolver.setCacheable(false);
return templateResolver;
}
public void sendEmail(String emailAddress, String title, String body, Locale local, String image) {
if (Boolean.parseBoolean(isEmailServiceActivated)) {
MimeMessage mimeMessage = mailSender.createMimeMessage();
MimeMessageHelper mailMsg = new MimeMessageHelper(mimeMessage);
try {
mailMsg.setFrom(EMAIL_USERNAME);
mailMsg.setTo(emailAddress);
mailMsg.setSubject(title);
// Prepare the evaluation context
ctx.setLocale(local);
ctx.setVariable("imageHeaderResourceName", HEADER_LOGO_IMAGE);
ctx.setVariable("body", body);
ctx.setVariable("imageResourceName", image);
final String htmlContent = this.templateEngine.process(new ClassPathResource(EMAIL_INLINEIMAGE_TEMPLATE_NAME).getPath(), ctx);
mailMsg.setText(htmlContent, true );
mailMsg.addInline(HEADER_LOGO_IMAGE, new ClassPathResource(HEADER_LOGO_IMAGE ) , PNG_MIME);
mailMsg.addInline(image, new ClassPathResource(image) , PNG_MIME);
} catch (MessagingException e) {
e.printStackTrace();
}
mailSender.send(mimeMessage);
}
}
I have templateemail.html file under /templates/ directory. when I launch the sending email method I have this exception :
org.thymeleaf.exceptions.TemplateInputException: Error resolving template "templateemail.html", template might not exist or might not be accessible by any of the configured Template Resolvers
I dont know if it's because the templateEngine can't find my file (I try even with tomcat absolute path and /bin directory but no way ) or I haven't configure the right Template Resolver.
Thank you very much for your help. I
It work now by deleting ".html" in the name of template (the file has the html extension)
private static final String EMAIL_INLINEIMAGE_TEMPLATE_NAME = "templateemail"
Note the non-cross-platform behavior that can occure: on Windows the CamelCase.html template was resolved, but not on Ubuntu linux! There I had to rename it to camelcase.html, all chars in lower case
I had the same issue recently. My problem was that my template had references to other templates that started with /.
For example:
<html ... th:include="/internal/layout-normal :: page"> <-- failed
<html ... th:include="internal/layout-normal :: page"> <-- worked
Both variants worked without problems when I run the application from IntelliJ. However, when packaged and run via java -jar the first line failed.
Removing the / solved the problem for me
Thymeleaf picks up the html files from resources/templates path by using the name of html file.
Hence in this case just removing .html extension from the filename would work!
I have a code like follows
public LocalFileStorage(String storageUrl, Resource storageDirectory) {
this.storageUrl = storageUrl;
try {
this.storageDirectory = storageDirectory.getFile();
this.storageDirectory.deleteOnExit();
this.storageDirectory.createNewFile();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
I call the class the follows.
private ResourceLoader resourceLoader; // from spring
LocalFileStorage pictureStorage = new LocalFileStorage(Url+ "/resources/", resourceLoader.getResource("/resources/"));
call to
resourceLoader.getResource("/resources/")
throws exception. I thought ResourceLoader loads directory also because after all directory is also a file.
My structure
Typically, only anything inside /WEB-INF/classes, /WEB-INF/lib, /WEB-INF/... will be added to the classpath and accessible through ClassLoader.getResource(). The folder you are trying to access is not in WEB-INF and will therefore not appear in the classpath.
Assuming you are using something similar to Maven, you should put resource files under /src/main/resources. When your project is built, those files will end up in WEB-INF/classes.
I have a Propertyfile config.properties in which I store a Path which a class loads to read Files.
The properties are loaded like this:
public class PropertyConfig {
private static final Properties properties = new Properties();
static {
try {
ClassLoader loader = Thread.currentThread().getContextClassLoader();
properties.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("config.properties"));
} catch (IOException e) {
throw new ExceptionInInitializerError(e);
}
}
public static String getSetting(String key) {
return properties.getProperty(key);
}
}
and the call in the relevant class is like this:
private static File savedGamesFolder = new File(PropertyConfig.getSetting("folder_for_saved_games"));
For testing purposes I want to be able to change the path to a test directory, or change the whole Property-file in a jUnit-TestCase. How can achieve this?
I'm using Maven if that helps.
Assuming you have your config.properties in
src/main/resources/config.properties
Note: you should nevertheless have your properties files somewhere in src/main/resources
Place your test configuration in
src/main/test/config.properties
That's it. No need to change your code.
I'm developing a small tool based on jersey and freemarker, which will enable designers to test there freemarker templates, locally, using some mok-objects.
I'm sorry to write here, but I cant find any documentation about it except some code and javadocs.
To do that I did the following:
1 Dependencies:
<dependency>
<groupId>com.sun.jersey.contribs</groupId>
<artifactId>jersey-freemarker</artifactId>
<version>1.9</version>
</dependency>
2 Starting grizzly, telling where to find freemarker templates:
protected static HttpServer startServer() throws IOException {
System.out.println("Starting grizzly...");
Map<String, Object> params = new HashMap<String, Object>();
params.put("com.sun.jersey.freemarker.templateBasePath", "/");
ResourceConfig rc = new PackagesResourceConfig("resource.package");
rc.setPropertiesAndFeatures(params);
HttpServer server = GrizzlyServerFactory.createHttpServer(BASE_URI, rc);
server.getServerConfiguration().addHttpHandler(
new StaticHttpHandler("/libs"), "/libs");
return server;
}
3 Creates the root resource and binds freemarker files:
#Context ResourceConfig resourceConfig;
#Path("{path: ([^\\s]+(\\.(?i)(ftl))$)}")
public Viewable renderFtl (#PathParam("path") String path) throws IOException {
Viewable view = new Viewable("/"+path);
return view;
}
Everything works fine, except that freemarker files are not rendered. I have an empty white page, but file exists and debugger enter inside renderFtl method right.
Do you know how can I do that?
I read a lot of articles here and around the web, but old posts only or articles talking about spring integration and I don't want to integrate it because I don't need it.
I really like Jersey, I think is one of the most complete and power framework on java world, but anytime I try to find documentation on specific features or contribs libraries, I'm lost... There no escape from groups forums :)
Where can I find a complete documentation about it?
Tanks a lot David
Updates:
Trying to solve I understood I cannot use built-in jersey support, because it needs to use files placed in resources tree. So What I did is to build freemarker configuration, in test for now, directly #runtime and returns a StreamingOutput object:
#Path("{path: ([^\\s]+(\\.(?i)(ftl))$)}")
public StreamingOutput renderFtl (#PathParam("path") String path) throws Exception {
Configuration cfg = new Configuration();
// Specify the data source where the template files come from.
// Here I set a file directory for it:
cfg.setDirectoryForTemplateLoading(new File("."));
// Create the root hash
Map<String, Object> root = new HashMap<String, Object>();
Template temp = cfg.getTemplate(path);
return new FTLOutput(root, temp);
}
FTLOutput is here:
This is not a good code, but is for test only...
class FTLOutput implements StreamingOutput {
private Object root;
private Template t;
public FTLOutput(Object root, Template t) {
this.root = root;
this.t = t;
}
#Override
public void write(OutputStream output) throws IOException {
Writer writer = new OutputStreamWriter(output);
try {
t.process(root, writer);
writer.flush();
} catch (TemplateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
I have no errors evidence on debug and freemarker tells me that template is found and rendered, but jersey still no give me a result...
I really don't know why!
Why are you using Jersey 1.9? 1.11 is already out, you should update if you can
Have you seen "freemarker" sample from Jersey? It demonstrates simple usecase of using freemarker with jersey.
Where are your resources?
Templates are being found by calling [LastMatchedResourceClass].getResources(...), so if your templates are not accessible as resources, they can't be rendered correctly. you can checkout Jersey source and place some breakpoints into FreemarkerViewProcessor, it should tell you where exactly the problem is..