Spring Boot nie obsługuje zawartości statycznej

173

Nie mogę sprawić, by mój projekt Spring-boot obsługiwał zawartość statyczną.

Umieściłem folder o nazwie staticpod src/main/resources. Wewnątrz mam folder o nazwie images. Kiedy pakuję aplikację i ją uruchamiam, nie może znaleźć obrazów, które umieściłem w tym folderze.

Starałem się umieścić pliki w statycznych public, resourcesa META-INF/resourcesjednak nic nie działa.

Jeśli ja jar -tvf app.jar widzę, że pliki znajdują się wewnątrz jar we właściwym folderze: /static/images/head.pngna przykład, ale dzwoniąc :, http://localhost:8080/images/head.pngwszystko, co otrzymuję, to404

Jakieś pomysły, dlaczego spring-boot tego nie znajduje? (Używam wersji 1.1.4 BTW)

Vinicius Carvalho
źródło
6
Domyślna obsługa zasobów jest mapowana na / **. Dokładnie sprawdziłbym, czy jest włączony. Jeśli tak jest, po uruchomieniu aplikacji zobaczysz wiersz kończący się wyrażeniem „Ścieżka mapowanego adresu URL [/ **] do modułu obsługi typu [klasa org.springframework.web.servlet.resource.ResourceHttpRequestHandler]”. Inną możliwością jest twój własny kontroler, który jest również mapowany na / ** i ma pierwszeństwo przed obsługą zasobów. Opublikowanie danych wyjściowych uruchomienia Twojej aplikacji ułatwiłoby nam sprawdzenie, co się dzieje.
Andy Wilkinson
12
Domyślam się, że masz @EnableWebMvc(lub odpowiednik) w swojej aplikacji. To wyłączyłoby domyślną konfigurację Boot MVC.
Dave Syer,
1
Nie, nigdzie nie mam @EnableWebMvc. Nie rozumiem tego. Teraz dzieje się to również z szablonami. Każdy z moich szablonów (freemarker) jest znajdowany przez program ładujący klasy Spring Boot.
Vinicius Carvalho
2
Mam podobny problem i nie miałem szczęścia z żadną z zalecanych rozdzielczości. Gdyby ktoś był tak miły, aby spojrzeć i dokładnie wskazać, co robię źle, byłoby to bardzo mile widziane !!! github.com/kylebober/kbss
Kyle S. Bober
3
Zauważyłem, że jeśli mam plik src / main / resources / public / style.css, to adres URL to /style.css, a nie /public/style.css, jak się spodziewałem.
Dave

Odpowiedzi:

179

Nie wskrzeszać zmarłych po ponad roku, ale wszystkie poprzednie odpowiedzi pomijają kilka kluczowych punktów:

  1. @EnableWebMvcna twojej klasie wyłączy się org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration. To dobrze, jeśli chcesz mieć pełną kontrolę, ale poza tym jest to problem.
  2. Nie ma potrzeby pisania żadnego kodu, aby dodać inną lokalizację dla zasobów statycznych oprócz tego, co już zostało udostępnione. Patrząc na org.springframework.boot.autoconfigure.web.ResourcePropertieswersję 1.3.0.RELEASE, widzę pole, staticLocationsktóre można skonfigurować w application.properties. Oto fragment ze źródła:

    /**
     * Locations of static resources. Defaults to classpath:[/META-INF/resources/,
     * /resources/, /static/, /public/] plus context:/ (the root of the servlet context).
     */
    private String[] staticLocations = RESOURCE_LOCATIONS;
  3. Jak wspomniano wcześniej, adres URL żądania zostanie rozwiązany względem tych lokalizacji. W ten sposób src/main/resources/static/index.htmlzostanie obsłużony, gdy adres URL żądania to /index.html. Klasa odpowiedzialna za rozwiązywanie ścieżki, od wersji Spring 4.1, to org.springframework.web.servlet.resource.PathResourceResolver.

  4. Dopasowywanie wzorca sufiksu jest domyślnie włączone, co oznacza, że ​​w przypadku adresu URL żądania /index.htmlSpring będzie szukał programów obsługi odpowiadających /index.html. Jest to problem, jeśli intencją jest dostarczanie treści statycznych. Aby to wyłączyć, rozszerz WebMvcConfigurerAdapter(ale nie używaj @EnableWebMvc) i zastąp, configurePathMatchjak pokazano poniżej:

    @Override
    public void configurePathMatch(PathMatchConfigurer configurer) {
        super.configurePathMatch(configurer);
    
        configurer.setUseSuffixPatternMatch(false);
    }

