Thymeleaf layout fragment not working in Spring Webflux - spring-boot

In spring boot, the layout came out properly with the following settings, but it does not work after changing to webflux.
WebConfig.java
#Configuration
#EnableWebFlux
public class WebConfig implements WebFluxConfigurer, ApplicationContextAware {
ApplicationContext context;
#Override
public void setApplicationContext(ApplicationContext context) throws BeansException {
}
#Bean
public ITemplateResolver thymeleafTemplateResolver() {
final SpringResourceTemplateResolver resolver = new SpringResourceTemplateResolver();
resolver.setApplicationContext(this.context);
resolver.setPrefix("classpath:templates/");
resolver.setSuffix(".html");
resolver.setTemplateMode(TemplateMode.HTML);
resolver.setCacheable(false);
resolver.setCheckExistence(false);
return resolver;
}
#Bean
public ISpringWebFluxTemplateEngine thymeleafTemplateEngine() {
SpringWebFluxTemplateEngine templateEngine = new SpringWebFluxTemplateEngine();
templateEngine.setTemplateResolver(thymeleafTemplateResolver());
return templateEngine;
}
#Bean
public ThymeleafReactiveViewResolver thymeleafReactiveViewResolver() {
ThymeleafReactiveViewResolver viewResolver = new ThymeleafReactiveViewResolver();
viewResolver.setTemplateEngine(thymeleafTemplateEngine());
return viewResolver;
}
#Override
public void configureViewResolvers(ViewResolverRegistry registry) {
registry.viewResolver(thymeleafReactiveViewResolver());
}
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry){
registry.addResourceHandler("/resources/**")
.addResourceLocations("/static/")
.resourceChain(true)
.addResolver(new VersionResourceResolver().addContentVersionStrategy("/**"));
}
}
layout_main.html
<body>
<div class="layout-main" ng-app="mainApp">
<header th:replace="fragment/header :: header"></header>
<div class="content">
<section layout:fragment="content"></section>
</div>
</div>
<th:block layout:fragment="js-end"></th:block>
</body>
chat.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorator="layout/layout_main">
<section layout:fragment="content" ng-controller="chatController" class="content-chat-container">
<nav th:replace="~{app/chat/fragment/nav_chat :: nav}"></nav>
<div class="app-wrapper">
</div>
</section>
When opening chat.html, the layout:decorator part is not properly processed, so layout_main is not included and the View appears.

Related

sec:authorize not working in spring-boot application

I have this index.html on the resources/templates directory of my project:
<!DOCTYPE html>
<html lang="pt-BR">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" th:href="#{/css/style.css}">
</head>
<body>
<nav sec:authorize="isAnonymous()">
<strong>Hello World!</strong> <a th:href="#{/login}">Login</a>
</nav>
<nav sec:authorize="isAuthenticated()">
<strong th:text="${usuario}"></strong> <a th:href="#{/logout}">Logout</a>
</nav>
<script th:src="#{/js/script.js}"></script>
</body>
</html>
Neither the tags inside sec:authorize="isAnonymous()" or inside sec:authorize="isAuthenticated()" are being display when I run the project and open it in the browser.
I have this application.properties file:
security.basic.enabled=false
spring.datasource.driver-class-name=org.postgresql.Driver
spring.datasource.url=jdbc:postgresql://localhost:5432/appdata
spring.datasource.username=kleber
spring.datasource.password=123456
spring.datasource.continue-on-error=true
sprinf.jpa.database-platform=org.hibernate.dialect.PostgreSQLDialect
spring.jpa.dialect=org.hibernate.dialect.PostgreSQLDialect
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=update
spring.jpa.generate-ddl=true
spring.thymeleaf.prefix=classpath:/templates/
spring.thymeleaf.suffix=.html
spring.thymeleaf.mode=HTML5
spring.thymeleaf.encoding=UTF-8
spring.thymeleaf.content-type=text/html
spring.thymeleaf.cache=false
spring.servlet.multipart.max-file-size=10MB
spring.servlet.multipart.max-request-size=10MB
spring.servlet.multipart.file-size-threshold=10MB
server.tomcat.max-http-post-size=10MB
and this App class:
#SpringBootApplication
#EnableWebSecurity
#Controller
public class AppApplication extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(AppApplication.class, args);
}
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(AppApplication.class);
}
#Bean
public WebSecurityCustomizer ignoringCustomizer() {
return (web) -> web.ignoring().antMatchers("/", "/login", "/logout", "/error", "/css/**", "/js/**", "/img/**");
}
#Bean
public SpringSecurityDialect springSecurityDialect() {
return new SpringSecurityDialect();
}
public UserDetailsService userDetailsService() {
return new UserDetailsService() {
#Autowired
private UsuarioDao usuarioDao;
#Override
public org.springframework.security.core.userdetails.UserDetails loadUserByUsername(String username) {
return usuarioDao.findBy("username", username).get(0);
}
};
}
#RequestMapping(value = "/")
public String index(Model model) {
return "index";
}
#RequestMapping(value = "/login")
public String login(Model model) {
return "login";
}
}
Any hints of what's wrong here?
Did you include Spring Security Thymeleaf extension?
If you're using Maven, the dependency should look like this:
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity5</artifactId>
</dependency>
Also you will need to enable the Thymeleaf Tags inside the HTML:
<html xmlns:sec="http://www.thymeleaf.org/extras/spring-security">
Heres more on that: https://www.thymeleaf.org/doc/articles/springsecurity.html
I also just realized this is a duplicate: Thymeleaf Spring security integration sec:authorize is not working

