Spring Boot không phục vụ nội dung tĩnh


173

Tôi không thể có được dự án Spring-boot của mình để phục vụ nội dung tĩnh.

Tôi đã đặt một thư mục có tên staticdưới đây src/main/resources. Bên trong nó tôi có một thư mục tên images. Khi tôi đóng gói ứng dụng và chạy nó, nó không thể tìm thấy hình ảnh tôi đã đặt trên thư mục đó.

Tôi đã cố gắng để đưa các tập tin tĩnh trong public, resourcesMETA-INF/resourcesnhưng không hoạt động.

Nếu tôi jar -tvf app.jar tôi có thể thấy rằng các tệp nằm trong jar trên thư mục bên phải: /static/images/head.pngví dụ: nhưng gọi: http://localhost:8080/images/head.pngtất cả những gì tôi nhận được là một404

Bất cứ ý tưởng tại sao spring-boot không tìm thấy điều này? (Tôi đang sử dụng 1.1.4 BTW)


6
Các bản đồ xử lý tài nguyên mặc định thành / **. Tôi sẽ kiểm tra lại xem nó đã được bật chưa. Nếu đúng như vậy, bạn sẽ thấy một dòng kết thúc bằng "Đường dẫn URL đã ánh xạ [/ **] vào trình xử lý loại [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]" trong đầu ra khi bạn khởi động ứng dụng. Một khả năng khác là bộ điều khiển của chính bạn cũng được ánh xạ tới / ** và được ưu tiên hơn trình xử lý tài nguyên. Đăng kết quả đầu ra của ứng dụng của bạn sẽ giúp chúng tôi dễ dàng thấy những gì đang diễn ra.
Andy Wilkinson

12
Tôi đoán bạn có @EnableWebMvc(hoặc tương đương) trong ứng dụng của mình. Điều đó sẽ tắt cấu hình Boot MVC mặc định.
Dave Syer

1
Không, tôi không có @EnableWebMvc ở bất cứ đâu. Tôi không hiểu điều này. Bây giờ nó xảy ra với các mẫu là tốt. Bất kỳ mẫu nào của tôi (freemarker) đang được tìm thấy bởi trình nạp lớp của boot mùa xuân.
Vinicius Carvalho

2
Tôi đang gặp phải một vấn đề tương tự và không gặp may mắn với bất kỳ nghị quyết nào được đề xuất. Nếu ai đó có thể tốt bụng như vậy để xem và chỉ ra chính xác những gì tôi đang làm sai, nó sẽ được đánh giá cao !!! github.com/kylebober/kbss
Kyle S. Bober

3
Tôi thấy rằng nếu tôi có một tệp src / main / resource / public / style.css, thì url cho đó là /style.css chứ không phải /public/style.css như tôi mong đợi.
Dave

Câu trả lời:


179

