Spring boot не может найти /web-inf/classes/index.jsp

У меня проблема с приложением Spring Boot + Angular 6 + Gradle. Мое приложение выглядит так: Родитель:
-> Бэкэнд
-> Frontend
Backend использует Spring Boot и настроен следующим образом:

@SpringBootApplication
@EnableBatchProcessing
public class BackendApplication extends SpringBootServletInitializer {

  @Override
  protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
    return configureApplication(builder);
  }

  public static void main(String[] args) {
    configureApplication(new SpringApplicationBuilder()).run(args);
  }

  private static SpringApplicationBuilder configureApplication(SpringApplicationBuilder builder) {
    return builder.sources(BackendApplication.class).bannerMode(Banner.Mode.OFF);
  }
}  

@Controller
@EnableWebMvc
public class IndexController extends WebMvcConfigurerAdapter {

  @RequestMapping(value = "/", method = RequestMethod.GET)
  public ModelAndView index(HttpServletRequest request, Model model) {
    ModelAndView modelAndView = new ModelAndView("index");
    modelAndView.addObject("apiUrl", resolveBaseApiUrl(request));;
    return modelAndView;
  }

  private String resolveBaseApiUrl(HttpServletRequest request) {
    return request.getRequestURL().toString().replace("https://", "//").replace("http://", "//");
  }
}

@EnableWebMvc()
@Configuration
public class ViewConfiguration extends WebMvcConfigurerAdapter {

  @Bean
  public ViewResolver jspViewResolver() {
    InternalResourceViewResolver bean = new InternalResourceViewResolver();
    bean.setPrefix("/WEB-INF/classes/");
    bean.setSuffix(".jsp");
    return bean;
  }

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

Кроме того, у меня есть некоторые зависимости, которые нужно добавить, чтобы запустить это приложение из войны.

compile 'javax.servlet:jstl:1.2'
compile group: 'org.apache.tomcat.embed', name: 'tomcat-embed-jasper', version: '9.0.10'

Я создаю свой интерфейс Angular 6 и добавляю содержимое каталога dist в WAR с помощью исходных наборов gradle:

sourceSets {
    main {
        resources {
            srcDirs = ["$webappDir/dist", "$projectDir/src/main/resources"]
        }
    }
}

Файл WAR после сборки выглядит так (как видите, есть файл WEB-INF / classes / index.jsp): Скриншот файла WAR

У вас есть идеи, почему я все еще получаю 404?

Whitelabel Error Page
There was an unexpected error (type=Not Found, status=404).
/WEB-INF/classes/index.jsp  
2
0
1 749
2

Ответы 2

Я сам борюсь с подобной проблемой. Я считать, что Spring Boot ищет каталог static внутри classes. Подробнее см. эта ссылка. Похоже, что для приложения Spring Boot вы можете поместить свой статический контент (включая index.html) в любой из:

  • / META-INF / ресурсы /
  • /Ресурсы/
  • / static /
  • / public /

В разделе комментариев ссылки spring.io много говорится о людях с похожими проблемами. Я работаю над этим, чтобы попытаться сделать мои настройки правильными. https://spring.io/blog/2013/12/19/serving-static-web-content-with-spring-boot

Кажется, что ваш sourceSets помещает содержимое Angular в main/resources, но на вашем результирующем снимке экрана WAR нет каталога /resources. Возможно, попробуйте изменить sourceSets на:

sourceSets {
    main {
        resources {
            srcDirs = ["$webappDir/dist", "$projectDir/src/main/resources/static"]
        }
    }
}

Я думаю, что это создаст статический каталог, а затем Spring Boot сможет найти ваш index.html, когда вы нажмете localhost:8080/WARname

Проблема:

The problem is that you configured, resource request path should be searched in /WEB-INF/classes/, and that's why you are getting error on this path /WEB-INF/classes/index.jsp


Решение:

Теперь, если вы используете AngularJS и это одностраничное приложение, конфигурация должна быть такой:

@EnableWebMvc()
    @Configuration
    public class ViewConfiguration extends WebMvcConfigurerAdapter {


        @Override
        public void addResourceHandlers(final ResourceHandlerRegistry registry) {
            registry.addResourceHandler("/resources/static/js/**")

                .addResourceLocations("/resources/static/js/");

            registry.addResourceHandler("/resources/static/css/**")

                .addResourceLocations("/resources/static/css/");

            registry.addResourceHandler("/resources/static/views/**")

                .addResourceLocations("/resources/static/views/");

            registry.addResourceHandler("/resources/static/**")

                .addResourceLocations("/resources/static/");

            registry.addResourceHandler("/webjars/**")

                .addResourceLocations("/webjars/");

            registry.addResourceHandler("/**")
                .addResourceLocations("classpath:/static/views/index.html")
                .setCachePeriod(cachePeriod).resourceChain(true)
                .addResolver(new PathResourceResolver() {
                    @Override
                    protected Resource getResource(String resourcePath,
                        Resource location) throws IOException {
                        return location.exists() && location.isReadable() ? location :
                            null;
                    }
                });
        }

        @Bean
        public InternalResourceViewResolver viewResolver() {
            InternalResourceViewResolver resolver = new InternalResourceViewResolver();
            resolver.setPrefix("/resources/static/views/");
            resolver.setSuffix(".html");
            return resolver;
        }


    }

Таким образом, вы говорите, что мои ресурсы, такие как js, css, изображения, следует искать в соответствующих папках, а все другие маршруты должны обслуживаться index.html на classpath:/static/views/index.html.


  • Note that you should probably change above code to match your folder structure. I hope you got the whole idea.

Другие вопросы по теме