@pugachok

Spring boot не видит css и js. Пути к файлам прописывал по советам всех форумов. Может не правильный конфиг?

Разрабатываю spring приложение. При подключении css и js на странице отображается только ее содержимое, т.е. стили не подключаются.

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>AdminLTE 3 | Dashboard</title>

    <link href="${pageContext.request.contextPath}/templates/bootstrap/plugins/fontawesome-free/css/all.min.css" rel="stylesheet">
    <!-- Google Font: Source Sans Pro -->
    <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,400i,700&display=fallback">
    <!-- Font Awesome -->
    <link rel="stylesheet" href="/templates/bootstrap/plugins/fontawesome-free/css/all.min.css" th:href="@{/plugins/fontawesome-free/css/all.min.css}">
    <!-- Ionicons -->
    <link rel="stylesheet" href="https://code.ionicframework.com/ionicons/2.0.1/css/ionicons.min.css">
    <!-- Tempusdominus Bootstrap 4 -->
    <link rel="stylesheet" href="/templates/bootstrap/plugins/tempusdominus-bootstrap-4/css/tempusdominus-bootstrap-4.min.css" th:href="@{/plugins/tempusdominus-bootstrap-4/css/tempusdominus-bootstrap-4.min.css}">
    <!-- iCheck -->
    <link rel="stylesheet" href="/templates/bootstrap/plugins/icheck-bootstrap/icheck-bootstrap.min.css" th:href="@{/plugins/icheck-bootstrap/icheck-bootstrap.min.css}">
    <!-- JQVMap -->
    <link rel="stylesheet" href="/templates/bootstrap/plugins/jqvmap/jqvmap.min.css" th:href="@{/plugins/jqvmap/jqvmap.min.css}">
    <!-- Theme style -->
    <link rel="stylesheet" href="/templates/bootstrap/dist/css/adminlte.min.css" th:href="@{/dist/css/adminlte.min.css}">
    <!-- overlayScrollbars -->
    <link rel="stylesheet" href="/templates/bootstrap/plugins/overlayScrollbars/css/OverlayScrollbars.min.css" th:href="@{/plugins/overlayScrollbars/css/OverlayScrollbars.min.css}">
    <!-- Daterange picker -->
    <link rel="stylesheet" href="/templates/bootstrap/plugins/daterangepicker/daterangepicker.css" th:href="@{/plugins/daterangepicker/daterangepicker.css}">
    <!-- summernote -->
    <link rel="stylesheet" href="/templates/bootstrap/plugins/summernote/summernote-bs4.min.css" th:href="@{/plugins/summernote/summernote-bs4.min.css}">
</head>
<body class="hold-transition sidebar-mini layout-fixed">
<div class="wrapper">
</div>
<!-- ./wrapper -->

<!-- jQuery -->
<script src="../bootstrap/plugins/jquery/jquery.min.js"></script>
<!-- jQuery UI 1.11.4 -->
<script src="../bootstrap/plugins/jquery-ui/jquery-ui.min.js"></script>
<!-- Resolve conflict in jQuery UI tooltip with Bootstrap tooltip -->
<script>
    $.widget.bridge('uibutton', $.ui.button)
</script>
<!-- Bootstrap 4 -->
<script src="../bootstrap/plugins/bootstrap/js/bootstrap.bundle.min.js"></script>
<!-- ChartJS -->
<script src="../bootstrap/plugins/chart.js/Chart.min.js"></script>
<!-- Sparkline -->
<script src="../bootstrap/plugins/sparklines/sparkline.js"></script>
<!-- JQVMap -->
<script src="../bootstrap/plugins/jqvmap/jquery.vmap.min.js"></script>
<script src="../bootstrap/plugins/jqvmap/maps/jquery.vmap.usa.js"></script>
<!-- jQuery Knob Chart -->
<script src="../bootstrap/plugins/jquery-knob/jquery.knob.min.js"></script>
<!-- daterangepicker -->
<script src="../bootstrap/plugins/moment/moment.min.js"></script>
<script src="../bootstrap/plugins/daterangepicker/daterangepicker.js"></script>
<!-- Tempusdominus Bootstrap 4 -->
<script src="../bootstrap/plugins/tempusdominus-bootstrap-4/js/tempusdominus-bootstrap-4.min.js"></script>
<!-- Summernote -->
<script src="../bootstrap/plugins/summernote/summernote-bs4.min.js"></script>
<!-- overlayScrollbars -->
<script src="../bootstrap/plugins/overlayScrollbars/js/jquery.overlayScrollbars.min.js"></script>
<!-- AdminLTE App -->
<script src="../bootstrap/dist/js/adminlte.js"></script>
<!-- AdminLTE for demo purposes -->
<script src="../bootstrap/dist/js/demo.js"></script>
<!-- AdminLTE dashboard demo (This is only for demo purposes) -->
<script src="../bootstrap/dist/js/pages/dashboard.js"></script>
</body>
</html>