Spring mvc jsp not rendering

Getting started with Spring MVC, when I enter my page it loads the welcome.jsp as plain text(just shows source), I know people asked this 1 million times, But I looked over many of the questions and didn't find my solution as most of them using XML and I use java.. I am still not experienced enough to switch between the two.
conf.class :
public class conf extends WebMvcConfigurerAdapter {
#Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
#Bean
public InternalResourceViewResolver jspViewResolver() {
InternalResourceViewResolver bean = new InternalResourceViewResolver();
bean.setViewClass(JstlView.class);
bean.setPrefix("/views/");
bean.setSuffix(".jsp");
return bean;
}
}
ServletInitializer.class:
public class ServletInitializer extends SpringBootServletInitializer {
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(Demo4Application.class,conf.class);
}
}
welCont.class (Controller) :
#Controller
#RequestMapping("/spring/")
public class welCont {
#RequestMapping(method = RequestMethod.GET)
public String wel(ModelMap model)
{
model.addAttribute("test","testme");
return "welcome";
}
}
welcome.jsp :
<%# page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h2>${test}</h2>
</body>
</html>
I think wrong thing is
#RequestMapping("/spring/")
normally "/spring/" request should go to DispatcherServlet. Not sure in spring boot.
try with this.
#Controller
public class WelCont {
#RequestMapping(value="/foldername_if_avaiable/welcome/", method=RequestMethod.GET )
public ModelAndView wel(
#RequestParam(value="id", required=false) String id,
ModelMap model,
HttpSession session,
HttpServletRequest req) throws Exception {
model.addAttribute("test","testme");
return new ModelAndView("/foldername_if_avaiable/welcome", model);
}
}
reference

Spring mvc 4 can't render jsp

I'm trying to learn Spring MVC 4 without using the web.xml but instead use the following:
public class WebAppInitializer implements WebApplicationInitializer {
#Override
public void onStartup(ServletContext servletContext) throws ServletException {
WebApplicationContext context = getContext();
servletContext.addListener(new ContextLoaderListener(context));
ServletRegistration.Dynamic dispatcher = servletContext.addServlet("DispatcherServlet", new DispatcherServlet(context));
dispatcher.setLoadOnStartup(1);
dispatcher.addMapping("*.html");
}
private AnnotationConfigWebApplicationContext getContext() {
AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
context.setConfigLocation("com.bookstr.WebConfig");
return context;
}
}
and
#Configuration
#EnableWebMvc
#ComponentScan({ "com.bookstr.*" })
public class WebConfig {
}
For some reason the home.jsp file I have created and placed in the src->main->webapp folder will not be rendered when I use the following controller:
#Controller
public class HomeController {
#RequestMapping(value = "/home", method = RequestMethod.GET)
public String getHome(Model model){
model.addAttribute("home", "Hello world");
return "home";
}
}
And the JSP file is the following:
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Home</title>
</head>
<body>
${home}
</body>
</html>
Update!
Folder structure as requested.
I can see that the HomeController is not getting called.
Register a ViewResolver in your WebConfig:
#Configuration
#EnableWebMvc
#ComponentScan("com.bookstr")
public class WebConfig {
#Bean
public InternalResourceViewResolver viewResolver() {
InternalResourceViewResolver viewResover = new InternalResourceViewResolver();
viewResolver.setPrefix("/WEB-INF/views/");
viewResolver.setSuffix(".jsp");
return viewResolver;
}
}
This way, when you return the home from your controller, it will try to render the /WEB-INF/views/home.jsp view. For configuring DispatcherServlet programtically, it's easier to use AbstractAnnotationConfigDispatcherServletInitializer. For example, you simply can:
public class WebInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
#Override
protected Class<?>[] getRootConfigClasses() {
return null;
}
#Override
protected Class<?>[] getServletConfigClasses() {
return new Class<?>[] { WebConfig.class };
}
#Override
protected String[] getServletMappings() {
return new String[] { "/*.html" };
}
}

integrating Spring with thymeleaf views

