Spring mvc 4 can't render jsp - spring

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" };
}
}

Related

Thymeleaf layout fragment not working in Spring Webflux

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.

Spring MVC - Dispatcher Servlet can't find any page

I do really simple demo web app using Spring mvc, Java class annotations and .jsp instead of .html.
When I start Tomcat on localhost - I always get 404 error. Where do I do mistake?
Config.class
#Configuration
#EnableWebMvc
#ComponentScan(basePackages = "com.mylov.springsecurity.demo.config")
public class Config {
//Define bean for ViewResolver
#Bean
public ViewResolver viewResolver() {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setPrefix("/WEB-INF/view/");
viewResolver.setSuffix(".jsp");
return viewResolver;
}
}
Dispatcher Servlet Initialization
public class DispatcherServletInit extends AbstractAnnotationConfigDispatcherServletInitializer {
#Override
protected Class<?>[] getRootConfigClasses() {
return null;
}
#Override
protected Class<?>[] getServletConfigClasses() {
return new Class[]{Config.class};
}
#Override
protected String[] getServletMappings() {
return new String[]{"/"};
}
}
Controller
#Controller
public class DemoController {
#GetMapping({"", "/"})
public String showHome() {
return "home";
}
}
Project Structure:
You need to scan packages under demo package. So Spring will find your Controllers and Config classes. But now you point to only config. So package 'controller' won't be scan.
Try to do this:
#ComponentScan(basePackages = "com.mylov.springsecurity.demo")
Try providing the mapping as below so that all url's are mapped with the servlet:
public class DispatcherServletInit extends AbstractAnnotationConfigDispatcherServletInitializer {
#Override
protected Class<?>[] getRootConfigClasses() {
return null;
}
#Override
protected Class<?>[] getServletConfigClasses() {
return new Class[]{Config.class};
}
#Override
protected String[] getServletMappings() {
return new String[]{"/*"};
}
}
Also change the base packages to as below so that the controller class is also picked up for component scanning :
#Configuration
#EnableWebMvc
#ComponentScan(basePackages = "com.mylov.springsecurity.demo")
public class Config {
..........
}

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

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>

Spring MVC returns jsp as text/plain content type

I have a problem with Spring MVC and jsp webpage.
When I request a webpage, it returns as text/plain by default. I tried setting the content type as text/html manually at the HttpServletResponse controller, and the web browser reconigzes it, showing it correctly BUT encoding the jsp tags at the body. Example:
JSP:
<%# page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Error 405 ******* </title>
</head>
<body> asdasdsasad </body>
</html>
Browser receives:
<html>
<body><%# page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Title</title>
</body>
</html>
I'm using Spring Boot and java web based annotation for configuration. Also, I'm using #EnableAutoConfiguration, and I found that the problem is solved by mapping the sevlet from "/*" to "/".
Because of the java annotation, I had to override the dispatchedServlet (https://github.com/spring-projects/spring-boot/issues/91#issuecomment-27626036) and the configuration class is:
#Configuration
public class DispatcherConfiguration {
#Bean
public ServletRegistrationBean dispatcherRegistration() {
ServletRegistrationBean registration = new ServletRegistrationBean(dispatcherServlet());
registration.addUrlMappings("/");
registration.setLoadOnStartup(1);
System.out.println("~~~~~~~ Servlet regristated " + registration.getServletName());
return registration;
}
#Bean
public DispatcherServlet dispatcherServlet() {
return new DispatcherServlet();
}
Notice that I'm using the #Bean annotation missfollowing the previous comment link, because if not, Spring boot throws an exception. But even if not using the bean annotation, and using an xml the main problem is still here).
This is the Spring MVC configuration file:
#Configuration
#EnableWebMvc
#ComponentScan("es.sfacut")
public class WebMvcConfiguration extends WebMvcConfigurerAdapter {
#Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/login").setViewName("login");
registry.setOrder(Ordered.HIGHEST_PRECEDENCE);
}
// Maps resources path to webapp/resources
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
registry.addResourceHandler("/images/**").addResourceLocations("/resources/images/");
registry.addResourceHandler("/imgs/**")
.addResourceLocations(Constant.RESOURCE_IMAGES_PATH);
}
#Bean
public UrlBasedViewResolver setupViewResolver() {
UrlBasedViewResolver resolver = new UrlBasedViewResolver();
resolver.setPrefix("/WEB-INF/views/");
resolver.setSuffix(".jsp");
// resolver.setContentType("text/html");
resolver.setViewClass(JstlView.class);
return resolver;
}
#Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
#Bean
public MultipartResolver multipartResolver() {
CommonsMultipartResolver resolver = new CommonsMultipartResolver();
// Size in bytes
resolver.setMaxUploadSize(1752300);
return resolver;
}
}
Main class:
#EnableAutoConfiguration
#ComponentScan("es.sfacut")
#EnableJpaRepositories
public class TelocomproMain {
public static void main(String[] args) {
SpringApplication.run(TelocomproMain.class, args);
}
}
Controller:
#RestController
#RequestMapping(value = "/api/")
public class CategoryController {
#RequestMapping(value="test4", method = RequestMethod.GET, produces = "text/plain;charset=UTF-8")
public ModelAndView pageTest4(HttpServletResponse response) {
ModelAndView model = new ModelAndView("elovendo/index");
response.setContentType("text/html");
response.setCharacterEncoding("UTF-8");
return model;
}
}
Application.properties:
#View resolver
spring.view.prefix= /WEB-INF/views/
spring.view.suffix= .jsp
Not sure if I'm missing something, I'll post everything you need.
Thank you in advance.
Your controller should be a #Controller not a #RestController, otherwise the response will be returned as a string as you observe.
As mentioned already in the comments your custom configuration is not needed at all, you could have a look at the sample provided by the Spring boot team https://github.com/spring-projects/spring-boot/tree/master/spring-boot-samples/spring-boot-sample-web-jsp.
Had the same issue.
It happens when you have your jsp in directory which is handled by ResourceHandler:
registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
This is only for static recourses - img, css, js.
You should move your jsp outside

Resources