How to configure Spring mvc for static html files? - java

I have a spring MVC application with JSP pages. I understand that JSPs are outdated technology and want to change them to HTML files. But all the guides and stacktrace questions I'm seeing are from 4 to 8+ years ago.
Here is my config:
public class InitWebApp extends AbstractAnnotationConfigDispatcherServletInitializer {
#Override
protected Class<?>[] getRootConfigClasses() {
return new Class[] {ConfigWeb.class ,DataConfig.class, ConfigSecurity.class};
}
#Override
protected Class<?>[] getServletConfigClasses() {
return new Class[0];
}
#Override
protected String[] getServletMappings() {
return new String[] {"/"};
}
}
#Configuration
#EnableWebMvc
#ComponentScan({"Controller","Config","Services"})
public class ConfigWeb implements WebMvcConfigurer {
#Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/login").setViewName("view/LoginPage");
registry.addViewController("/").setViewName("index");
registry.addViewController("/curator").setViewName("view/Curator/curatorHome");
registry.addViewController("/student").setViewName("view/Student/studentHome");
registry.addViewController("/change").setViewName("view/ProfileChange");
registry.setOrder(Ordered.HIGHEST_PRECEDENCE);
}
#Override
public void addResourceHandlers(final ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
registry.addResourceHandler("/profilePictures/**").addResourceLocations("file:///${fullPath}/resources/profilePictures/");
registry.addResourceHandler("/profilePictures/**").addResourceLocations("file:///${fullPath}/web-resources/profilePictures/");
}
#Bean
public InternalResourceViewResolver viewResolver() {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setViewClass(JstlView.class);
viewResolver.setPrefix("/");
viewResolver.setSuffix(".jsp");
return viewResolver;
}
}
I've tried to experiment with changing view resolvers and resourceHandlers. As soon as I managed to make my Tomcat server find my index.html and open it on the start, my controllers stopped working.
Could you please help me with the direction in which I should move on?

Related

Resources are not loaded in Spring MVC with Java config

Firstly I was used WebMvcConfigurerAdapter in RootConfig, and the resources were connected, but I didn't deploy the Spring Security project.
#Configuration
#ComponentScan({"org.example"})
public class RootConfig extends WebMvcConfigurerAdapter {
}
Then I deleted WebMvcConfigurerAdapter from the class RootConfig, and the project became deployable, but the resources stopped working.
#Configuration
#ComponentScan({"org.example"})
public class RootConfig {
}
project structure
How I connect styles:
<link rel="stylesheet" href="${pageContext.request.contextPath}/resources/css/index.css">
My resource handler:
#Configuration
#EnableWebMvc
#ComponentScan({
"org.example",
"org.example.model",
"org.example.repo",
"org.example.service"
})
public class WebConfig implements WebMvcConfigurer {
#Bean
public ViewResolver viewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/views/");
resolver.setSuffix(".jsp");
return resolver;
}
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
}
}
SpringMvcDispatcherServletInitializer:
public class SpringMvcDispatcherServletInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
#Override
protected Class<?>[] getRootConfigClasses() {
return new Class[]{RootConfig.class};
}
#Override
protected Class<?>[] getServletConfigClasses() {
return new Class[]{WebConfig.class};
}
#Override
protected String[] getServletMappings() {
return new String[]{"/"};
}
}
try to override config method with web-security on resources like below and also if you are using thymleaf use # to represent URI href="#{/**/css/index.css}" or else check the path properly.
#Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/resources/*");
}
Use this syntax to access your css file
<link href="<c:url value="/resources/css/index.css />" rel="stylesheet">

JavaConfig Spring Web Flow returns 404 not found (JSP)