I have simple doGet method in Spring:
#Override
public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
HttpSession session = req.getSession(true);
List<Category> categories = categoriesService.getCategories();
req.setAttribute("categories", categories);
if (!resp.isCommitted()) {
req.getRequestDispatcher("thymeleaf_views/categories.html").forward(req, resp);
}
}
I can get html page. But its all content is not resolved((
<body>
<div>
<h2>Categories</h2>
<ul id="menu" style="list-style-type:none">
<li th:each="category: ${categories}" th:text="${category.name}"></li>
</ul>
</div>
</body>
When I try to load the page - it loads tags as it is - does not substitute tags with its content(( What can be the reason?
You have to set a TemplateResolver. E. g. like the way below:
#Configuration
public class ThymeleafConfig {
#Bean
public ServletContextTemplateResolver templateResolver() {
ServletContextTemplateResolver resolver = new ServletContextTemplateResolver();
resolver.setPrefix("/WEB-INF/jsp/");
resolver.setSuffix(".html");
resolver.setTemplateMode("HTML5");
return resolver;
}
#Bean
public SpringTemplateEngine templateEngine() {
SpringTemplateEngine engine = new SpringTemplateEngine();
engine.setTemplateResolver(templateResolver());
return engine;
}
#Bean
public ThymeleafViewResolver thymeleafViewResolver() {
ThymeleafViewResolver resolver = new ThymeleafViewResolver();
resolver.setTemplateEngine(templateEngine());
return resolver;
}
}

JSF bean is not interpreted on the *.xhtml page

I am trying to configure JSF/primefaces with Spring boot in my maven project. I am following this example https://github.com/stephanrauh/JSF-on-Spring-Boot which works good.
Issue: when Application is running, the JSF views are shown without data from the back-end.
Here is my *.java classes:
#Configuration
public class WebInitializer extends SpringBootServletInitializer implements ServletContextAware {
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(Application.class);
}
#Bean
public DispatcherServlet dispatcherServlet() {
DispatcherServlet dispatcherServlet = new DispatcherServlet();
dispatcherServlet.setThrowExceptionIfNoHandlerFound(true);
return dispatcherServlet;
}
#Bean
public ServletRegistrationBean servletRegistrationBean() {
FacesServlet servlet = new FacesServlet();
ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(servlet, "*.xhtml");
servletRegistrationBean.setLoadOnStartup(1);
return servletRegistrationBean;
}
#Bean
public ServletListenerRegistrationBean<ConfigureListener> jsfConfigureListener() {
return new ServletListenerRegistrationBean<ConfigureListener>(new ConfigureListener());
}
#Override
public void setServletContext(ServletContext servletContext) {
servletContext.setInitParameter("com.sun.faces.forceLoadConfiguration", Boolean.TRUE.toString());
}
}
HelloBean class:
#ManagedBean(value = "helloBean")
#ViewScoped
public class HelloBean implements Serializable {
private String hello = "Hello from PrimeFaces and Spring Boot!";
public String getHello() {
return hello;
}
#PostConstruct
public void init() {
System.out.println("---------");
System.out.println(hello);
}
}
index.xhtml file:
<f:view xmlns="http://www.w3c.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:ng="http://xmlns.jcp.org/jsf/passthrough"
xmlns:prime="http://primefaces.org/ui">
<h:head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<title>#{menuController.title}</title>
<style>
body {font-size:12px; }
</style>
</h:head>
<h:body>
<h:form>
<prime:panel header="What do you see here?" >
<div style="height:50px">
This is a simple PrimeFaces 5 project running on Spring Boot 1.1.4.
</div>
</prime:panel>
<prime:panel header="JSF 2.2 Bean Access">
#{helloBean.hello}
</prime:panel>
</h:form>
</h:body>
</f:view>
Could anyone tell me why helloBean is not displayed on index.xhtml ?
Finally I have found solution to my issue.The problem was in HelloBean.class. I have used incorrect import - import javax.annotation.ManagedBean instead of import javax.faces.bean.ManagedBean;
I've made a different configuration to run Spring Boot + JSF. I think it is simpler. Check it out:
faces-config.xml
<application>
<el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver>
</application>
<lifecycle>
<phase-listener>org.springframework.web.jsf.DelegatingPhaseListenerMulticaster</phase-listener>
</lifecyle>
MyApp.java
#SpringBootApplication
public class MyApp extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(MyApp.class, args);
}
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(MyApp.class);
}
#Bean
public ServletRegistrationBean servletRegistrationBean() {
FacesServlet servlet = new FacesServlet();
ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(servlet, "*.jsf");
return servletRegistrationBean;
}
}
From Spring Boot 1.2 and above you can set the JSF parameters in the application.properties file, as below:
### JSF CONFIGS ###
server.context_parameters.com.sun.faces.forceLoadConfiguration=true
The Managed Bean of course. Remember not to use the javax.faces.bean package for the bean annotations
MyBean.java
import javax.annotation.ManagedBean;
import javax.faces.view.ViewScoped;
#ManagedBean
#ViewScoped
public class MyBean {
public String getHello() {
return "hello";
}
}
And finally, the view:
<ui:composition
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:c="http://xmlns.jcp.org/jsp/jstl/core"
xmlns:p="http://primefaces.org/ui"
template="views/templates/basic_template.xhtml"
>
<ui:define name="body_content">
<p:panel header="JSF 2.2 Bean Access">
<h:outputText value="#{myBean.hello}" />
</p:panel>
</ui:define>
</ui:composition>

Resources