Как я могу служить статический html из весенней загрузки?

Я запустил проект spring-boot-sample-web-static из здесь, сделал это изменение для pom

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

И добавил этот класс для обслуживания дубликата страницы index2.html из той же папки static:

import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class Rester {

    @RequestMapping(value = "/rand", produces = MediaType.APPLICATION_JSON_VALUE)
    @ResponseBody
    private RandomObj jsonEndpoint() {
        return new RandomObj();
    }

    @RequestMapping(value = "/tw")
    public String somePg() {
        return "index2";
    }
}

URL-адрес json работает нормально, но когда я пытаюсь получить доступ к localhost: 8080/tw, я получаю пустую страницу, и эта ошибка в консоли:

2017-02-22 15:37:22.076 ERROR 21494 --- [nio-8080-exec-9] o.s.boot.web.support.ErrorPageFilter     : Cannot forward to error page for request [/tw] as the response has already been committed. As a result, the response may have the wrong status code. If your application is running on WebSphere Application Server you may be able to resolve this problem by setting com.ibm.ws.webcontainer.invokeFlushAfterService to false

Я что-то не так делаю?

Ответы

Ответ 1

Статические файлы должны обслуживаться от ресурсов, а не от контроллера.

Spring Boot автоматически добавит статические веб-ресурсы, расположенные в любом из следующих каталогов:

/META-INF/resources/  
/resources/  
/static/  
/public/

рефов:
https://spring.io/blog/2013/12/19/serving-static-web-content-with-spring-boot https://spring.io/guides/gs/serving-web-content/

Ответ 2

В Spring boot доступны каталоги /META-INF/resources/, /resources/, static/ и public/ для обслуживания статического содержимого.

Таким образом, вы можете создать каталог static/ или public/ в каталоге resources/ и поместить туда свое статическое содержимое. И они будут доступны по: http://localhost:8080/your-file.ext. (при условии, что server.port равен 8080)

Вы можете настроить эти каталоги, используя spring.resources.static-locations в application.properties.

Например:

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

Теперь вы можете использовать папку custom/ в папке resources/ для обслуживания статических файлов.

Обновление:

Это также возможно с помощью конфигурации Java:

@Configuration
public class StaticConfig implements WebMvcConfigurer {

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/static/**").addResourceLocations("classpath:/custom/");
    }
}

Эта конфигурация отображает содержимое каталога custom в URL http://localhost:8080/static/**.

Ответ 3

Я использую :: Spring Boot :: (v2.0.4. RELEASE ) with Spring Framework 5

Spring Boot 2.0 требует Java 8 как минимальную версию. Многие существующие API были обновлены, чтобы использовать преимущества функций Java 8, таких как: методы по умолчанию на интерфейсах, функциональные обратные вызовы и новые API, такие как javax.time.

В статических материалах

По умолчанию Spring Boot загружает статический контент из каталога с именем /static (или /public или /resources или /META-INF/ ресурсов) в пути к классам или из корня ServletContext. Он использует ResourceHttpRequestHandler из Spring MVC, чтобы вы могли изменить это поведение, добавив свой собственный WebMvcConfigurer и переопределив метод addResourceHandlers.

По умолчанию ресурсы отображаются в /** и находятся в каталоге /static. Но вы можете настраивать статические формулировки программно внутри нашего класса конфигурации контекста.

@Configuration @EnableWebMvc
public class Static_ResourceHandler implements WebMvcConfigurer {

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        // When overriding default behavior, you need to add default(/) as well as added static paths(/webapp).

        // src/main/resources/static/...
        registry
            //.addResourceHandler("/**") // « /css/myStatic.css
            .addResourceHandler("/static/**") // « /static/css/myStatic.css
            .addResourceLocations("classpath:/static/") // Default Static Loaction
            .setCachePeriod( 3600 )
            .resourceChain(true) // 4.1
            .addResolver(new GzipResourceResolver()) // 4.1
            .addResolver(new PathResourceResolver()); //4.1

        // src/main/resources/templates/static/...
        registry
            .addResourceHandler("/templates/**") // « /templates/style.css
            .addResourceLocations("classpath:/templates/static/");

        // Do not use the src/main/webapp/... directory if your application is packaged as a jar.
        registry
            .addResourceHandler("/webapp/**") // « /webapp/css/style.css
            .addResourceLocations("/");

        // File located on disk
        registry
            .addResourceHandler("/system/files/**")
            .addResourceLocations("file:///D:/");
    }
}
http://localhost:8080/handlerPath/resource-path+name
                    /static         /css/myStatic.css
                    /webapp         /css/style.css
                    /templates      /style.css

Spring каждый запрос будет проходить через DispatcherServlet. Чтобы избежать запроса статического файла через DispatcherServlet (Front contoller), мы настраиваем содержимое MVC Static.

Как сказал @STEEL статические ресурсы не должны проходить через контроллер. Thymleaf - это ViewResolver, который принимает контроллер формы имени вида и добавляет prefix и suffix в View Layer.

Ответ 4

Вы можете быстро загружать статический контент в JAVA Spring-boot App через thymeleaf (ref: source)

Я предполагаю, что вы уже добавили плагин Spring Boot apply plugin: 'org.springframework.boot' и необходимый buildscript

Затем перейдите и добавьте thymeleaf к вашему build.gradle ==>

dependencies {
    compile('org.springframework.boot:spring-boot-starter-web')
    compile("org.springframework.boot:spring-boot-starter-thymeleaf")
    testCompile('org.springframework.boot:spring-boot-starter-test')
}

Допустим, вы добавили home.html в src/main/resources Чтобы обслуживать этот файл, вам нужно создать контроллер.

package com.ajinkya.th.controller;

  import org.springframework.stereotype.Controller;
  import org.springframework.web.bind.annotation.RequestMapping;

  @Controller
  public class HomePageController {

      @RequestMapping("/")
      public String homePage() {
        return "home";
      }

  }

Это оно ! Теперь перезапустите свой сервер градиентов. ./gradlew bootRun

Ответ 5

Как написано ранее, некоторые папки (/META-INF/resources/,/resources/,/static/,/public/) по умолчанию обслуживают статическое содержимое, неправильная настройка контроллера может нарушить это поведение.

Это распространенная ошибка, когда люди определяют базовый URL контроллера в аннотации @RestController вместо аннотации @RequestMapping в верхней части контроллеров.

Это неправильно:

@RestController("/api/base")
public class MyController {

    @PostMapping
    public String myPostMethod( ...) {

Приведенный выше пример запретит вам открывать index.html. Spring ожидает метод POST в корне, потому что myPostMethod сопоставлен с путем "/".

Вы должны использовать это вместо:

@RestController
@RequestMapping("/api/base")
public class MyController {

    @PostMapping
    public String myPostMethod( ...) {

Ответ 6

вы можете увидеть spring boot official пример spring boot проекте spring boot, названный spring-boot-sample-web-static.
Во-первых, вам нужно extends SpringBootServletInitializer;
Во-вторых, вам нужно override метод configure в стартовом классе Application

@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
    return builder.sources(Application.class);
}