I would like to serve internationalized html pages with my Spring Boot application and I am using Thymeleaf with messages_XX.properties for i18n. I would prefer accessing these as http://localhost:8080/some/path/test.html and having them in e.g. /src/main/resources/html but I am unable to configure Spring Boot to process a page using thymeleaf by default.
As a temporary workaround I have a controller with
#RequestMapping(value="**/*.html")
public String serve(HttpServletRequest req) {
String res = req.getRequestURI().substring(0, req.getRequestURI().length() - 5);
res = res.substring(1);
return res;
}
This works for me now: http://localhost:8080/some/path/file.html processes and serves src/templates/some/path/file.html but can I just configure somewhere that src/resources/html are to be PROCESSED by thymeleaf and then served?
So far I have tried
spring.thymeleaf.prefix=classpath:/html/
in application.properties but it does not seemed to work for me.
Environment:
spring-boot-starter-2.0.0.RELEASE,
spring-webmvc-5.0.4.RELEASE,
thymeleaf-spring5-3.0.9.RELEASE
Since you are cutting of the .html in:
String res = req.getRequestURI().substring(0, req.getRequestURI().length() - 5);
You should probably set
spring.thymeleaf.suffix=.html
Or with Configuration:
#Bean
public SpringResourceTemplateResolver templateResolver(){
SpringResourceTemplateResolver templateResolver = new SpringResourceTemplateResolver();
templateResolver.setApplicationContext(this.applicationContext);
templateResolver.setPrefix("classpath:/html/");
templateResolver.setSuffix(".html");
templateResolver.setTemplateMode(TemplateMode.HTML);
templateResolver.setCacheable(true);
return templateResolver;
}
Related
I have a project and I need users to be able to add content without recompiling the application or using a database. What I want to achieve is for spring to look in a directory called modules / for all folders containing a thymeleaf html file and render them according to their name from a single controller. it's possible?.
I have looked for information on how to render a fragment of thymeleaf from java in real time but I have not found any information.
with the help of this, we can navigate our template path as per our desired location.
#Bean
public ClassLoaderTemplateResolver templateResolver() {
ClassLoaderTemplateResolver templateResolver = new ClassLoaderTemplateResolver();
templateResolver().setPrefix("file://C:/test/");// this is
templateResolver.setCacheable(false);
templateResolver.setTemplateMode("HTML5");
templateResolver.setSuffix(".html");
templateResolver.setTemplateMode("XHTML");
templateResolver.setCharacterEncoding("UTF-8");
templateResolver.setOrder(1);
return templateResolver;
}
This is also a solution.
use this in application properties file
project.base-dir=file:///E:/Work/WorkSpace/RND WorkSpace/sk
spring.thymeleaf.prefix=${project.base-dir}/src/main/resources/templates/
I am using spring boot 2.2.4 and using the thymealeaf text templates for the first time with spring boot.
Belowis the texttemplate I am trying to use and I am trying to print the current date and time but it is printing blank on screen.
CurrentDate:[#th:block th:utext="${#temporals.format(now, 'dd/MMM/yyyy HH:mm')}"/]
I have added the Java8 date time dependency in pom.xml and also added the java8dialect in the template resolver bean.
pom.xml
--------
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-java8time</artifactId>
<version>3.0.4.RELEASE</version>
</dependency>
ThymeleafConfig.java
----------------------
#Configuration
public class ThymeleafConfig {
#Bean(name = "textTemplateEngine")
public TemplateEngine textTemplateEngine() {
TemplateEngine templateEngine = new TemplateEngine();
templateEngine.addTemplateResolver(textTemplateResolver());
templateEngine.addDialect(new Java8TimeDialect());
return templateEngine;
}
private ITemplateResolver textTemplateResolver() {
ClassLoaderTemplateResolver templateResolver = new ClassLoaderTemplateResolver();
templateResolver.setPrefix("/templates/text/");
templateResolver.setSuffix(".txt");
templateResolver.setTemplateMode(TemplateMode.TEXT /* https://github.com/thymeleaf/thymeleaf/issues/395 */);
templateResolver.setCharacterEncoding("UTF8");
templateResolver.setCheckExistence(true);
templateResolver.setCacheable(false);
return templateResolver;
}
}
Can anybody please tell me what am I doing wrong in thymealeaf text template that it is not printing the date?
You can use a Thymeleaf utility method to print various date and time variants.
For example:
<div th:text="${#dates.createNow()}"></div>
I think that may answer your specific question.
However, I suspect your question is more about the wider topic of binding Java objects to Thymeleaf templates in Spring - and I have not used Spring with Thymeleaf.
I worked with spring boot and redis to caching.I can cache my data that fetch from database(oracle) use #Cacheable(key = "{#input,#page,#size}",value = "on_test").
when i try to fetch data from key("on_test::0,0,10") with redisTemplate the result is 0
why??
Redis Config:
#Configuration
public class RedisConfig {
#Bean
JedisConnectionFactory jedisConnectionFactory() {
RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration("localhost", 6379);
redisStandaloneConfiguration.setPassword(RedisPassword.of("admin#123"));
return new JedisConnectionFactory(redisStandaloneConfiguration);
}
#Bean
public RedisTemplate<String,Objects> redisTemplate() {
RedisTemplate<String,Objects> template = new RedisTemplate<>();
template.setStringSerializer(new StringRedisSerializer());
template.setValueSerializer(new StringRedisSerializer());
template.setConnectionFactory(jedisConnectionFactory());
return template;
}
//service
#Override
#Cacheable(key = "{#input,#page,#size}",value = "on_test")
public Page<?> getAllByZikaConfirmedClinicIs(Integer input,int page,int size) {
try {
Pageable newPage = PageRequest.of(page, size);
String fromCache = controlledCacheService.getFromCache();
if (fromCache == null && input!=null) {
log.info("cache is empty lets initials it!!!");
Page<DataSet> all = dataSetRepository.getAllByZikaConfirmedClinicIs(input,newPage);
List<DataSet> d = redisTemplate.opsForHash().values("on_test::0,0,10");
System.out.print(d);
return all;
}
return null;
The whole point of using #Cacheable is that you don't need to be using RedisTemplate directly. You just need to call getAllByZikaConfirmedClinicIs() (from outside of the class it is defined in) and Spring will automatically check first if a cached result is available and return that instead of calling the function.
If that's not working, have you annotated one of your Spring Boot configuration classes with #EnableCaching to enable caching?
You might also need to set spring.cache.type=REDIS in application.properties, or spring.cache.type: REDIS in application.yml to ensure Spring is using Redis and not some other cache provider.
im getting this error i searched on the same issues like mine on stack and i have foudn that i shouldn t put .html when calling it but im getting the same error :
`Caused by: org.thymeleaf.exceptions.TemplateInputException: Error resolving template "orderConfirmationEmailTemplate", template might not exist or might not be accessible by any of the configured Template Resolver`s
my mail constructor :
#Component
public class MailConstructor {
#Autowired
private Environment env;
#Autowired
private TemplateEngine templateEngine;
public SimpleMailMessage constructNewUserEmail(User user, String password) {
String message="\nPlease use the following credentials to log in and edit your personal information including your own password."
+ "\nUsername:"+user.getUsername()+"\nPassword:"+password;
SimpleMailMessage email = new SimpleMailMessage();
email.setTo(user.getEmail());
email.setSubject("Le's Bookstore - New User");
email.setText(message);
email.setFrom(env.getProperty("support.email"));
return email;
}
public MimeMessagePreparator constructOrderConfirmationEmail (User user, Order order, Locale locale) {
Context context = new Context();
context.setVariable("order", order);
context.setVariable("user", user);
context.setVariable("cartItemList", order.getCartItemList());
String text = templateEngine.process("orderConfirmationEmailTemplate.html", context);
MimeMessagePreparator messagePreparator = new MimeMessagePreparator() {
#Override
public void prepare(MimeMessage mimeMessage) throws Exception {
MimeMessageHelper email = new MimeMessageHelper(mimeMessage);
email.setTo(user.getEmail());
email.setSubject("Order Confirmation - "+order.getId());
email.setText(text,true);
email.setFrom(new InternetAddress("alaaeddinezammel1993#gmail.com"));
}
};
return messagePreparator;
}
and im calling it from rest service:
mailSender.send(mailConstructor.constructOrderConfirmationEmail(user, order, Locale.ENGLISH));
shoppingCartService.clearShoppingCart(shoppingCart);
and im putting the file .html under package in the project
In your question, the TemplateEngine is auto wired so I cannot see how it is configured but it in order to discover your template from the location com.bookstore.domain.security.templates the configuration should look something like this:
#Bean
public TemplateEngine templateEngine() {
final SpringTemplateEngine templateEngine = new SpringTemplateEngine();
templateEngine.addTemplateResolver(templateResolver());
return templateEngine;
}
private ITemplateResolver templateResolver() {
final ClassLoaderTemplateResolver templateResolver = new ClassLoaderTemplateResolver();
templateResolver.setPrefix(“/com/bookstore/domain/security/templates“);
templateResolver.setSuffix(".html");
…
return templateResolver;
}
In this code I am configuring the TemplateEngine in code, perhaps you are using XML. Regardless of how you are configuring the TemplateEngine, you are clearly using Spring to do so (since you inject it into your MailConstructor), the key point here is that regardless of how you configure it you need to tell it where to find your template and the way to do that is to invoke the ITemplateResolver's setPrefix() method.
Plenty more details in the article titled Sending email in Spring with Thymeleaf in the Thymeleaf docs.
actually with my configuration putted in my question i just put the .html file under file called templates under resources and it works the mail is sent , spring boot is apparently auto configured with this path without configuring the
templateResolver
I configure my JAXRS Server in Spring Boot like so:
JAXRSServerFactoryBean factoryBean = new JAXRSServerFactoryBean();
factoryBean.setBus(this.bus);
factoryBean.setFeatures(singletonList(swagger2Feature()));
factoryBean.setServiceBeans(Arrays.asList(blah(), blah2(), blah3()));
factoryBean.setAddress("/api/v1/"); // HERE
List<Object> providers = new ArrayList<>();
providers.add(new JacksonJaxbJsonProvider());
factoryBean.setProviders(providers);
BindingFactoryManager manager = factoryBean.getBus().getExtension(BindingFactoryManager.class);
JAXRSBindingFactory restFactory = new JAXRSBindingFactory();
restFactory.setBus(factoryBean.getBus());
manager.registerBindingFactory(JAXRSBindingFactory.JAXRS_BINDING_ID, restFactory);
return factoryBean.create();
However, the URLs always require /services in front, which is a nuisance (but not the end of the world). Is there any way I can remove /services and just get it deployed to the root context?
If you have not created your own CxfServlet bean you can set the path by setting cxf.path property in your application.properties file
cxf.path=/
Another way is to override ServletRegistrationBean.
#Bean
public ServletRegistrationBean cxfServletRegistration() {
String urlMapping = "/*";
ServletRegistrationBean registration = new ServletRegistrationBean(
new CXFServlet(), urlMapping);
registration.setLoadOnStartup(-1);
return registration;
}