I have been trying out the Java Configuration feature of Spring Web Flow 2.4 by modifying an existing project from xml configuration to JavaConfig. The XML version works, but JavaConfig doesn't. Every time I try to start the flow with URL http://localhost:8080/sia_p219_ch08_spring_web_flow_order_pizza_customer_flow_complete/pizza , it returns 404. There are no exceptions. The console show no "no request mapping found for..." message. The webpage shows The origin server did not find a current representation for the target resource or is not willing to disclose that one exists.
The project is hosted on github, the working XML version is here.
I think the problem is the request URL doesn't call the pizza flow (/WEB-INF/flows/pizza/pizza-flow.xml).
Here are some code snippets:
WebAppInitializer:
#Override
protected Class<?>[] getRootConfigClasses() {
return new Class<?>[] { RootConfig.class };
}
#Override
protected Class<?>[] getServletConfigClasses() {
return new Class<?>[] { WebConfig.class };
}
#Override
// map DispatcherServlet to /
protected String[] getServletMappings() {
return new String[] { "/" };
}
RootConfig:
#Configuration
#Import({WebFlowConfig.class})
public class RootConfig {}
WebFlowConfig:
#Configuration
#ComponentScan({"pizza"})
public class WebFlowConfig extends AbstractFlowConfiguration {
static{
System.out.println("WebFlowConfig loaded");
}
#Autowired
private WebConfig webMvcConfig;
#Bean
public FlowDefinitionRegistry flowRegistry() {
return
getFlowDefinitionRegistryBuilder(flowBuilderServices())
.setBasePath("/WEB-INF/flows")
.addFlowLocationPattern("/**/*-flow.xml")
.build();
}
#Bean
public FlowExecutor flowExecutor(){
return getFlowExecutorBuilder(flowRegistry()).build();
}
#Bean
public FlowBuilderServices flowBuilderServices() {
return getFlowBuilderServicesBuilder()
.setViewFactoryCreator(mvcViewFactoryCreator())
.setDevelopmentMode(true)
.build();
}
#Bean
public MvcViewFactoryCreator mvcViewFactoryCreator() {
MvcViewFactoryCreator factoryCreator = new MvcViewFactoryCreator();
factoryCreator.setViewResolvers(Collections.singletonList(this.webMvcConfig.viewResolver()));
factoryCreator.setUseSpringBeanBinding(true);
return factoryCreator;
}
}
WebConfig
#Configuration
#EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {
static{
System.out.println("WebConfig loaded");
}
#Bean
public ViewResolver viewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/flows/");
resolver.setSuffix(".jsp");
return resolver;
}
// configure static content handling
#Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
The flow definition files and JSPs are fine and you can see them on github if you want.
Thanks a lot, any help is greatly appreciated.
What I've found so far that the configuration definitely lacks this part of configuration in WebFlowConfig (take a look at the documentation page for integration with Spring MVC for details):
#Bean
#Autowired
public FlowHandlerAdapter flowHandlerAdapter(FlowExecutor flowExecutor) {
FlowHandlerAdapter flowHandlerAdapter = new FlowHandlerAdapter();
flowHandlerAdapter.setFlowExecutor(flowExecutor);
return flowHandlerAdapter;
}
#Bean
#Autowired
public FlowHandlerMapping flowHandlerMapping(FlowDefinitionRegistry flowDefinitionRegistry) {
FlowHandlerMapping flowHandlerMapping = new FlowHandlerMapping();
flowHandlerMapping.setFlowRegistry(flowDefinitionRegistry);
flowHandlerMapping.setOrder(0);
return flowHandlerMapping;
}
Also remove mvcViewFactoryCreator definition and setViewFactoryCreator call from the flowBuilderServices bean definition as well. It works for me.

Can't start Spring project

I want to process the request with the controller without any logic inside only to return html page. Here the class with configurations and starter class:
#Configuration
#EnableWebMvc
public class MVCConfig extends WebMvcConfigurerAdapter {
#Bean
public InternalResourceViewResolver viewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/webapp/");
resolver.setSuffix(".html");
return resolver;
}
#Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/home").setViewName("NewPage");
}
}
public class WebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
#Override
protected Class<?>[] getRootConfigClasses() {
return new Class[] { MVCConfig.class };
}
#Override
protected Class<?>[] getServletConfigClasses() {
return null;
}
#Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
}
Apparently that's not enough to do it because when trying to get the page in browser I recieve 404 error.
What do I must to add or change to make it work?
Just to remind you that except the configuration must be complicated,u also need to publish your project as a war and deploy to Tomcat or whatever.
(how to package project as a war,such as maven,use the command "package")
Hope that will help.