60a7f6554f023663706693.jpeg
структура ресурс дериктории.

конфиг файл
@EnableWebMvc
@Configuration
public class MvcConfig implements WebMvcConfigurer {

    private static final String[] CLASSPATH_RESOURCE_LOCATIONS = new String[]{"classpath:/resources/", "classpath:/assets/", "classpath:/templates/"};

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        if (!registry.hasMappingForPattern("/**")) {
            registry.addResourceHandler("/**").addResourceLocations(
                    "classpath:/resources/");
        }
        if (!registry.hasMappingForPattern("/**")) {
            registry.addResourceHandler("/**").addResourceLocations(CLASSPATH_RESOURCE_LOCATIONS);
        }
    }

    @Override
    public void configurePathMatch(PathMatchConfigurer configurer) {
        WebMvcConfigurer.super.configurePathMatch(configurer);

        configurer.setUseSuffixPatternMatch(false);
    }
}


конфиг secutiry
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    private final UserDetailsService userDetailsService;

    @Autowired
    public WebSecurityConfig(@Qualifier("userDetailsServiceImpl") UserDetailsService userDetailsService) {
        this.userDetailsService = userDetailsService;
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                    .csrf().disable()
                    .authorizeRequests()
                    .antMatchers("/resources/**", "/assets/**", "/css/**", "/js/**", "/").permitAll()
                    .anyRequest()
                    .authenticated()
                .and()
                    .formLogin()
                    .loginPage("/auth/login").permitAll()
                    .defaultSuccessUrl("/auth/index")
                .and()
                    .logout()
                    .logoutRequestMatcher(new AntPathRequestMatcher("/auth/logout", "POST"))
                    .invalidateHttpSession(true)
                    .clearAuthentication(true)
                    .deleteCookies("JSESSIONID")
                    .logoutSuccessUrl("/auth/login");
    }



    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.authenticationProvider(daoAuthenticationProvider());
    }

    @Bean
    public PasswordEncoder encoder() {
        return new BCryptPasswordEncoder(12);
    }

    @Bean
    protected DaoAuthenticationProvider daoAuthenticationProvider() {
        DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider();
        daoAuthenticationProvider.setPasswordEncoder(encoder());
        daoAuthenticationProvider.setUserDetailsService(userDetailsService);
        return daoAuthenticationProvider;
    }

    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers( "/resources/**", "/assets/**", "/css/**", "/js/**", "/auth/login.html");
    }

}


Гугление не помогло. Если подключаю стили через ссылку http формата - работает, через директории - нет
  • Вопрос задан
  • 96 просмотров
Решения вопроса 1
@pugachok Автор вопроса
поменял структуру папок:
60a8f503c1afa402044033.jpeg

узнал, что spring по умолчанию сканирует директорию static
и при подключении стилей в аттрибуте href нужно указывать путь от /static директории, а в th:href ее не учитаваем, т.е. от /style
60a8f59f22ab2907202325.jpeg
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
azerphoenix
@azerphoenix Куратор тега Spring
Java Software Engineer
Добрый день.
Используете ли вы шаблонизатор thymeleaf?

Если да, то это не совсем корректно:
<link href="${pageContext.request.contextPath}/templates/bootstrap/plugins/fontawesome-free/css/all.min.css" rel="stylesheet">


Попробуйте так:


То же самое проделайте с js
Например,
<script th:src="@{/bootstrap/plugins/bootstrap/js/bootstrap.bundle.min.js}"></script>


Все остальное замените таким же образом. Должно сработать.

И еще что в консоли браузера отображается во вкладке Сеть (Network) ?
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы