2014-05-09 5 views
1

나는 큰 프로젝트에서 과거에 Spring과 함께 일해 왔지만 처음부터 스프링 MVC 웹 앱을 시작한 적이 없다.봄 - Thymeleaf - 404 오류

글쎄, 지금 내가 연습을 위해 지금하고있는 것은 그것이 프로젝트를 필요로 할 때이다.

주석을 사용하고 XML을 사용하지 않고 .JSP 페이지를 사용하는 간단한 Spring MVC 웹 응용 프로그램을 만들 수있었습니다. 나는 Thymeleaf를 사용하고 싶었고 그것을 변환하기 시작했습니다.

이제 404 오류가 발생하고 HomeController 클래스가 충돌하는 것조차 보이지 않습니다.

콘솔 출력에 오류가 없습니다.

Google 검색, 가이드 및 코드 샘플을 읽었습니다. 두 번째 눈 쌍이 좋을 것입니다. 감사! :)

참고 : .JSP에서 Thymeleaf 로의 변경 사항은 ThymeleafConfig 클래스가 추가 된 것입니다. 나는 그것이 일하는 것에서부터 일하는 것이 어떻게되었는지 보지 못한다. 여기

내 코드입니다 :

WebInit.java

public class WebInit implements WebApplicationInitializer { 

@Override 
public void onStartup(ServletContext servletContext) 
     throws ServletException { 
    // Creates the root application context 
    AnnotationConfigWebApplicationContext appContext = new AnnotationConfigWebApplicationContext(); 
    appContext.register(ServletConfig.class); 
    appContext.setDisplayName("REPLACE ME"); 
    appContext.setConfigLocation("com.demo.config"); 

    // Creates the Spring Container shared by all Servlets and Filters 
    servletContext.addListener(new ContextLoaderListener(appContext)); 

    // Further configures the servlet context 
    ServletRegistration.Dynamic dispatcher = servletContext.addServlet(
      "dispatcher", new DispatcherServlet(appContext)); 
    dispatcher.setLoadOnStartup(1); 
    dispatcher.setAsyncSupported(true); 
    dispatcher.addMapping("/"); 
} 
} 

ServetConfig.java

@Configuration 
@Import(WebConfig.class) 
@ImportResource({ 
    //"classpath:META-INF/spring/persistence-context.xml", 
}) 
public class ServletConfig { 

} 

WebConfig.java

@Configuration 
@ComponentScan("com.illinois.dnr") 
@EnableAspectJAutoProxy 
@EnableWebMvc 
@Import({ThymeleafConfig.class}) 
public class WebConfig extends WebMvcConfigurerAdapter { 
    // Maps resources path to webapp/resources 
    @Override 
    public void addResourceHandlers(ResourceHandlerRegistry registry) { 
     registry.addResourceHandler("/resources/**").addResourceLocations(
       "/resources/"); 
    } 

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

Thymeleaf.java

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

HomeController.java 당신이 공격하려는 어떤 페이지

@Controller 
public class HomeController { 

    private static final Logger logger = LoggerFactory.getLogger(HomeController.class); 

    /** 
    * Simply selects the home view to render by returning its name. 
    */ 
    @RequestMapping(value = "/dnr", method = RequestMethod.GET) 
    public String home(Locale locale, Model model) { 
     logger.info("Welcome home! The client locale is {}.", locale); 
     Date date = new Date(); 
     DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, 
       DateFormat.LONG, locale); 
     String formattedDate = dateFormat.format(date); 
     model.addAttribute("serverTime", formattedDate); 
     return "home"; 
    } 

    @RequestMapping(value = "/login", method = RequestMethod.GET) 
    public String loginPage(Locale locale, Model model) { 
     logger.info("Login"); 
     return "login"; 
    } 

    @RequestMapping(value = "/home", method = RequestMethod.POST) 
    public String login(@Validated User user, Model model) { 
     model.addAttribute("userName", user.getUserName()); 
     logger.info("User"); 
     return "user"; 
    } 

    @RequestMapping(value = { "/", "/welcome**" }, method = RequestMethod.GET) 
    public ModelAndView welcomePage() { 

     ModelAndView model = new ModelAndView(); 
     model.addObject("title", "Spring Security Hello World"); 
     model.addObject("message", "This is welcome page!"); 
     model.setViewName("hello"); 
     logger.info("Hello"); 
     return model; 
    } 

    @RequestMapping(value = "/admin**", method = RequestMethod.GET) 
    public ModelAndView adminPage() { 

     ModelAndView model = new ModelAndView(); 
     model.addObject("title", "Spring Security Hello World"); 
     model.addObject("message", "This is protected page - Admin Page!"); 
     model.setViewName("admin"); 
     logger.info("admin"); 
     return model; 
    } 