Spring MVC loads blank webpage, but '/' is configured to load homepage. Setup done using no xml

I'm trying to build a Spring MVC application, using no XML. To load the application I am using a tomcat server. I want the homepage "home.html" to load, when I go to http://localhost:8080/.
I have followed many other spring mvc helloworld tutorials, but I can't see what I'm doing wrong. The webpage that loads, when I run the application is completely blank. When I inspect the html, it has an empty body. Any help is much appreciated.
Initialization class
public class WebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
#Override
protected String[] getServletMappings() {
return new String[]{"/"};
}
#Override
protected Class<?>[] getRootConfigClasses() {
return new Class<?>[] {ApplicationConfig.class};
}
#Override
protected Class<?>[] getServletConfigClasses() {
return new Class<?>[]{WebMvcConfig.class};
}
#Override
protected Filter[] getServletFilters() {
CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter();
characterEncodingFilter.setEncoding("UTF-8");
characterEncodingFilter.setForceEncoding(true);
DelegatingFilterProxy securityFilterChain = new DelegatingFilterProxy("springSecurityFilterChain");
return new Filter[] {characterEncodingFilter, securityFilterChain};
}
#Override
protected void customizeRegistration(ServletRegistration.Dynamic registration) {
registration.setInitParameter("defaultHtmlEscape", "true");
registration.setInitParameter("spring.profiles.active", "default");
}
}
MVC configuration
#Configuration
class WebMvcConfig extends WebMvcConfigurationSupport {
private static final String MESSAGE_SOURCE = "/WEB-INF/i18n/messages";
private static final String VIEWS = "/WEB-INF/views/";
private static final String RESOURCES_LOCATION = "/resources/";
private static final String RESOURCES_HANDLER = RESOURCES_LOCATION + "**";
#Override
public RequestMappingHandlerMapping requestMappingHandlerMapping() {
RequestMappingHandlerMapping requestMappingHandlerMapping = super.requestMappingHandlerMapping();
requestMappingHandlerMapping.setUseSuffixPatternMatch(false);
requestMappingHandlerMapping.setUseTrailingSlashMatch(false);
return requestMappingHandlerMapping;
}
#Bean(name = "messageSource")
public MessageSource messageSource() {
ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
messageSource.setBasename(MESSAGE_SOURCE);
messageSource.setCacheSeconds(5);
return messageSource;
}
#Bean
public ITemplateResolver templateResolver() {
SpringResourceTemplateResolver resolver = new SpringResourceTemplateResolver();
resolver.setPrefix(VIEWS);
resolver.setSuffix(".html");
resolver.setTemplateMode(TemplateMode.HTML);
resolver.setCacheable(false);
return resolver;
}
#Bean
public SpringTemplateEngine templateEngine() {
SpringTemplateEngine templateEngine = new SpringTemplateEngine();
templateEngine.setTemplateResolver(templateResolver());
templateEngine.addDialect(new SpringSecurityDialect()); //TODO no using Spring security
templateEngine.addDialect(new Java8TimeDialect());
return templateEngine;
}
#Bean
public ViewResolver viewResolver() {
ThymeleafViewResolver thymeleafViewResolver = new ThymeleafViewResolver();
thymeleafViewResolver.setTemplateEngine(templateEngine());
thymeleafViewResolver.setCharacterEncoding("UTF-8");
return thymeleafViewResolver;
}
#Override
public Validator getValidator() {
LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean();
validator.setValidationMessageSource(messageSource());
return validator;
}
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler(RESOURCES_HANDLER).addResourceLocations(RESOURCES_LOCATION);
}
#Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
/**
* Handles favicon.ico requests assuring no <code>404 Not Found</code> error is returned.
*/
#Controller
static class FaviconController {
#RequestMapping("favicon.ico")
String favicon() {
return "forward:/resources/images/favicon.ico";
}
}
}
Home controller
#Controller
public class HomeController {
#RequestMapping(value = "/")
public String index() {
return "home";
}
}
Here is what my views look like

