Как обслуживать файлы .html с помощью Spring

Я разрабатываю веб-сайт с Spring и пытаюсь обслуживать ресурсы, которые не являются файлами .jsp(например,.html).

прямо сейчас я прокомментировал эту часть моей конфигурации сервлета

    <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver" 
        p:prefix="/WEB-INF/jsp/" p:suffix=".jsp" />

И попытался вернуть с контроллера полный путь к ресурсу.

@Controller
public class LandingPageController {

protected static Logger logger = Logger.getLogger(LandingPageController.class);

@RequestMapping({"/","/home"})
public String showHomePage(Map<String, Object> model) {
    return "/WEB-INF/jsp/index.html";   
   }
}

файл index.html существует в этой папке.

ПРИМЕЧАНИЕ. Когда я меняю index.html на index.jsp, мой сервер теперь правильно обслуживает страницу.

Спасибо.

Ответы

Ответ 1

Первоначальная проблема заключается в том, что в конфигурации указано свойство suffix=".jsp", поэтому класс реализации ViewResolver добавит .jsp в конец имени представления, возвращаемого из вашего метода.

Однако, поскольку вы прокомментировали InternalResourceViewResolver, тогда, в зависимости от остальной конфигурации вашего приложения, может быть не зарегистрировано ни одного другого зарегистрированного ViewResolver. Вы можете обнаружить, что сейчас ничего не работает.

Так как файлы .html являются статическими и не требуют обработки сервлетом, то более эффективно и проще использовать сопоставление <mvc:resources/>. Для этого требуется Spring 3.0.4 +.

Например:

<mvc:resources mapping="/static/**" location="/static/" />

который будет проходить через все запросы, начинающиеся с /static/, в каталог webapp/static/.

Итак, поместив index.html в webapp/static/ и используя return "static/index.html"; из вашего метода, Spring должен найти представление.

Ответ 2

Предыстория проблемы

Первое, что нужно понять, следующее: это НЕ spring, который отображает файлы jsp. Это делает JspServlet (org.apache.jasper.servlet.JspServlet). Этот сервлет поставляется с компилятором Tomcat (jasper), а не с spring. Этот JspServlet знает, как скомпилировать jsp-страницу и как вернуть ее в виде html-текста клиенту. JspServlet в tomcat по умолчанию обрабатывает запросы, соответствующие двум шаблонам: *.jsp и *.jspx.

Теперь, когда spring отображает представление с помощью InternalResourceView (или JstlView), три вещи действительно имеют место:

  • получить все параметры модели из модели (возвращается методом обработчика контроллера, т.е. "public ModelAndView doSomething() { return new ModelAndView("home") }")
  • выставить эти параметры модели в качестве атрибутов запроса (чтобы их можно было прочитать JspServlet)
  • запрос вперед в JspServlet. RequestDispatcher знает, что каждый запрос *.jsp должен быть перенаправлен в JspServlet (поскольку это настройка по умолчанию tomcat)

Когда вы просто меняете имя вида на home.html, tomcat не будет знать, как обрабатывать запрос. Это связано с тем, что обработчики сервлета не обрабатываются *.html.

Решение

Как это решить. Существует три наиболее очевидных решения:

  • выставить html в качестве файла ресурсов
  • поручить JspServlet также обрабатывать запросы *.html
  • напишите свой собственный сервлет (или перейдите к другим существующим запросам сервлетов в *.html).

Для получения полного кода примера, как это сделать, пожалуйста, обратитесь к моему ответу в другом сообщении: Как сопоставить запросы к HTML файлу в spring MVC?

Ответ 3

Я бы добавил, что вам не нужно внедрять для него метод контроллера, так как вы можете использовать тег view-controller (Spring 3) в файле конфигурации сервлета:

<mvc:view-controller path="/" view-name="/WEB-INF/jsp/index.html"/>

Ответ 4

Вы по-прежнему можете использовать один и тот же вид распознавателя, но установить суффикс в пустую.

<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver" 
    p:prefix="/WEB-INF/jsp/" p:suffix="" />

Теперь ваш код может выбрать для возврата index.html или index.jsp, как показано в примере ниже -

@RequestMapping(value="jsp", method = RequestMethod.GET )
public String startJsp(){
    return "/test.jsp";
}

@RequestMapping(value="html", method = RequestMethod.GET )
public String startHtml(){
    return "/test.html";
}   

Ответ 5

Я столкнулся с той же проблемой и попробовал различные решения для загрузки html страница из Spring MVC, следующее решение работало для меня

