如何使用Spring提供.html文件


69

我正在用Spring开发一个网站,并试图提供不是.jsp文件(例如.html)的资源。

现在我已经注释掉了我的servlet配置的这一部分

    <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时,我的服务器现在可以正确服务该页面。

谢谢。


2
我认为[这个答案] [1]可能会有所帮助。[1]:stackoverflow.com/questions/1483063/…–
CodeChimp

不,这不是我想做的。我想拥有一个自己的文件夹,就像我用notepad ++对网站静态内容进行编程一样。存放我的index.html且所有内容都相对于该index.html的文件夹
Gleeb 2013年

Answers:


103

最初的问题是配置中指定了一个属性,suffix=".jsp"因此ViewResolver实现类将添加.jsp到从您的方法返回的视图名称的末尾。

但是,由于您注释了InternalResourceViewResolverthen,所以根据其余应用程序配置,可能未注册任何其他ViewResolver。您可能会发现现在什么也没用。

由于.html文件是静态的,不需要Servlet进行处理,因此使用<mvc:resources/>映射更加高效,简单。这需要Spring 3.0.4+。

例如:

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

这将通过启动与所有请求/static/webapp/static/目录。

因此,通过把index.htmlwebapp/static/使用return "static/index.html";从你的方法,春天应该找到视图。


3
出乎意料的是,这可行。仅需很小的更改,您就需要返回“ static / index.html”。
Gleeb

2
万分感谢!它解决了我在该项目上的许多问题
DenisFLASH,2014年

4
只是一点点。我什至不必在方法中返回“ page.html”,因为不再需要该方法。如果“方法”是指响应GET请求的@Controller类的方法,我们将不再需要它们,因为这样<mvc:resources mapping>我们将拦截所有对/ static / ...的请求,并将它们直接重定向到我们的资源中/ webapp / static,因此甚至都不会调用类似“ onHttpGet”的控制器方法。所以我评论了这种方法,它仍然有效;-)谢谢
DenisFLASH 2014年

@andyb AFAIK,没有**Servlet规范中的URL模式定义。/static/*如果要映射static路径下的所有资源,则应使用。看到这里:stackoverflow.com/questions/13843294/…如果我错了,请纠正我。
smwikipedia

1
**是Spring路径模式比较的一部分,尽管他们是从Apache Ant借来的-请参阅AntPathMatcher。使用它是完全有效的**,在我的回答中,它用于匹配任何子目录。希望这会有所帮助,但如果不能,请发表评论或提出其他问题,我很乐意提供帮助。
andyb

8

我只是补充说,您不需要为此实现控制器方法,因为您可以在servlet配置文件中使用view-controller标记(Spring 3):

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

8

问题的背景

首先要了解的是:呈现jsp文件的不是spring。它是由JspServlet(org.apache.jasper.servlet.JspServlet)完成的。该servlet随Tomcat(碧玉编译器)一起提供,而不与spring一起提供。该JspServlet知道如何编译jsp页面以及如何将其作为html文本返回给客户端。默认情况下,tomcat中的JspServlet仅处理与以下两种模式匹配的请求:* .jsp和* .jspx。

现在,当spring用InternalResourceView(或JstlView)渲染视图时,实际上发生了三件事:

  1. 从模型中获取所有模型参数(由控制器处理程序方法IE返回"public ModelAndView doSomething() { return new ModelAndView("home") }"
  2. 将这些模型参数公开为请求属性(以便JspServlet可以读取)
  3. 转发请求到JspServlet。RequestDispatcher知道每个* .jsp请求都应该转发到JspServlet(因为这是默认的tomcat的配置)

当您仅将视图名称更改为home.html时,tomcat将知道如何处理该请求。这是因为没有Servlet处理* .html请求。

如何解决这个问题。有三个最明显的解决方案:

  1. 将html公开为资源文件
  2. 指示JspServlet也处理* .html请求
  3. 编写您自己的servlet(或传递给* .html的另一个现有servlet请求)。

有关如何实现此功能的完整代码示例,请参考我在另一篇文章中的回答:如何在Spring MVC中将请求映射到HTML文件?


7

您仍然可以继续使用相同的View解析器,但是将后缀设置为空。

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

以及我尝试一起删除所有后缀。同样的交易。仅适用于.JSP而不适用于.HTML
Gleeb 2013年

不,这是一个非常有趣的解决方案。您确定这对理论以外的工作
有用

@Sashi,您能看一下我在此链接中
Lord ST

也不适合我。仅适用于.jsp(春季版本:4.3.14)。
luis-br

1

我遇到了同样的问题,并尝试了各种解决方案以从Spring MVC加载html页面,以下解决方案对我有用

服务器的web.xml中的步骤1注释了这两行

<!--     <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"; 

    }

}

Spring配置文件中的第4步将后缀更改为.htm .htm

步骤5将页面重命名为.htm文件并将其存储在WEB-INF中并构建/启动服务器

localhost:8080/.../landingPage

1

html文件的Java配置(在本例中为index.html):

@Configuration
@EnableWebMvc
public class DispatcherConfig extends WebMvcConfigurerAdapter {

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {

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

}


0

听起来您正在尝试执行以下操作:

  • 静态HTML视图
  • 服务于AJAX的Spring控制器

如果是这样,如前所述,最有效的方法是让Web服务器(而非Spring)将HTML请求作为静态资源进行处理。因此,您需要以下内容:

  1. 将所有.html,.css,.js,.png等请求转发到Web服务器的资源处理程序
  2. 将所有其他请求映射到spring控制器

这是完成此任务的一种方法...

web.xml-将servlet映射到根(/)

<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重写过滤器。
  • 模板化-您不想在每个HTML页面中为通用元素重复标记。如果将HTML用作静态资源,则可能无法在服务器上完成此操作。查看客户端* VC框架。我是YUI的粉丝,它具有许多模板机制,包括把手。

0

如果您使用的春天开机,你不能设置属性spring.mvc.view.prefix,并spring.mvc.view.suffix在application.properties文件,而不是配置的beanViewResolver从配置类。

application.properties

# Configured in @Configuration GuestNav
#spring.mvc.view.prefix=/WEB-INF/views/
#spring.mvc.view.suffix=.jsp
# Live reload
spring.devtools.restart.additional-paths=.
# Better logging
server.tomcat.accesslog.directory=logs
server.tomcat.accesslog.file-date-format=yyyy-MM-dd
server.tomcat.accesslog.prefix=access_log
server.tomcat.accesslog.suffix=.log

主要方法

@SpringBootApplication
public class WebApp extends SpringBootServletInitializer {

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(WebApp.class);
    }

    public static void main(String[] args) throws Exception {
        SpringApplication.run(WebApp.class, args);
    }

}

配置类

@Configuration
@EnableWebMvc
public class DispatcherConfig implements WebMvcConfigurer {

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

    @Bean
    public ViewResolver viewResolver() {
        InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
        viewResolver.setViewClass(JstlView.class);
        viewResolver.setPrefix("/WEB-INF/notinuse/");
        viewResolver.setSuffix("");
        return viewResolver;
    }

}

控制器类

@Controller
public class GuestNav {

    @GetMapping("/")
    public String home() {
        return "forward:/views/guest/index.html";
    }
}

您必须将文件放置在目录中/webapp/views/guest/index.html,请注意,webapp目录位于资源目​​录之外。
这样,您可以使用spring-mvc的url模式,但可以提供静态上下文。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.