Spring Boot internationalization (messages.properties)

I'm trying to simply add the version number of an application to a Thymeleaf fragment. I'm using Spring Boot 1.2.5. If I have a file named /resources/messages.properties defined like this:
application.version=1.0.0
And I have a Thymeleaf view with the following fragment:
Application Version: <span th:text="#{application.version}">
It's displaying something like ??application.version_en_US?? instead of 1.0.0. (I also have files named messages_en.properties and messages_en_US.properties in the classpath with the same contents too.) I am really not sure how to resolve this problem... I've spent hours on something which seems incredibly trivial...
Application.java
#SpringBootApplication
#ComponentScan(basePackages = {"org.application"})
#EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class, ThymeleafAutoConfiguration.class})
#PropertySources(value = {#PropertySource("classpath:website.properties")})
public class Application extends SpringBootServletInitializer {
public static void main(String[] args) throws Exception {
SpringApplication.run(Application.class, args);
}
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(Application.class);
}
}
WebConfig.java
#EnableWebMvc
#Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
#Bean
public SpelAwareProxyProjectionFactory projectionFactory() {
return new SpelAwareProxyProjectionFactory();
}
#Bean
public SessionHandler sessionHandler() {
return new SessionHandler();
}
#Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/web/auth/login").setViewName("auth/login");
registry.setOrder(Ordered.HIGHEST_PRECEDENCE);
}
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**").addResourceLocations(
"/resources/");
}
#Bean
public LocaleChangeInterceptor localeChangeInterceptor() {
LocaleChangeInterceptor localeChangeInterceptor = new LocaleChangeInterceptor();
localeChangeInterceptor.setParamName("language");
return localeChangeInterceptor;
}
#Bean
public CookieLocaleResolver localeResolver() {
CookieLocaleResolver localeResolver = new CookieLocaleResolver();
localeResolver.setDefaultLocale(Locale.ENGLISH);
return localeResolver;
}
#Bean
public ResourceBundleMessageSource messageSource() {
return new ResourceBundleMessageSource();
}
#Override
public void addInterceptors(InterceptorRegistry registry) {
// Locale change interceptor
registry.addInterceptor(localeChangeInterceptor());
// Utility interceptor which helps with the "active" link styles in the navigation. --mm
registry.addInterceptor(new BaseInterceptor());
// Expire session after a period of time
registry.addInterceptor(sessionHandler());
}
}
ThymeleafConfig.java
#Configuration
public class ThymeleafConfig {
#Bean
public ServletContextTemplateResolver templateResolver() {
ServletContextTemplateResolver resolver = new ServletContextTemplateResolver();
resolver.setPrefix("/WEB-INF/views/");
resolver.setSuffix(".html");
// must use Legacy HTML5 as the template, otherwise Handlebars will not parse!
//
// this should hopefully be fixed in Thymeleaf 3.0
resolver.setTemplateMode("LEGACYHTML5");
resolver.setCacheable(false);
return resolver;
}
public SpringTemplateEngine templateEngine() {
SpringTemplateEngine engine = new SpringTemplateEngine();
engine.setTemplateResolver(templateResolver());
// Add Spring security
Set<IDialect> dialects = new HashSet<IDialect>();
engine.setAdditionalDialects(dialects);
engine.addDialect(new SpringSecurityDialect());
return engine;
}
#Bean
public ViewResolver viewResolver() {
ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
viewResolver.setTemplateEngine(templateEngine());
viewResolver.setOrder(1);
viewResolver.setViewNames(new String[]{"*"});
viewResolver.setCache(false);
return viewResolver;
}
}
Will buy a virtual round of shots to whomever can resolve this issue...
i guess you could always add this in your templateEngine method:
engine.addMessageResolver(new StandardMessageResolver());
or engine.setMessageResolver(new StandardMessageResolver());
Also,from the design perspective,i would suggest you to try using the autoconfiguration for thymeleaf(removing the exclude),and many other stuff which spring boot provides automatically for you.

Categories

Resources