IMHO, jedynym sposobem, aby mieć mniej błędów w kodzie, jest nie pisać kodu, gdy tylko jest to możliwe. Skorzystaj z tego, co już zostało dostarczone, nawet jeśli wymaga to pewnych badań, zwrot jest tego wart.

Abhijit Sarkar
źródło
3
ta odpowiedź jest rzeczywiście po wielu badaniach. Świetny do przeczytania
Ekansh Rastogi
2
Gdybym był kluczowy, wziąłbym tę odpowiedź i umieściłbym ją w dokumentacji Spring Boot
aliopi
2
@Abhijit Sarkar Miałem na myśli firmę Pivotal , przepraszam za złe uczucia, ale nie było to zamierzone. Pivotal jest właścicielem Spring, jeśli mam rację. Mógłbym to udokumentować, ale mają ludzi, którym za to płacą, więc powinni to zrobić: P
aliopi
1
@aliopi Spring to projekt open source.
Abhijit Sarkar
3
Jedynym sposobem, aby mieć mniej błędów w kodzie, jest nie pisać [...] kodu naprawdę takiego, jak ten.
Clijsters
78

W przeciwieństwie do tego, co stwierdza spring-boot, aby mój spring-boot jar obsługiwał zawartość: musiałem specjalnie zarejestrować moją zawartość src / main / resources / static za pomocą tej klasy konfiguracyjnej:

@Configuration
public class StaticResourceConfiguration implements WebMvcConfigurer {

