2015-02-24 165 views
1

我下面爲構建春春+ +安全+ Thymeleaf Maven項目一個簡單的在線教程,我發現了以下錯誤:彈簧MVC +彈簧安全+ Thymeleaf - 錯誤解決模板

[ERROR] [tomcat-http--4 02:00:16] (TemplateEngine.java:process:1085) [THYMELEAF][tomcat-http--4] Exception processing template "login": Error resolving template "login", template might not exist or might not be accessible by any of the configured Template Resolvers 
Feb 24, 2015 2:00:16 PM org.apache.catalina.core.StandardWrapperValve invoke 
SEVERE: Servlet.service() for servlet [dispatcher] in context with path [/hub] threw exception [Request processing failed; nested exception is org.thymeleaf.exceptions.TemplateInputException: Error resolving template "login", template might not exist or might not be accessible by any of the configured Template Resolvers] with root cause 
org.thymeleaf.exceptions.TemplateInputException: Error resolving template "login", template might not exist or might not be accessible by any of the configured Template Resolvers 
at org.thymeleaf.TemplateRepository.getTemplate(TemplateRepository.java:246) 
at org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1104) 
at org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1060) 
at org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1011) 
at org.thymeleaf.spring4.view.ThymeleafView.renderFragment(ThymeleafView.java:335) 
at org.thymeleaf.spring4.view.ThymeleafView.render(ThymeleafView.java:190) 
at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1228) 
at org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1011) 
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:955) 
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:877) 
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:966) 
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:857) 
at javax.servlet.http.HttpServlet.service(HttpServlet.java:618) 
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:842) 
at javax.servlet.http.HttpServlet.service(HttpServlet.java:725) 
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:291) 
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) 
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) 
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239) 
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) 
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) 
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:118) 
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:84) 
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) 
at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:113) 
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) 
at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:103) 
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) 
at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:113) 
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) 
at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:154) 
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) 
at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:45) 
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) 
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:199) 
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) 
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:110) 
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) 
at org.springframework.security.web.csrf.CsrfFilter.doFilterInternal(CsrfFilter.java:85) 
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) 
at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:57) 
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) 
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87) 
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) 
at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:50) 
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) 
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192) 
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160) 
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:344) 
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:261) 
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239) 
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) 
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:219) 
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106) 
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:501) 
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:142) 
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79) 
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:610) 
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88) 
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:537) 
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1085) 
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:658) 
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:146) 
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:279) 
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) 
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) 
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) 
at java.lang.Thread.run(Thread.java:745) 

由於某些原因,它不會解析登錄頁面,但即使登錄頁面位於正確的位置。如果我指向頁面加載的users.html頁面並且沒有錯誤。必須是非常簡單的東西,我錯過了。有人可以協助嗎?

以下是我的配置類:

public class ApplicationInitializer implements WebApplicationInitializer { 

@Override 
public void onStartup(ServletContext servletContext) throws ServletException { 
    //Load application context 
    AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext(); 
    rootContext.register(ApplicationContext.class); 
    rootContext.setDisplayName("hub"); 

    //Context loader listener 
    servletContext.addListener(new ContextLoaderListener(rootContext)); 

    //Dispatcher servlet 
    ServletRegistration.Dynamic dispatcher = 
      servletContext.addServlet("dispatcher", new DispatcherServlet(rootContext)); 
    dispatcher.setLoadOnStartup(1); 
    dispatcher.addMapping("/"); 
} 

} 

的ApplicationContext類:

@Configuration 
@ComponentScan(basePackages = {"com.motodoc.hub.*"}) 
@EnableWebMvc 
@Import({SpringDataConfig.class, ThymeleafConfig.class, SecurityConfig.class}) 
@ImportResource("classpath:trace-context.xml") 
@PropertySource("classpath:spring.properties") 
public class ApplicationContext extends WebMvcConfigurerAdapter { 

// Maps resources path to webapp/resources 
@Override 
public void addResourceHandlers(ResourceHandlerRegistry registry) { 
    registry.addResourceHandler("/resources/**").addResourceLocations("/resources/"); 
} 

// Only needed if we are using @Value and ${...} when referencing properties 
@Bean 
public static PropertySourcesPlaceholderConfigurer properties() { 
    PropertySourcesPlaceholderConfigurer propertySources = new PropertySourcesPlaceholderConfigurer(); 
    Resource[] resources = new ClassPathResource[] { 
      new ClassPathResource("spring.properties") }; 
    propertySources.setLocations(resources); 
    propertySources.setIgnoreUnresolvablePlaceholders(true); 
    return propertySources; 
} 

// Provides internationalization of messages 
@Bean 
public ResourceBundleMessageSource messageSource() { 
    ResourceBundleMessageSource source = new ResourceBundleMessageSource(); 
    source.setBasename("messages"); 
    return source; 
} 
} 

ThymeleafConfig類:

@Configuration 
public class ThymeleafConfig { 

@Bean 
public ServletContextTemplateResolver templateResolver() { 
    ServletContextTemplateResolver resolver = new ServletContextTemplateResolver(); 
    resolver.setPrefix("/WEB-INF/views/"); 
    resolver.setSuffix(".html"); 
    resolver.setTemplateMode("HTML5"); 
    resolver.setOrder(1); 
    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; 
} 
} 

SpringSecurityConfig類:

@Configuration 
@EnableWebSecurity 
public class SecurityConfig extends WebSecurityConfigurerAdapter { 

@Autowired 
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { 
    auth.inMemoryAuthentication().withUser("mkyong").password("123456").roles("USER"); 
    auth.inMemoryAuthentication().withUser("admin").password("123456").roles("ADMIN"); 
    auth.inMemoryAuthentication().withUser("dba").password("123456").roles("DBA"); 
} 

@Override 
public void configure(WebSecurity web) throws Exception { 
    web.ignoring().antMatchers("/resources/**"); 
    } 

@Override 
protected void configure(HttpSecurity http) throws Exception 
{ 
    http 
     .authorizeRequests() 
     .antMatchers("/**").authenticated() 
     .antMatchers("/resources/**").permitAll() 
     .anyRequest().authenticated() 
     .and() 
    .formLogin() 
     .loginPage("/login") 
     .permitAll() 
     .defaultSuccessUrl("/users") 
     //.failureUrl("/login.html?authfailed=true") 
     .and() 
    .logout() 
     .invalidateHttpSession(true) 
     .logoutUrl("/logout") 
     .deleteCookies("JSESSIONID") 
     .logoutSuccessUrl("/"); 
} 
} 

SecurityInit類:

public class SecurityInit extends AbstractSecurityWebApplicationInitializer { 

} 

Screenshot of project folders and files

+0

你確定你是不是混亂的頁面和模板? – mylenereiners 2015-02-24 14:21:21

+0

如果你給頁面命名爲'login2',會發生什麼?由於Spring Security提供了默認的表單,因此可能會出現一些令人驚訝的問題,特定的名稱「login」。 – chrylis 2015-02-24 14:31:48

+0

@mylenereiners這不是問題。 Thymeleaf模板是HTML頁面。 – chrylis 2015-02-24 14:32:13

回答

0

也許你有thymeleaf和springSecurity的解析器的衝突。您已將loginPage配置設置爲「登錄」,並且thymeleaf期待「login.html」。您是否嘗試更改.loginPage(「/ login.html」)的.loginPage(「/ login」)?

0

只需從配置中刪除後綴代碼即可。

resolver.setSuffix(".html"); 
-1

在ThymeleafProperties類的意見則默認前綴爲classpath:/templates/,默認後綴爲.html。因此,改變你的htmlsrc/main/resources/templates/login.html,如下面的圖像

Image depicting the file naming notation