70

我正在使用 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 时,我的服务器现在可以正确地为页面提供服务。

谢谢你。

4

9 回答 9

104

最初的问题是配置指定了一个属性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";,Spring 应该会找到视图。

于 2013-03-18T15:17:54.350 回答
8

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

<mvc:view-controller path="/" view-name="/WEB-INF/jsp/index.html"/>
于 2013-12-03T12:07:08.927 回答
8

问题的背景

首先要了解的是:呈现jsp文件的不是spring。是 JspServlet (org.apache.jasper.servlet.JspServlet) 做的。这个 servlet 带有 Tomcat(jasper 编译器)而不是 spring。这个 JspServlet 知道如何编译 jsp 页面以及如何将其作为 html 文本返回给客户端。默认情况下,tomcat 中的 JspServlet 只处理匹配两种模式的请求:*.jsp 和 *.jspx。

InternalResourceView现在,当 spring 用(or )渲染视图时JstlView,真正发生了三件事:

  1. 从模型中获取所有模型参数(由您的控制器处理程序方法返回,即"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(或将请求传递给另一个现有的 servlet 到 *.html)。

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

于 2015-09-17T10:56:34.583 回答
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";
}   
于 2013-03-18T14:56:13.203 回答
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>
 -->

Step-2 在应用程序的 web xml 中输入以下代码

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

Step-3 创建一个静态控制器类

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

    }

}

Step-4 在Spring配置文件中修改后缀为.htm .htm

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

localhost:8080/.../landingPage
于 2016-08-05T04:05:08.513 回答
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");
    }

}
于 2017-04-23T20:47:18.817 回答
0

相应地更改 p:suffix=".jsp" 值,否则我们可以开发自定义视图解析器

http://static.springsource.org/spring/docs/3.1.x/javadoc-api/org/springframework/web/servlet/view/UrlBasedViewResolver.html

于 2013-03-18T14:37:24.833 回答
0

听起来你正在尝试做这样的事情:

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

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

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

这是实现这一目标的一种方法...

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>

春天的 Java 配置

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 的粉丝,它有许多模板机制,包括 Handlebars。
于 2016-06-24T22:45:17.317 回答
0

如果您使用 spring boot,则不能在 application.properties 文件中设置属性spring.mvc.view.prefix,而是从配置类spring.mvc.view.suffix配置 bean 。ViewResolver

应用程序属性

# 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 模式,但提供静态上下文。

于 2019-11-09T06:11:19.257 回答