Шаг 1 в сервере web.xml прокомментирует эти две строки

<!--     <mime-mapping>
        <extension>htm</extension>
        <mime-type>text/html</mime-type>
    </mime-mapping>--> 
<!--     <mime-mapping>
        <extension>html</extension>
        <mime-type>text/html</mime-type>
    </mime-mapping>
 -->

Шаг-2 введите следующий код в приложении web xml

  <servlet-mapping>
    <servlet-name>jsp</servlet-name>
    <url-pattern>*.htm</url-pattern>
</servlet-mapping>

Шаг 3 создает класс статического контроллера

@Controller 
public class FrontController {
     @RequestMapping("/landingPage") 
    public String getIndexPage() { 
    return "CompanyInfo"; 

    }

}

Шаг 4 в конфигурационном файле Spring изменит суффикс на .htm                          .htm           

Шаг-5 Переименуйте страницу как .htm файл и сохраните его в WEB-INF и создайте/запустите сервер

localhost:8080/.../landingPage

Ответ 7

Похоже, вы пытаетесь сделать что-то вроде этого:

  • Статические представления HTML
  • Spring контроллеры, обслуживающие AJAX

Если это так, как было сказано ранее, наиболее эффективным способом является то, чтобы веб-сервер (а не Spring) обрабатывал запросы HTML как статические ресурсы. Поэтому вам понадобится следующее:

  • Переслать все .html,.css,.js,.png и т.д. запросы на обработчик ресурсов веб-сервера
  • Сопоставьте все остальные запросы с контроллерами spring

Вот один из способов добиться этого...

web.xml. Создайте сервлет сервлета (/)

<servlet>
            <servlet-name>sprung</servlet-name>
            <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
            ...
<servlet>

<servlet-mapping>
            <servlet-name>sprung</servlet-name>
            <url-pattern>/</url-pattern>
</servlet-mapping>

Spring JavaConfig

public class SpringSprungConfig extends DelegatingWebMvcConfiguration {

    // Delegate resource requests to default servlet
    @Bean
    protected DefaultServletHttpRequestHandler defaultServletHttpRequestHandler() {
        DefaultServletHttpRequestHandler dsrh = new DefaultServletHttpRequestHandler();
        return dsrh;
    }

    //map static resources by extension
    @Bean
    public SimpleUrlHandlerMapping resourceServletMapping() {
        SimpleUrlHandlerMapping mapping = new SimpleUrlHandlerMapping();

        //make sure static resources are mapped first since we are using
        //a slightly different approach
        mapping.setOrder(0);
        Properties urlProperties = new Properties();
        urlProperties.put("/**/*.css", "defaultServletHttpRequestHandler");
        urlProperties.put("/**/*.js", "defaultServletHttpRequestHandler");
        urlProperties.put("/**/*.png", "defaultServletHttpRequestHandler");
        urlProperties.put("/**/*.html", "defaultServletHttpRequestHandler");
        urlProperties.put("/**/*.woff", "defaultServletHttpRequestHandler");
        urlProperties.put("/**/*.ico", "defaultServletHttpRequestHandler");
        mapping.setMappings(urlProperties);
        return mapping;
    }

    @Override
    @Bean
    public RequestMappingHandlerMapping requestMappingHandlerMapping() {
        RequestMappingHandlerMapping handlerMapping = super.requestMappingHandlerMapping();

        //controller mappings must be evaluated after the static resource requests
        handlerMapping.setOrder(1);
        handlerMapping.setInterceptors(this.getInterceptors());
        handlerMapping.setPathMatcher(this.getPathMatchConfigurer().getPathMatcher());
        handlerMapping.setRemoveSemicolonContent(false);
        handlerMapping.setUseSuffixPatternMatch(false);
        //set other options here
        return handlerMapping;
    }
}

Дополнительные соображения

  • Скрыть расширение .html. Это не входит в область spring, если вы делегируете статические запросы ресурсов. Посмотрите на фильтр перезаписи URL.
  • Templating. Вы не хотите дублировать разметку на каждой странице HTML для общих элементов. Вероятно, это невозможно сделать на сервере, если вы используете HTML как статический ресурс. Посмотрите на клиентскую инфраструктуру VC. Я поклонник YUI, у которого есть многочисленные механизмы шаблонов, включая Handlebars.

Ответ 8

Конфигурация Java для html файлов (в этом случае index.html):

@Configuration
@EnableWebMvc
public class DispatcherConfig extends WebMvcConfigurerAdapter {

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {

        registry.addResourceHandler("/index.html").addResourceLocations("/index.html");
    }

}