Không nuôi sống người chết sau hơn một năm, nhưng tất cả các câu trả lời trước đó đều bỏ lỡ một số điểm quan trọng:

  1. @EnableWebMvctrên lớp của bạn sẽ vô hiệu hóa org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration. Điều đó tốt nếu bạn muốn kiểm soát hoàn toàn nhưng nếu không, đó là một vấn đề.
  2. Không cần phải viết bất kỳ mã nào để thêm một vị trí khác cho tài nguyên tĩnh ngoài những gì đã được cung cấp. Nhìn org.springframework.boot.autoconfigure.web.ResourcePropertiestừ v1.3.0.RELEASE, tôi thấy một trường staticLocationscó thể được cấu hình trong application.properties. Đây là một đoạn trích từ nguồn:

    /**
     * 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. Như đã đề cập trước đó, URL yêu cầu sẽ được giải quyết liên quan đến các vị trí này. Do đó src/main/resources/static/index.htmlsẽ được phục vụ khi URL yêu cầu là /index.html. Lớp chịu trách nhiệm giải quyết đường dẫn, kể từ Mùa xuân 4.1, là org.springframework.web.servlet.resource.PathResourceResolver.

  4. Kết hợp mẫu hậu tố được bật theo mặc định có nghĩa là đối với URL yêu cầu /index.html, Spring sẽ tìm kiếm các trình xử lý tương ứng /index.html. Đây là một vấn đề nếu ý định là để phục vụ nội dung tĩnh. Để vô hiệu hóa điều đó, hãy mở rộng WebMvcConfigurerAdapter(nhưng không sử dụng @EnableWebMvc) và ghi đè configurePathMatchnhư hiển thị bên dưới:

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

IMHO, cách duy nhất để có ít lỗi hơn trong mã của bạn là không viết mã bất cứ khi nào có thể. Sử dụng những gì đã được cung cấp, ngay cả khi điều đó cần một số nghiên cứu, lợi nhuận là xứng đáng.


3
Câu trả lời này thực sự là sau nhiều nghiên cứu. Một cuốn sách tuyệt vời để đọc
Ekansh Rastogi

2
Nếu tôi là trụ cột, tôi sẽ lấy câu trả lời này và đưa nó vào tài liệu Spring Boot
aliopi

2
@Abhijit Sarkar Ý tôi là công ty Pivotal , xin lỗi vì bất kỳ cảm giác tồi tệ nào, nhưng nó không có ý định. Pivotal là chủ sở hữu của Spring nếu tôi đúng. Tôi có thể ghi lại, nhưng họ có những người được trả tiền cho việc này, vì vậy họ nên làm điều đó: P
aliopi

1
@aliopi Spring là một dự án nguồn mở.
Abhijit Sarkar

3
cách duy nhất để có ít lỗi hơn trong mã của bạn là không viết mã [...] thực sự như thế này.
Clijsters

78

Không giống như trạng thái khởi động mùa xuân, để có được jar khởi động mùa xuân của tôi để phục vụ nội dung: Tôi đã phải thêm cụ thể đăng ký nội dung src / main / resource / static của mình thông qua lớp cấu hình này:

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

3
Tôi có cùng một vấn đề, cùng một phiên bản Spring Boot nhưng điều này cũng không hiệu quả với tôi
greyfox

Đã sửa lỗi của tôi trong phiên bản 1.2.5 !! cảm ơn bạn rất nhiều .. bỏ phiếu này lên !!
mrclrchtr

Bản hack này hoạt động ... kỳ lạ là cấu hình tự động không thành công
Allan Vital

Đáng tiếc, hack này không hoạt động đối với tôi đó là một sự xấu hổ do sự thanh lịch. Tôi không chắc chắn nếu nguyên nhân gốc là đường dẫn đến tài nguyên. Có lẽ, vì tôi đang chạy nó trong windows, chúng cần được định dạng khác nhau?
acarlstein

50

Tôi đã có một vấn đề tương tự, và hóa ra giải pháp đơn giản là mở rộng lớp cấu hình của tôi WebMvcAutoConfiguration:

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

Tôi không cần bất kỳ mã khác để cho phép nội dung tĩnh của tôi để được phục vụ, tuy nhiên, tôi đã đặt một thư mục có tên publicdưới src/main/webappvà cấu hình maven để trỏ đến src/main/webappnhư một thư mục tài nguyên. Điều này có nghĩa là nó publicđược sao chép vào target/classes, và do đó trên đường dẫn lớp trong thời gian chạy để tìm spring-boot / tomcat.


Với cách này, tài nguyên tĩnh không hoạt động trong hồ sơ khác. ví dụ tôi có một hồ sơ để phát hành sử dụng địa chỉ IP khác. Tôi nhận được lỗi 404 cho tất cả các tài nguyên của tôi.
Mahdi

24

Tìm Bộ điều khiển được ánh xạ tới "/" hoặc không có ánh xạ đường dẫn.

Tôi đã gặp một vấn đề như thế này, nhận được 405 lỗi và đập đầu rất nhiều ngày. Vấn đề hóa ra là một @RestControllerbộ điều khiển chú thích mà tôi đã quên chú thích bằng một @RequestMappingchú thích. Tôi đoán đường dẫn được ánh xạ này được mặc định là "/" và chặn ánh xạ tài nguyên nội dung tĩnh.


1
Giải quyết nó cho tôi! Tôi đã có một bộ điều khiển được chú thích bằng @RestControll ("/ blubb") rõ ràng là sai, nhưng trong nước bạn không thấy gỗ cho cây. Thay đổi nó thành @RestControll @RequestMapping ("/ blubb") đã giải quyết nó
krinklesaurus

Tôi rất vui vì nó đã giúp, và thích thú bởi quan điểm cho rằng khái niệm "Không thể nhìn thấy rừng cho tất cả những cái cây" tồn tại trong Đức cũng như swedish :)
Johannes

2
Bạn cũng có thể thêm @RequestMapping ("/") một cách rõ ràng nếu mục đích là vừa phục vụ nội dung tĩnh vừa có trình xử lý động cho các yêu cầu gốc.
mjj1409

1
Wow .... Đã dành 2 ngày lãng phí cho cái này. Ứng dụng mvc khởi động mùa xuân của tôi sử dụng bảo mật mùa xuân và không thấy tệp Styles.css. Tôi tin rằng bảo mật đã không cho phép .jsp truy cập vào tệp style.css. Tôi đã có @RequestMapping ({"", "/", "/ home"}) trong bộ điều khiển của mình. Lấy ra "" và "/" và MVC của tôi bắt đầu hoạt động hoàn hảo ... Rất lạ.
skmansfield

3
@Shafiul Không thêm cả EnableAutoConfiguration và SpringBootApplication là dư thừa! "@SpringBootApplication" chứa "@EnableAutoConfiguration"
Dehan de Croos

19

Cấu hình có thể được thực hiện như sau:

@Configuration
@EnableWebMvc
public class WebMvcConfig extends WebMvcAutoConfigurationAdapter {

// specific project configuration

}

Điều quan trọng ở đây là phương pháp WebMvcConfig có thể ghi đè của bạn addResourceHandlersvà do đó bạn cần phải gọi một cách rõ ràng super.addResourceHandlers(registry)(đúng là nếu bạn hài lòng với các vị trí tài nguyên mặc định, bạn không cần ghi đè bất kỳ phương thức nào).

Một điều mà cần phải được nhận xét ở đây là những địa điểm tài nguyên mặc định ( /static, /public, /resources/META-INF/resources) sẽ được đăng ký chỉ nếu không có đã một handler nguồn ánh xạ tới /**.

Từ thời điểm này, nếu bạn có một hình ảnh src/main/resources/static/imagesđược đặt tên image.jpgchẳng hạn, bạn có thể truy cập nó bằng URL sau: http://localhost:8080/images/image.jpg(là máy chủ bắt đầu trên cổng 8080 và ứng dụng được triển khai vào ngữ cảnh gốc).


Có lẽ rất quan trọng để nhận xét rằng mặc dù bạn / có thể / ghi đè addResourceHandlers, bạn thực sự không cần phải giải quyết vấn đề của OP.
Kỹ sư phần mềm

@EngineerDollery cảm ơn vì nhận xét, đó là ý định của tôi nhưng tôi đã thêm lời giải thích rõ ràng
Francisco Spaeth

Tôi đã chuyển css / js của mình vào thư mục src / main / resource / static và các lỗi không còn nữa, nhưng tôi vẫn không thể để css hiển thị trong trang của mình.
HHR Jaber

Anh bạn, tôi đã đi sâu vào internet để tìm giải pháp làm việc này. Có vẻ như chìa khóa là sự kết hợp của @EnableWebMvcWebMvcAutoConfigurationAdapter. Cảm ơn thời gian lớn!
Ian Newland

Nó cũng không hoạt động ngoài hộp cho tôi. Tôi đã phải thêm điều này là tốt. Tôi chỉ thêm bình luận của tôi ở đây vì tôi có hai vấn đề. Tôi cũng có một bộ điều khiển ánh xạ "/" như @Johannes đề cập. Làm điều này và loại bỏ bộ điều khiển "/" đã giải quyết vấn đề của tôi.
loyaltyBrown

11

Bạn đã kiểm tra tài liệu tham khảo Spring Boot chưa?

Theo mặc định, Spring Boot sẽ phục vụ nội dung tĩnh từ một thư mục có tên /static( /publichoặc /resourceshoặc /META-INF/resources) trong đường dẫn lớp hoặc từ thư mục gốc của ServletContext.

Bạn cũng có thể so sánh dự án của mình với hướng dẫn Phục vụ nội dung web với Spring MVC hoặc xem mã nguồn của dự án spring-boot-sample-web-ui .


2
Có tôi đã làm, đó là những nơi tôi đã cố gắng, giống như được hướng dẫn bởi các tài liệu. Nhưng không có gì hoạt động. Tôi không hiểu tại sao tài nguyên không được tìm thấy ở tất cả. Tôi đã cố gắng xem xét các mẫu, kỳ lạ là không có mẫu nào sử dụng cấu trúc được đề xuất bởi các tài liệu. Cái mà bạn vừa dán sử dụng một thư mục mẫu, tôi giả sử rằng đó là cho cấu hình hoặc vận tốc của thymeleaf.
Vinicius Carvalho


Tôi đồng ý với @ViniciusCarvalho, tôi đã thử mọi cách kết hợp có thể để có được css / js ở đúng nơi và dường như không thể làm điều đó. Ngay cả khi tôi truy cập localhost: 8089 / css / style.css tôi không thấy gì cả. Tôi chỉ có một quy tắc duy nhất để thay đổi màu sắc cơ thể.
HHR Jaber

10

Tôi đã có vấn đề chính xác này, sau đó nhận ra rằng tôi đã xác định trong ứng dụng của mình.

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

Đó là ghi đè tất cả mọi thứ khác tôi đã cố gắng. Trong trường hợp của tôi, tôi muốn giữ cả hai, vì vậy tôi chỉ giữ tài sản và thêm:

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

Các tệp được phân phát từ src / main / resource / static dưới dạng localhost: {port} /file.html.

Không ai ở trên làm việc cho tôi vì không ai đề cập đến tài sản nhỏ này có thể dễ dàng được sao chép từ trực tuyến để phục vụ mục đích khác;)

Hy vọng nó giúp! Hình nó sẽ phù hợp trong bài viết dài câu trả lời cho những người có vấn đề này.


Tôi đang sử dụng Spring Boot 2.0.5.RELEASE và đưa spring.resources.static-locations=file:/var/www/static,classpath:staticvào application.properations của tôi, nhưng nó không hoạt động với tôi. Tôi đang sử dụng @EnableWebMvctrên lớp cấu hình của tôi.
N. Ngô

Đây là một trong những giải quyết vấn đề của tôi. cùng với security.ignoredsecurity.publicPaths
JoSSte

5

Tôi nghĩ rằng các câu trả lời trước giải quyết chủ đề rất tốt. Tuy nhiên, tôi nói thêm rằng trong một trường hợp khi bạn bật Spring Security trong ứng dụng của mình, bạn có thể phải thông báo cụ thể cho Spring để cho phép các yêu cầu đối với các thư mục tài nguyên tĩnh khác, ví dụ như "/ static / font" .

Trong trường hợp của tôi, tôi đã "/ static / css", "/ static / js", "/ static / hình ảnh" được cho phép theo mặc định, nhưng / static / font / ** đã bị chặn bởi triển khai Spring Security của tôi.

Dưới đây là một ví dụ về cách tôi sửa lỗi này.

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

5

Chỉ cần thêm một câu trả lời khác cho một câu hỏi cũ ... Mọi người đã đề cập đến việc @EnableWebMvcngăn chặn WebMvcAutoConfigurationtải, đó là mã chịu trách nhiệm tạo các trình xử lý tài nguyên tĩnh. Có những điều kiện khác cũng sẽ ngăn chặn WebMvcAutoConfigurationtải. Cách rõ ràng nhất để thấy điều này là nhìn vào nguồn:

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

Trong trường hợp của tôi, tôi đã bao gồm một thư viện có một lớp học mở rộng từ WebMvcConfigurationSupportđó là một điều kiện sẽ ngăn chặn quá trình tự động cấu hình:

@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)

Điều quan trọng là không bao giờ mở rộng từ WebMvcConfigurationSupport. Thay vào đó, mở rộng từ WebMvcConfigurerAdapter.

CẬP NHẬT: Cách thích hợp để làm điều này trong 5.x là triển khai WebMvcConfigker


WebMvcConfigurerAd CHƯƠNG không được dùng nữa kể từ Spring Boot 5.0. Googling nó bật lên điều này trong Javadocs cho lớp đó: "kể từ 5.0 WebMvcConfigker có các phương thức mặc định (được tạo bởi đường cơ sở Java 8) và có thể được triển khai trực tiếp mà không cần bộ điều hợp này." Vì vậy, tôi nghĩ rằng bây giờ người ta thực hiện WebMvcConfigker.
Marvo

@Marvo đó là chính xác. Cách thích hợp để làm điều này trong 5.x là thực hiện WebMvcConfigurer.
Bal

4

Giải pháp này hiệu quả với tôi:

Đầu tiên, đặt một thư mục tài nguyên trong webapp / WEB-INF, theo cấu trúc sau

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

Thứ hai, trong tập tin cấu hình mùa xuân

@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/");
    }
}

Sau đó, bạn có thể truy cập nội dung tài nguyên của mình, chẳng hạn như http: // localhost: 8080 / resource / image / yourimage.jpg


3

Có 2 điều cần xem xét (Spring Boot v1.5.2.RELEASE) - 1) Kiểm tra tất cả các lớp Trình điều khiển cho chú thích @EnableWebMvc, xóa nó nếu có bất kỳ 2) Kiểm tra các lớp Trình điều khiển để sử dụng chú thích nào - @RestControll hoặc @Controll . Không trộn lẫn hành vi Rest API và MVC trong một lớp. Đối với MVC, hãy sử dụng @Controll và cho API REST, hãy sử dụng @RestControll

Làm trên 2 điều đã giải quyết vấn đề của tôi. Bây giờ khởi động mùa xuân của tôi đang tải tài nguyên tĩnh với bất kỳ vấn đề. @Controll => load index.html => tải các tệp tĩnh.

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

Xóa @EnableWebMvc đã làm điều đó cho tôi! Cảm ơn bạn
turboemu

3

Đặt tài nguyên tĩnh trong thư mục:

/src/main/resources/static

thêm thuộc tính này vào tập tin application.properIES

server.servlet.context-path=/pdx

Bạn có thể truy cập từ http: // localhost: 8080 / pdx / images / image.jpg

nhập mô tả hình ảnh ở đây


1
Tôi không biết nói Cảm ơn bạn như thế nào . Anh bạn thật tuyệt. Tôi đã thử hầu hết tất cả các giải pháp trên nhưng đây là giải pháp tốt nhất và ngắn nhất.
dùng12061795

2

Trong trường hợp vấn đề xuất hiện khi khởi chạy ứng dụng từ bên trong IDE (nghĩa là bắt đầu từ Eclipse hoặc IntelliJ Idea) và sử dụng Maven, chìa khóa cho giải pháp nằm trong tài liệu Bắt đầu khởi động mùa xuân :

Nếu bạn đang sử dụng Maven, hãy thực thi:

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

Phần quan trọng trong đó là thêm packagemục tiêu sẽ được chạy trước khi ứng dụng thực sự bắt đầu. (Idea: Runmenu, Edit Configrations..., Add, và có chọn Run Maven Goalvà xác định packagemục tiêu trong lĩnh vực này)


1

Tôi đang sử dụng 1.3.5 và lưu trữ một loạt các dịch vụ REST thông qua triển khai Jersey. Điều đó hoạt động tốt cho đến khi tôi quyết định thêm một vài tệp HTML + js. Không có câu trả lời nào được đưa ra trên diễn đàn này đã giúp tôi. Tuy nhiên, khi tôi thêm phụ thuộc sau vào pom.xml của mình, tất cả nội dung trong src / main / resource / static cuối cùng cũng được hiển thị qua trình duyệt:

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

Dường như spring-web / spring-webmvc là phụ thuộc bắc cầu quan trọng giúp bật chức năng tự động khởi động mùa xuân.


1

FYI: Tôi cũng nhận thấy rằng tôi có thể làm rối ứng dụng khởi động lò xo hoạt động hoàn hảo và ngăn không cho nó phục vụ nội dung từ thư mục tĩnh, nếu tôi thêm một bộ điều khiển nghỉ ngơi tồi như vậy

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

Trong ví dụ này, sau khi thêm bộ điều khiển xấu vào dự án, khi trình duyệt yêu cầu một tệp có sẵn trong thư mục tĩnh, phản hồi lỗi là ' 405 Phương thức không được phép '.

Đường dẫn thông báo không được ánh xạ trong ví dụ về bộ điều khiển xấu.


1

Tôi đã phải đối mặt với cùng một vấn đề trong khởi động mùa xuân 2.1.3 nói rằng tài nguyên không được tìm thấy 404. Tôi đã xóa bên dưới khỏi applicationatiion.properies .

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

Đã xóa @enableWebMVC và xóa mọi ghi đè WebMvcConfigker

// @ EnableWebMvc

Đồng thời đảm bảo rằng bạn có @EnableAutoConfiguration trong cấu hình của mình.

Và đặt tất cả các tài nguyên tĩnh vào src / main / resource / static và cuối cùng nó cũng hoạt động như ma thuật ..


phiên bản mùa xuân của tôi vào 2.2.6 và tôi có @EnableAutoConfiguration và các tệp dưới src / main / resource / static nhưng nó không hoạt động và ném 500.
shivani thakur

1

sử dụng spring boot 2. *, tôi có một bộ điều khiển ánh xạ tới các tuyến đường GetMapping({"/{var}", "/{var1}/{var2}", "/{var1}/{var2}/{var3}"})và giúp ứng dụng của tôi ngừng phục vụ tài nguyên.

Tôi biết không nên có các tuyến như vậy nhưng tất cả phụ thuộc vào ứng dụng bạn đang xây dựng (trong trường hợp của tôi, tôi không có lựa chọn nào khác ngoài việc có các tuyến như vậy)

Vì vậy, đây là hack của tôi để đảm bảo ứng dụng của tôi phục vụ tài nguyên một lần nữa. Tôi chỉ cần có một bộ điều khiển ánh xạ tới tài nguyên của tôi. vì mùa xuân sẽ khớp với một tuyến trực tiếp trước khi có bất kỳ biến nào, tôi quyết định thêm một phương thức điều khiển ánh xạ /imgaes/{name}và lặp lại tương tự cho các tài nguyên khác

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

và điều này đã giải quyết vấn đề của tôi


0

Có cùng một vấn đề, sử dụng gradle và nhật thực và dành hàng giờ cố gắng để tìm ra nó.

Không cần mã hóa, mẹo là bạn phải sử dụng tùy chọn menu Mới-> Thư mục nguồn (KHÔNG phải mới -> Thư mục) để tạo thư mục tĩnh trong src / main / resource. Không biết tại sao điều này hoạt động, nhưng đã làm mới -> thư mục nguồn sau đó tôi đặt tên cho thư mục tĩnh (sau đó hộp thoại thư mục nguồn đưa ra lỗi mà bạn phải kiểm tra: Cập nhật các bộ lọc loại trừ trong các thư mục nguồn khác để giải quyết lồng nhau). Thư mục tĩnh mới của tôi, tôi đã thêm index.html và bây giờ nó hoạt động.


0

Đôi khi cũng đáng để kiểm tra xem bạn có ghi đè lên ánh xạ toàn cầu bằng một số bộ điều khiển còn lại không. Lỗi ví dụ đơn giản (kotlin):

@RestController("/foo")
class TrainingController {

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

}

Trong trường hợp trên, bạn sẽ nhận được khi bạn yêu cầu tài nguyên tĩnh:

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

Lý do cho nó có thể là bạn muốn ánh xạ @PostMappingtới /foomà quên đi @RequestMappingchú thích ở @RestControllercấp độ. Trong trường hợp này, tất cả các yêu cầu được ánh xạ tới POSTvà bạn sẽ không nhận được nội dung tĩnh trong trường hợp này.


0

Được cung cấp tài nguyên dưới src / main / resource / static, nếu bạn thêm mã này, thì tất cả nội dung tĩnh từ src / main / resource / static sẽ có sẵn trong "/":

@Configuration
public class StaticResourcesConfigurer implements WebMvcConfigurer {
    public void addResourceHandlers(final ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/resources/**").addResourceLocations("classpath:/resources/static/");
    }
}

0

Trong trường hợp của tôi, một số tệp tĩnh không được cung cấp, như phông chữ .woff và một số hình ảnh. Nhưng css và js chỉ hoạt động tốt.

Cập nhật: Một giải pháp tốt hơn nhiều để làm cho Spring Boot phục vụ chính xác các phông chữ woff là định cấu hình bộ lọc tài nguyên được đề cập trong câu trả lời này , ví dụ (lưu ý rằng bạn cần cả bao gồm và loại trừ):

<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>

----- Giải pháp cũ (hoạt động nhưng sẽ làm hỏng một số phông chữ) -----

Một giải pháp khác là vô hiệu hóa khớp mẫu hậu tố với 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);
    }
}

Tín dụng: @Abhiji đã chỉ cho tôi 4. theo đúng hướng!


0

Yêu cầu / ** được ước tính cho các vị trí tĩnh được định cấu hình trong resourceProperations .

thêm phần sau vào application.properations, có thể là điều duy nhất bạn cần làm ...

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

điều này sẽ ghi đè lên các vị trí tĩnh mặc định, trong đó là:

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

Bạn có thể không muốn làm điều đó và chỉ cần đảm bảo rằng tài nguyên của bạn kết thúc ở một trong những thư mục mặc định đó.

Thực hiện một yêu cầu: Nếu tôi có example.html được lưu trữ trên /public/example.html Sau đó tôi có thể xác nhận nó như thế này:

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

Nếu tôi muốn một uri khác <host>/<context-path>/magico/*cho các tệp trong classpath: / magicofiles / * bạn cần thêm một chút cấu hình

@Configuration
class MyConfigClass implements WebMvcConfigurer

@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
    registry.addResourceHandler("/magico/**").addResourceLocations("/magicofiles/");
}

-1

Như đã nói ở trên, tệp phải ở trong $ClassPath/static/images/name.png, (/ tĩnh hoặc / công khai hoặc / tài nguyên hoặc / META-INF / tài nguyên). $ ClassPath này có nghĩa là main/resourceshoặc main/javathư mục.

Nếu tệp của bạn không có trong thư mục tiêu chuẩn, bạn có thể thêm cấu hình sau:

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

}

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.