    @RequestMapping(value = "/dba**", method = RequestMethod.GET) 
    public ModelAndView dbaPage() { 

     ModelAndView model = new ModelAndView(); 
     model.addObject("title", "Spring Security Hello World"); 
     model.addObject("message", "This is protected page - Database Page!"); 
     model.setViewName("admin"); 
     logger.info("dba"); 
     return model; 
    } 
} 
+0

사용하여 STS와 – MSwezey

+0

tomcat7 말할 수있는 스택 추적이 있습니까? 또한'ThymeleafConfig' 메쏘드에'System.out.println() '을 넣어서 그것들이 실행 중인지 확인할 수 있습니까? Thymeleaf 템플릿은 모두 WEB-INF/views에 있습니까? – CodeChimp

+0

당신은 localhost : 8080/appName/dnr으로 가야하며 페이지는 WEB-INF/views/dnr.html –

답변

1

처럼

이 도움이 있는지 확실하지 않습니다 대신 구현 WebApplicationInitializerAbstractAnnotationConfigDispatcherServletInitializer을 확장하여이 WebInit을 단순화 할 수 있습니다. 그렇지 않으면 Thymeleaf 구성이 나에게 괜찮은 것 같습니다 (호출 된 것으로 가정). 여기에 실험용 스켈레톤을 주어서 실험 해 볼 수 있습니다.

WebApplicationInitializer

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[] { "/" }; 
    } 

} 

WebConfig

@Configuration 
@EnableWebMvc 
@ComponentScan("com.kreuzman") 
public class WebConfig { 

    @Bean 
    public ITemplateResolver templateResolver() { 
     TemplateResolver resolver = new ServletContextTemplateResolver(); 
     resolver.setPrefix("/templates/"); 
    resolver.setSuffix(".html"); 
     resolver.setTemplateMode("HTML5"); 
     resolver.setCacheTTLMs(0l); 

     return resolver; 
    } 

    @Bean 
    public SpringTemplateEngine templateEngine() { 
     SpringTemplateEngine engine = new SpringTemplateEngine(); 
     engine.setTemplateResolver(templateResolver()); 

     return engine; 
    } 

    @Bean 
    public ViewResolver thymeleafViewResolver() { 
     ThymeleafViewResolver viewResolver = new ThymeleafViewResolver(); 
     viewResolver.setTemplateEngine(templateEngine()); 
     viewResolver.setCharacterEncoding("UTF-8"); 

     return viewResolver; 
    } 

} 
+0

고마워요! Spring Web App 기반의 순수 주석 기반 Spring Web App을 원한다면 도움이되기를 바랍니다. 몇 가지 자습서와 도움말 가이드를 찾았지만, 모두 자신의 "스타일"을 가지고 있습니다. 마지막으로 Spring MVC-Security-WebFlow, Hibernate 및 Thymeleaf 프로젝트의 작동 예제를 발견했습니다. 설정 파일은 해골과 비슷하게 설정됩니다. 이 길을 확실히하고있어. 훨씬 더 청결한. 감사 – MSwezey

1

? 해당 HTML 페이지가/WEB-INF/views /에 있습니까?

JSP 페이지입니까? ThymeleafViewResolver가 해결하지 않을 모든 페이지를 제외해야합니다. 또한 ThymeleafViewResolver를 첫 번째 순서로 설정하지 않은 것으로 나타났습니다. 그래서

@Bean 
public ThymeleafViewResolver thymeleafViewResolver() 
{ 
    String[] excludedViews = new String[]{ 
     "login", "logout"}; 

    ThymeleafViewResolver resolver = new ThymeleafViewResolver(); 
    resolver.setTemplateEngine(templateEngine()); 
    /* 
    * This is how we get around Thymeleaf view resolvers throwing an error instead of returning 
    * of null and allowing the next view resolver in the {@see 
    * DispatcherServlet#resolveViewName(String, Map<String, Object>, Locale, 
    * HttpServletRequest)} to resolve the view. 
    */ 
    resolver.setExcludedViewNames(excludedViews); 
    resolver.setOrder(1); 
    return resolver; 
} 
+0

setOrder (1) 설정을 시도했지만 작동하지 않았습니다. 나는 프로젝트를 삭제하고 처음부터 다시 시작했다. 이번에 유일한 차이점은 다음과 같습니다. javax 6.0 – MSwezey

+0

.JSP와 .html 페이지를 모두 지원하려면 .JSP 페이지를 제외해야했습니다. 감사합니다. – MSwezey