    private static final String[] CLASSPATH_RESOURCE_LOCATIONS = {
            "classpath:/META-INF/resources/", "classpath:/resources/",
            "classpath:/static/", "classpath:/public/" };

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/**")
            .addResourceLocations(CLASSPATH_RESOURCE_LOCATIONS);
    }
}
Francois
źródło
3
Mam ten sam problem, tę samą wersję Spring Boot, ale to też mi nie
pomogło
Naprawiono mój problem w wersji 1.2.5 !! dziękuję bardzo .. zagłosuj na to !!
mrclrchtr
Ten hack działa ... dziwne, że automatyczna konfiguracja się nie udaje
Allan Vital
Niestety ten hack nie działa dla mnie, a szkoda ze względu na elegancję. Nie jestem pewien, czy główną przyczyną są ścieżki do zasobu. Być może skoro uruchamiam go w systemie Windows, trzeba je inaczej sformatować?
acarlstein
50

Miałem podobny problem i okazało się, że prostym rozwiązaniem było rozszerzenie mojej klasy konfiguracji WebMvcAutoConfiguration:

@Configuration
@EnableWebMvc
@ComponentScan
public class ServerConfiguration extends WebMvcAutoConfiguration{
}

Nie potrzebowałem żadnego innego kodu, aby umożliwić obsługę mojej statycznej zawartości, jednak umieściłem katalog o nazwie publicunder src/main/webappi skonfigurowałem maven tak, aby wskazywał src/main/webappjako katalog zasobów. Oznacza to, że publicjest kopiowany do target/classes, a zatem znajduje się w ścieżce klas w czasie wykonywania, aby spring-boot / tomcat mógł znaleźć.

Inżynier oprogramowania
źródło
W ten sposób statyczne zasoby nie działają w innych profilach. na przykład mam profil do wydania, który używa innego adresu IP. Otrzymuję błąd 404 dla wszystkich moich zasobów.
Mahdi,
24

Poszukaj kontrolerów zamapowanych na „/” lub bez mapowanych ścieżek.

Miałem taki problem, otrzymywałem 405 błędów i przez wiele dni mocno waliłem w głowę. Problemem okazał się @RestControllerkontroler z adnotacjami, do którego zapomniałem dodać @RequestMappingadnotację. Domyślam się, że ta zmapowana ścieżka ma wartość domyślną „/” i blokuje mapowanie zasobów zawartości statycznej.

Johannes
źródło
1
Rozwiązałem to za mnie! Miałem kontroler z adnotacją @RestController ("/ blubb"), co jest oczywiście błędne, ale czasami nie widzisz drewna dla drzew. Zmiana na @RestController @RequestMapping ("/ blubb") rozwiązała problem
krinklesaurus
Cieszę się, że pomogło i rozbawiło mnie stwierdzenie, że wyrażenie „Nie widzę lasu ze wszystkich drzew” istnieje zarówno w języku niemieckim, jak i szwedzkim :)
Johannes
2
Możesz także jawnie dodać @RequestMapping („/”), jeśli celem jest zarówno udostępnianie treści statycznej, jak i dynamiczna obsługa żądań roota.
mjj1409
1
Wow .... Spędziłem na tym 2 zmarnowane dni. Moja aplikacja Spring Boot Mvc używa zabezpieczeń Spring i nie widziała pliku styles.css. Uważam, że zabezpieczenia nie zezwalały plikom .jsp na dostęp do pliku styles.css. W kontrolerze miałem @RequestMapping ({"", "/", "/ home"}). Usunąłem „” i „/” i mój MVC zaczął działać idealnie ... Bardzo dziwne.
skmansfield
3
@Shafiul Nie Dodanie zarówno EnableAutoConfiguration, jak i SpringBootApplication jest zbędne! „@SpringBootApplication” zawiera „@EnableAutoConfiguration”
Dehan de Croos,
19

Konfigurację można wykonać w następujący sposób:

@Configuration
@EnableWebMvc
public class WebMvcConfig extends WebMvcAutoConfigurationAdapter {

// specific project configuration

}

Ważne jest tutaj, że twoja metoda WebMvcConfig może przesłonić addResourceHandlersi dlatego musisz jawnie wywołać super.addResourceHandlers(registry)(prawdą jest, że jeśli jesteś zadowolony z domyślnych lokalizacji zasobów, nie musisz nadpisywać żadnej metody).

Inną rzeczą, którą należy skomentował tutaj jest to, że te lokalizacje domyślne zasobów ( /static, /public, /resourcesi /META-INF/resources) będą rejestrowane tylko wtedy, gdy nie ma już obsługi zasobów odwzorowywane na /**.

Od tego momentu, jeśli masz na przykład obraz src/main/resources/static/imagesnazwany image.jpg, możesz uzyskać do niego dostęp za pomocą następującego adresu URL: http://localhost:8080/images/image.jpg(serwer uruchomiony na porcie 8080 i aplikacja wdrożona w kontekście głównym).

Francisco Spaeth
źródło
Być może ważne jest, aby skomentować, że chociaż możesz / możesz / przesłonić addResourceHandlers, w rzeczywistości nie musisz tego robić, aby rozwiązać problem OP.
Inżynier oprogramowania,
@EngineerDollery dzięki za komentarz, taki był mój zamiar, ale wyraźnie dodałem wyjaśnienie
Francisco Spaeth
Przeniosłem mój css / js do folderu src / main / resources / static i błędów już tam nie ma, ale nadal nie mogę wyświetlić css na mojej stronie.
Hatem Jaber
Koleś, przemierzyłem głębiny internetu, aby znaleźć to działające rozwiązanie. Wygląda na to, że kluczem była kombinacja @EnableWebMvci WebMvcAutoConfigurationAdapter. Wielkie dzięki!
Ian Newland
Dla mnie też nie wyszło z pudełka. Musiałem to również dodać. Po prostu dodaję tutaj swój komentarz, ponieważ miałem dwa problemy. Miałem też kontroler, który mapował „/”, jak wspomina @Johannes. Wykonanie tego i usunięcie kontrolera „/” rozwiązało moje problemy.
loyalBrown
11

Czy sprawdziłeś dokumentację dotyczącą Spring Boot ?

Domyślnie Spring Boot będzie obsługiwać statyczną zawartość z folderu o nazwie /static(lub /publiclub /resourceslub /META-INF/resources) w ścieżce klas lub z katalogu głównego ServletContext.

Możesz również porównać swój projekt z przewodnikiem Udostępnianie treści internetowych za pomocą Spring MVC lub sprawdzić kod źródłowy projektu spring-boot-sample-web-ui .

matsev
źródło
2
Tak, zrobiłem, to są miejsca, których próbowałem, tak jak poinstruowali doktorzy. Ale nic nie działa. Nie rozumiem, dlaczego w ogóle nie znaleziono zasobu. Próbowałem przyjrzeć się próbkom, co dziwne, nie ma próbki, która używa struktury zaproponowanej przez dokumentację. Ten, który właśnie wkleiłeś, używa folderu szablonów, zakładam, że jest to konfiguracja lub prędkość grasicy.
Vinicius Carvalho
Przykładowy interfejs użytkownika sieci Web ( github.com/spring-projects/spring-boot/tree/v1.1.3.RELEASE/ ... ) zawiera zawartość statyczną.
Andy Wilkinson,
Zgadzam się z @ViniciusCarvalho, próbowałem każdej możliwej kombinacji, aby uzyskać css / js we właściwym miejscu i nie mogę tego zrobić. Nawet jeśli odwiedzę localhost: 8089 / css / styles.css, nic nie widzę. Mam tylko jedną zasadę, aby zmienić kolor ciała.
Hatem Jaber
10

Miałem dokładnie ten problem, a potem zdałem sobie sprawę, że zdefiniowałem w mojej application.properties:

spring.resources.static-locations=file:/var/www/static

Co przeważało nad wszystkim, czego próbowałem. W moim przypadku chciałem zachować oba, więc po prostu zachowałem nieruchomość i dodałem:

spring.resources.static-locations=file:/var/www/static,classpath:static

Który udostępnił pliki z src / main / resources / static jako localhost: {port} /file.html.

Żadne z powyższych nie zadziałało dla mnie, ponieważ nikt nie wspomniał o tej małej właściwości, którą można łatwo skopiować z Internetu, aby służyć innym celom;)

Mam nadzieję, że to pomoże! Pomyślałem, że będzie dobrze pasował do tego długiego postu z odpowiedziami dla osób z tym problemem.

S. Jacob Powell
źródło
Używam Spring Boot 2.0.5.RELEASE i umieszczam spring.resources.static-locations=file:/var/www/static,classpath:staticw pliku application.properties, ale to nie zadziałało. Używam @EnableWebMvcw mojej klasie konfiguracji.
N. Ngo
To był ten, który rozwiązał mój problem. wraz z security.ignoredisecurity.publicPaths
JoSSte
5

Myślę, że poprzednie odpowiedzi bardzo dobrze odnoszą się do tematu. Dodam jednak, że w jednym przypadku, gdy w aplikacji włączono Spring Security, być może będziesz musiał wyraźnie powiedzieć Springowi, aby zezwolił na żądania do innych statycznych katalogów zasobów, takich jak na przykład „/ static / fonts” .

W moim przypadku domyślnie dozwolone były "/ static / css", "/ static / js", "/ static / images", ale / static / fonts / ** zostało zablokowane przez moją implementację Spring Security.

Poniżej znajduje się przykład, jak to naprawiłem.

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
.....
    @Override
    protected void configure(final HttpSecurity http) throws Exception {
        http.authorizeRequests().antMatchers("/", "/fonts/**").permitAll().
        //other security configuration rules
    }
.....
}
RemusS
źródło
5

Żeby dodać jeszcze jedną odpowiedź na stare pytanie ... Wspomniano już o @EnableWebMvczapobieganiu WebMvcAutoConfigurationładowaniu, czyli kodzie odpowiedzialnym za tworzenie statycznych procedur obsługi zasobów. Istnieją również inne warunki, które również uniemożliwiają WebMvcAutoConfigurationładowanie. Najlepszym sposobem, aby to zobaczyć, jest spojrzenie na źródło:

https://github.com/spring-projects/spring-boot/blob/master/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/ WebMvcAutoConfiguration.java # L139-L141

W moim przypadku włączyłem bibliotekę, która miała klasę, z WebMvcConfigurationSupportktórej rozszerzała się, co jest warunkiem uniemożliwiającym autokonfigurację:

@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)

Ważne jest, aby nigdy nie wychodzić z WebMvcConfigurationSupport. Zamiast tego rozszerz WebMvcConfigurerAdapter.

UPDATE: Właściwym sposobem na zrobienie tego w 5.x jest zaimplementowanie WebMvcConfigurer

Bal
źródło
WebMvcConfigurerAdapter jest przestarzały od wersji Spring Boot 5.0. Wyszukiwanie w Google powoduje, że w Javadocs dla tej klasy: „od wersji 5.0 WebMvcConfigurer ma metody domyślne (możliwe dzięki podstawowej wersji Java 8) i może być implementowane bezpośrednio bez potrzeby stosowania tego adaptera”. Myślę więc, że teraz implementuje się WebMvcConfigurer.
Marvo
@Marvo dokładnie tak. Właściwym sposobem na zrobienie tego w 5.x jest implementacja WebMvcConfigurer.
Bal
4

U mnie działa to rozwiązanie:

Najpierw umieść folder zasobów w webapp / WEB-INF, zgodnie z następującą strukturą

-- src
  -- main
    -- webapp
      -- WEB-INF
        -- resources
          -- css
          -- image
          -- js
          -- ...

Po drugie, wiosną plik konfiguracyjny

@Configuration
@EnableWebMvc
public class MvcConfig extends WebMvcConfigurerAdapter{

    @Bean
    public ViewResolver getViewResolver() {
        InternalResourceViewResolver resolver = new InternalResourceViewResolver();
        resolver.setPrefix("/WEB-INF/views/");
        resolver.setSuffix(".html");
        return resolver;
    }

    @Override
    public void configureDefaultServletHandling(
            DefaultServletHandlerConfigurer configurer) {
        configurer.enable();
    }

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/resource/**").addResourceLocations("WEB-INF/resources/");
    }
}

Następnie możesz uzyskać dostęp do zawartości zasobów, takich jak http: // localhost: 8080 / resource / image / yourimage.jpg

ldeng
źródło
3

Są dwie rzeczy do rozważenia (Spring Boot v1.5.2.RELEASE) - 1) Sprawdź wszystkie klasy kontrolera pod kątem adnotacji @EnableWebMvc, usuń ją, jeśli istnieje 2) Sprawdź klasy kontrolera, dla których jest używana adnotacja - @RestController lub @Controller . Nie mieszaj zachowania Rest API i MVC w jednej klasie. W przypadku MVC użyj @Controller, a dla interfejsu API REST użyj @RestController

Wykonanie powyższych dwóch czynności rozwiązało mój problem. Teraz mój wiosenny rozruch ładuje statyczne zasoby bez żadnych problemów. @Controller => load index.html => ładuje pliki statyczne.

@Controller
public class WelcomeController {

    // inject via application.properties
    @Value("${welcome.message:Hello}")
    private String message = "Hello World";

    @RequestMapping("/")
    public String home(Map<String, Object> model) {
        model.put("message", this.message);
        return "index";
    }

}

index.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>index</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />


    <link rel="stylesheet/less" th:href="@{/webapp/assets/theme.siberia.less}"/>

    <!-- The app's logic -->
    <script type="text/javascript" data-main="/webapp/app" th:src="@{/webapp/libs/require.js}"></script>
    <script type="text/javascript">
        require.config({
            paths: { text:"/webapp/libs/text" }
        });
    </script>



   <!-- Development only -->
     <script type="text/javascript" th:src="@{/webapp/libs/less.min.js}"></script>


</head>
<body>

</body>
</html>
gjp
źródło
Usunięcie @EnableWebMvc zrobiło to za mnie! Dziękuję
turboemu
3

Umieść zasoby statyczne w katalogu:

/src/main/resources/static

dodaj tę właściwość w pliku application.properties

server.servlet.context-path=/pdx

Możesz uzyskać dostęp z http: // localhost: 8080 / pdx / images / image.jpg

wprowadź opis obrazu tutaj

dasunse
źródło
1
Nie wiem, jak ci podziękować . Bracie, jesteś wspaniały. Wypróbowałem prawie wszystkie powyższe rozwiązania, ale to jest najlepsze i najkrótsze.
user12061795
2

W przypadku pojawienia się problemu podczas uruchamiania aplikacji z poziomu IDE (tj. Zaczynając od Eclipse lub IntelliJ Idea) i przy użyciu Maven, klucz do rozwiązania znajduje się w dokumentacji Spring-boot Getting Started :

Jeśli używasz Mavena, wykonaj:

mvn package && java -jar target/gs-spring-boot-0.1.0.jar

Ważną częścią tego jest dodanie packagecelu do uruchomienia przed faktycznym uruchomieniem aplikacji. (Idea: Runmenu Edit Configrations..., Addi tam wybrać Run Maven Goali określić packagecel w tej dziedzinie)

ppeterka
źródło
1

Używam 1.3.5 i hostuję kilka usług REST za pośrednictwem implementacji Jersey. To działało dobrze, dopóki nie zdecydowałem się dodać kilka plików HTMLs + js. Żadna z odpowiedzi udzielonych na tym forum nie pomogła mi. Jednak kiedy dodałem następującą zależność w moim pom.xml, cała zawartość w src / main / resources / static została ostatecznie wyświetlona przez przeglądarkę:

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<dependency>

Wygląda na to, że spring-web / spring-webmvc to ważna zależność przechodnia, która powoduje włączenie automatycznej konfiguracji Spring Boot.

LilleElefant
źródło
1

FYI: Zauważyłem również, że mogę zepsuć doskonale działającą aplikację do rozruchu wiosennego i uniemożliwić jej serwowanie zawartości z folderu statycznego, jeśli dodam zły kontroler odpoczynku, taki jak ten

 @RestController
public class BadController {
    @RequestMapping(method= RequestMethod.POST)
    public String someMethod(@RequestParam(value="date", required=false)String dateString, Model model){
        return "foo";
    }
}

W tym przykładzie po dodaniu złego kontrolera do projektu, gdy przeglądarka zapyta o plik dostępny w folderze statycznym, odpowiedź o błędzie to „ 405 Metoda niedozwolona ”.

Zwróć uwagę, że ścieżki nie są mapowane w przykładzie złego kontrolera.

Ganesh
źródło
1

Miałem ten sam problem w Spring Boot 2.1.3, mówiąc, że nie znaleziono zasobu 404. Usunąłem poniżej z pliku application.properties .

#spring.resources.add-mappings=true
#spring.resources.static-locations=classpath:static
#spring.mvc.static-path-pattern=/**,

Usunięto @enableWebMVC i usunięto wszelkie nadpisywanie WebMvcConfigurer

// @ EnableWebMvc

Upewnij się również, że masz @EnableAutoConfiguration w swoim config.

I umieść wszystkie statyczne zasoby w src / main / resources / static i wreszcie zadziałało jak magia.

Debadatta
źródło
moja wiosenna wersja 2.2.6 i mam @EnableAutoConfiguration i pliki w src / main / resources / static, ale to nie działa i wyrzuca 500.
shivani thakur
1

Używając Spring Boot 2. *, mam kontroler, który mapuje trasy GetMapping({"/{var}", "/{var1}/{var2}", "/{var1}/{var2}/{var3}"})i wysuwa moją aplikację, która przestaje obsługiwać zasoby.

wiem, że takie trasy nie są wskazane, ale wszystko zależy od aplikacji, którą budujesz (w moim przypadku nie mam wyboru, muszę mieć takie trasy)

więc oto mój trik, aby upewnić się, że moja aplikacja ponownie obsługuje zasoby. Po prostu mam kontroler, który mapuje do moich zasobów. ponieważ wiosna najpierw dopasuje trasę bezpośrednią przed jakąkolwiek, która ma zmienną, postanowiłem dodać metodę kontrolera, która mapuje /imgaes/{name}i powtórzy to samo dla innych zasobów

@GetMapping(value = "/images/{image}", produces = {MediaType.IMAGE_GIF_VALUE, MediaType.IMAGE_JPEG_VALUE, MediaType.IMAGE_PNG_VALUE})
    public @ResponseBody
    byte[] getImage(@PathVariable String image) {
        ClassPathResource file = new ClassPathResource("static/images/" + image);
        byte[] bytes;
        try {
            bytes = StreamUtils.copyToByteArray(file.getInputStream());
        } catch (IOException e) {
            throw new ResourceNotFoundException("file not found: " + image);
        }
        return bytes;
    }

i to rozwiązało mój problem

Raines
źródło
0

Miałem ten sam problem, używając gradle i eclipse i spędzając godziny na próbach rozwiązania tego problemu.

Nie jest wymagane kodowanie, sztuczka polega na tym, że musisz użyć opcji menu Nowy-> Folder źródłowy (NIE Nowy -> Folder), aby utworzyć folder statyczny w lokalizacji src / main / resources. Nie wiem, dlaczego to działa, ale zrobiłem nowy -> folder źródłowy, a następnie nazwałem folder statyczny (wtedy okno dialogowe folderu źródłowego wyświetla błąd, który należy sprawdzić: Zaktualizuj filtry wykluczeń w innych folderach źródłowych, aby rozwiązać zagnieżdżenie). Mój nowy folder statyczny dodałem index.html i teraz działa.

Vizcaino
źródło
0

Cóż, czasami warto sprawdzić, czy nadpisałeś globalne mapowania jakimś kontrolerem reszty. Prosty przykładowy błąd (kotlin):

@RestController("/foo")
class TrainingController {

    @PostMapping
    fun bazz(@RequestBody newBody: CommandDto): CommandDto = return commandDto

}

W powyższym przypadku, gdy poprosisz o zasoby statyczne, otrzymasz:

{
    title: "Method Not Allowed",
    status: 405,
    detail: "Request method 'GET' not supported",
    path: "/index.html"
}

Powodem tego może być fakt, że chcesz na mapie @PostMapping, aby /foojednak zapomnieć o @RequestMappingadnotacji na @RestControllerpoziomie. W takim przypadku wszystkie żądania są mapowane POSTi nie otrzymasz w tym przypadku zawartości statycznej.

Przemek Nowak
źródło
0

Biorąc pod uwagę zasoby w src / main / resources / static, jeśli dodasz ten kod, cała zawartość statyczna z src / main / resources / static będzie dostępna pod „/”:

@Configuration
public class StaticResourcesConfigurer implements WebMvcConfigurer {
    public void addResourceHandlers(final ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/resources/**").addResourceLocations("classpath:/resources/static/");
    }
}
mmirwaldt
źródło
0

W moim przypadku nie wyświetlono niektórych plików statycznych, takich jak czcionki .woff i niektóre obrazy. Ale css i js działały dobrze.

Aktualizacja: O wiele lepszym rozwiązaniem, aby Spring Boot poprawnie obsługiwał czcionki woff, jest na przykład skonfigurowanie filtrowania zasobów wspomnianego w tej odpowiedzi (pamiętaj, że potrzebujesz zarówno opcji włączania, jak i wykluczania):

<resources>
    <resource>
        <directory>src/main/resources</directory>
        <filtering>true</filtering>
        <excludes>
            <exclude>static/aui/fonts/**</exclude>
        </excludes>
    </resource>
    <resource>
        <directory>src/main/resources</directory>
        <filtering>false</filtering>
        <includes>
            <include>static/aui/fonts/**</include>
        </includes>
    </resource>
</resources>

----- Stare rozwiązanie (działa, ale spowoduje uszkodzenie niektórych czcionek) -----

Innym rozwiązaniem było wyłączenie dopasowywania wzorców sufiksów z setUseSuffixPatternMatch(false)

@Configuration
public class StaticResourceConfig implements WebMvcConfigurer {
    @Override
    public void configurePathMatch(PathMatchConfigurer configurer) {
        // disable suffix matching to serve .woff, images, etc.
        configurer.setUseSuffixPatternMatch(false);
    }
}

Podziękowania: @Abhiji wskazał mi 4. we właściwym kierunku!

LukeSolar
źródło
0

Żądania do / ** są oceniane w statycznych lokalizacjach skonfigurowanych w resourceProperties .

dodanie następującego elementu do application.properties może być jedyną rzeczą, którą musisz zrobić ...

spring.resources.static-locations=classpath:/myresources/

spowoduje to nadpisanie domyślnych lokalizacji statycznych, czyli:

ResourceProperties.CLASSPATH_RESOURCE_LOCATIONS = { "classpath:/META-INF/resources/",
        "classpath:/resources/", "classpath:/static/", "classpath:/public/" };

Możesz nie chcieć tego robić i po prostu upewnij się, że Twoje zasoby trafiają do jednego z tych domyślnych folderów.

Wykonywanie żądania: Gdybym miał przykład.html przechowywany w /public/example.html, to mogę uzyskać do niego dostęp w następujący sposób:

<host>/<context-path?if you have one>/example.html

Jeśli chciałbym mieć inny <host>/<context-path>/magico/*identyfikator URI, taki jak dla plików w ścieżce klas: / magicofiles / *, potrzebujesz trochę więcej konfiguracji

@Configuration
class MyConfigClass implements WebMvcConfigurer

@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
    registry.addResourceHandler("/magico/**").addResourceLocations("/magicofiles/");
}
Sven Dhaens
źródło
-1

Jak wspomniano powyżej, plik powinien znajdować się w $ClassPath/static/images/name.png, (/ static lub / public lub / resources lub / META-INF / resources). Ta $ ClassPath oznacza main/resourceslubmain/java reż.

Jeśli twoje pliki nie znajdują się w standardowych katalogach, możesz dodać następującą konfigurację:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

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

@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        // ... etc.
}
...

}

Mavlarn
źródło