2014-12-02 13 views
5

Mam aplikację, która działa idealnie, gdy uruchamiana jest przez IntelliJ lub za pomocą gradle bootRun.Spring Boot daje "TemplateInputException: Error resolving template" przy uruchomieniu ze słownika

jednak, jeśli robię Gradle bootRepackage a następnie spróbuj i uruchomić wynikającej słój, ja skończyć z:

2014-12-02 21:46:14.086 ERROR 9839 --- [nio-2014-exec-2] org.thymeleaf.TemplateEngine    : [THYMELEAF][http-nio-2014-exec-2] Exception processing template "/login": Error resolving template "/login", template might not exist or might not be accessible by any of the configured Template Resolvers 
2014-12-02 21:46:14.087 ERROR 9839 --- [nio-2014-exec-2] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] 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:245) 
    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) 

widzę, że słoik ma/szablony/** w nim zawartych. treść wygląda dla mnie dobrze. (?)

Jeden możliwe czynnikiem może być to, że używam strona html odnosząc się do układu, a więc:

layout:decorator="layouts/main" 

Mogę potwierdzić, że plik jest w słoiku.

/login definiuje thusly:

@Override 
public void addViewControllers(ViewControllerRegistry registry) { 
    registry.addViewController("/login").setViewName("/login"); 
    registry.addViewController("/").setViewName("/login"); 
} 

i ja bezpieczeństwo wiosna skonfigurowany jako:

@Configuration 
public class WebSecurityConfig extends WebSecurityConfigurerAdapter { 

@Override 
public void configure(WebSecurity security) { 
    security.ignoring().antMatchers("/assets/**"); 
} 

@Override 
protected void configure(HttpSecurity http) throws Exception { 
    http 
      .csrf().disable(); 
    http 
      .authorizeRequests() 
      .antMatchers("/").permitAll() 
      .anyRequest().authenticated(); 
    http 
      .formLogin() 
      .loginPage("/login") 
      .defaultSuccessUrl("/home") 
      .failureUrl("/login?error") 
      .permitAll() 
      .and() 
      .logout() 
      .invalidateHttpSession(true) 
      .logoutSuccessUrl("/login?logout") 
      .permitAll(); 
} 
} 

myślę, że to wszystko, co może mieć znaczenie w tej kwestii ...

Widziałem https://github.com/spring-projects/spring-boot/issues/112 i Proper location of Thymeleaf views for Spring (między innymi). Pomimo tych zasobów nie udało mi się uzyskać rozwiązania szablonu.

Wszelkie sugestie otrzymane z wdzięcznością.

Doszedłem do tej pory z Spring Boot, ale natknąłem się na ostatnią przeszkodę (ostateczne rozmieszczenie) jest dokuczliwy.

+0

Nic oczywiste skacze się na mnie i wiosna Boot ma próbkę zastosowań Thymeleaf z układem (https://github.com/spring-projects/spring- boot/drzewo/master/spring-boot-samples/spring-boot-sample-web-ui), więc nie sądzę, że to jest problem. Może spojrzenie na próbkę może pomóc dostrzec różnicę w konfiguracji Twojej aplikacji? –

Odpowiedz

4

Odpowiedź wydaje się być tutaj: https://github.com/spring-projects/spring-boot/issues/1744

W skrócie: jeśli ścieżka zawiera resouce „//”, coś pójdzie nie tak.

Rozwiązaniem jest modyfikacja application.yml wygląda następująco:

spring: 
    thymeleaf: 
    prefix: classpath:/templates 

(poprawka jest podobna do pliku .properties, oczywiście)

domina skutkiem jest to, że wszystkie odniesienia do szablonów lub cokolwiek trzeba być poprzedzone ukośnikiem, jak w (Thymeleaf pliku .html):

 layout:decorator="/layouts/main" 

lub Groovy (Controller):

@RequestMapping(value = "/home", method = RequestMethod.GET) 
def home(Model model, Principal principal) { 

    "/home/home" 
} 

I Myślę, że rozruch wiosenny powinien to naprawić. Pilnie. Jest to NAPRAWDĘ zła ergonomia, która bardzo źle wieje, właśnie w momencie, w którym wydaje się, że zbliża się ostateczne wdrożenie.

+0

Dzięki za wysłanie tego. To, co w końcu mi się udało, to dodać końcowe ukośniki do mojej własności. 'spring.thymeleaf.prefix = classpath:/templates /' – Derrek

+0

Niestety to nie rozwiązało problemu, mam dokładnie ten sam problem. Eclipse działa, a plik wykonywalny nie może rozwiązać szablonu ... :-( –

3

Dobra, znalazłem, gdzie trzeba przyjrzeć się bliżej. W klasach kontrolerów podczas używania klasy @RequestMapping nie ma ukośnika wiodącego (np. @RequestMapping("property")). Do metody potrzebujesz wiodącego ukośnika (np. @GetMapping("/list")) i wartości zwracanej bez ukośnika wiodącego (np.return "property/list";)

Przykład Fragment

@Controller 
@RequestMapping("property") 
public class PropertyController { 
    @NonNull PropertyService service; 

    @GetMapping("/list") 
    public String list() { 
     return "property/list"; 
    } 
} 
1

miałem sam problem za pomocą sprężyny z thymeleaf buta przez domyślne. Wszystko działało aż muszę spróbować .jar

komunikat mówi: ... org.thymeleaf.exceptions.TemplateInputException: Błąd rozwiązywania szablon „/ fragmenty/stopki”

Rozwiązałem z gry /, problemem było to, nie potrzebują cięcia.

zmieniłem to:

<footer class="footers" th:replace="/fragments/footer :: footer"> 

na to:

<footer class="footers" th:replace="fragments/footer :: footer"> 
+0

Wystąpił ten sam błąd i udało mi się go naprawić z powodu twojej odpowiedzi, więc dziękuję. – blitzen12

0

spring.thymeleaf.prefix = ścieżka klasy:/templates/

zmiana

@Override 
public void addViewControllers(ViewControllerRegistry registry) { 
    registry.addViewController("/login").setViewName("/login"); 
    registry.addViewController("/").setViewName("/login"); 
} 

do

@Override 
public void addViewControllers(ViewControllerRegistry registry) { 
    registry.addViewController("/login").setViewName("login"); 
    registry.addViewController("/").setViewName("login"); 
} 

nazwa widoku powinny być względna ścieżka