【问题标题】:Spring MVC ViewResolver not mapping to HTML filesSpring MVC ViewResolver 未映射到 HTML 文件
【发布时间】:2014-09-18 18:58:07
【问题描述】:

我无法让 spring mvc 解析 .html 视图文件。

我有以下视图文件夹结构:

WEB-INF
      `-views
            |- home.jsp
            `- home.html

我有一个简单的 hello world 控制器方法,它只打印一条消息 并返回视图名称“home”。我有一个 home.jsp 文件,但想要 改为使用 home.html。

<!-- Working servlet mapping --> 
<servlet-mapping>
    <servlet-name>spaceShips</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

<!-- working servlet context -->
<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> 
    <beans:property name="prefix" value="WEB-INF/views/" />
    <beans:property name="suffix" value=".jsp" /> 
</beans:bean>

当我点击 spaceships/home 时,控制器会打印出 hello world 消息,我会看到 home.jsp 查看没有问题。

问题是当我将后缀更改为 .html 时。

更改后缀并导航到 /home 后,控制器会打印 消息但是我在浏览器中看到 404 错误,在控制台中看到以下内容: 警告:未找到带有 URI [/spaceships/WEB-INF/views/home.html] 的 HTTP 请求的映射

澄清一下:

<!-- not working with .html -->
<servlet-mapping>
    <servlet-name>spaceShips</servlet-name>
    <!-- I have tried /* here as well without success -->
    <url-pattern>/</url-pattern>
</servlet-mapping>

<!-- not working with .html-->
<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> 
    <beans:property name="prefix" value="WEB-INF/views/" />
    <beans:property name="suffix" value=".html" /> 
</beans:bean>

我已经检查了分解的战争文件夹,并且可以确认两个主文件都存在。

有没有人遇到过这样的事情?

最后一段控制台消息:

INFO: Server startup in 5256 ms
Hello, World!
Jul 27, 2014 12:52:01 PM org.springframework.web.servlet.DispatcherServlet noHandlerFound
WARNING: No mapping found for HTTP request with URI [/spaceships/WEB-INF/views/home.html] in DispatcherServlet with name 'spaceShips'

感谢阅读。

=========== 解决方案============

以下(丑陋的)配置解决了这个问题。可能有一些方法可以解决这个问题,但如果您遇到同样的问题,您也许可以从中拼凑出一个解决方案。

文件夹结构:

 WEB-INF
       `-static
              |-html
                    `-home.html
              |-css
              `-img

控制器方法:

 @RequestMapping(value = "/home")
 public String goHome() { 
      System.out.println("lolololololol");
      return "static/html/home";
 }

弹簧配置:

 <resources mapping="/static/**" location="/WEB-INF/static/" />

 <beans:bean
    class="org.springframework.web.servlet.view.InternalResourceViewResolver">
      <beans:property name="prefix" value="" />
      <beans:property name="suffix" value=".html" />
 </beans:bean>

【问题讨论】:

  • 在您的控制器中,@Path 可能必须具有 .html 扩展名。
  • 我有同样的问题,但我得到 405 而不是 404 错误。据我了解的问题是资源处理只接受 GET 请求,所以当我在发布表单后重定向到 index.html如果用户已注册,则使用 POST 请求并重定向到 index.html!
  • 感谢您发布解决方案。其他主题缺乏资源映射和 InternalResourceViewResolver 的正确组合。
  • 尝试使用&lt;dependency&gt; &lt;groupId&gt;org.apache.velocity&lt;/groupId&gt; &lt;artifactId&gt;velocity&lt;/artifactId&gt; &lt;version&gt;1.7&lt;/version&gt; &lt;/dependency&gt;

标签: spring spring-mvc


【解决方案1】:

检查一下在 Spring mvc 中映射 html 文件(详细步骤在答案中给出):

Which spring view resolver plays nice with angularjs?

简单来说:

为了在spring中使用静态资源(html,css,img,js),使用如下目录结构:

src/
   package/
   LayoutController.java
WebContent/
   WEB-INF/
    static/
      html/
       layout.html
      images/
       image.jpg
      css/
       test.css
      js/
       main.js
     web.xml
    springmvc-servlet.xml


@Controller 
public class LayoutController {

 @RequestMapping("/staticPage") 
public String getIndexPage() { 
return "layout.htm"; 

} }




<!-- in spring config file -->
 <mvc:resources mapping="/static/**" location="/WEB-INF/static/" />

layout.html

<h1>Page with image</h1>
<img src="/static/img/image.jpg"/>

【讨论】:

  • 感谢您的回复。我已将文件夹结构更新为您建议的结构。我还在 spring 配置文件中添加了资源映射。不幸的是,我仍然看到同样的问题 - 调用了控制器方法,但在控制台中“找不到映射......”。我尝试了不同的视图解析器实现,并尝试将“.html”添加到返回的视图名称(现在它寻找“home.html.jsp”)。
【解决方案2】:

这是因为通常*.jsp 样式的 uri 模式由 servlet 容器处理,在此特定实例中,*.html 不由容器处理,而是将路径委托给不知道如何处理的 Spring MVC渲染这些扩展。

例如,如果您使用的是 tomcat,您会在 conf/web.xml 文件下看到这些条目:

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

即 jsp servlet 处理 *.jsp、*.jspx 扩展名。

因此,考虑到这一点,一个潜在的解决方法是添加 .html 以供 jsp servlet 处理,如以下链接所示:

Using .html files as JSPs

或者更好的是,将扩展名保留为 .jsp 并使用 .html 作为控制器模式?

【讨论】:

  • 感谢您的建议。我已经尝试将“.html”添加到返回的视图名称中,但它现在正在尝试解析视图名称“home.html.jsp”。如果有办法避免更改 tomcat 配置文件,我更喜欢这种方法。再次感谢。
【解决方案3】:
I was also facing the same issue and tried various solutions to load the AngularJS html file using Spring configuration. After applying below steps it got resolved.

Step-1 in server's web.xml commemt these two lines

<!--     <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 enter following code in application's web xml

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


Step-3

create a static controller class 

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

    }

}
Step-4 in the Spring configuration file change the suffix to .htm
        <property name="suffix">
            <value>.htm</value>
        </property>

Step-5
Rename page as .htm file and store it in WEB-INF and build/start the server 

localhost:8080/.../landingPage

【讨论】:

【解决方案4】:
//Finally a working solution both html and jsp view together 
------------------------------------------------------------------------

public class ChainableInternalResourceViewResolver extends InternalResourceViewResolver {

    private static Log logger = LogFactory.getLogger(ChainableInternalResourceViewResolver.class);

    /**
     * 
     */
    protected AbstractUrlBasedView buildView(String viewName) throws Exception {
        logger.entering("buildView");
        String url = getPrefix() + viewName + getSuffix();
        InputStream stream = getServletContext().getResourceAsStream(url);
        if (stream == null) {
            logger.log(Log.DEBUG,"-----!!!------resource not found-------!!!-----"+getPrefix() + viewName + getSuffix());
            return new NonExistentView();
        } else {
            logger.log(Log.DEBUG,"----***-------resource found-------***-----"+getPrefix() + viewName + getSuffix());
            stream.close();
        }
        return super.buildView(viewName);
    }

    /**
     * 
     * @author 
     *
     */
    private static class NonExistentView extends AbstractUrlBasedView {

        //private static Log logger = LogFactory.getLogger(NonExistentView.class);

        protected boolean isUrlRequired() {
            //logger.entering("isUrlRequired");
            return false;
        }

        public boolean checkResource(Locale locale) throws Exception {
            //logger.entering("checkResource");
            return false;
        }

        protected void renderMergedOutputModel(Map<String, Object> model, HttpServletRequest request,
                HttpServletResponse response) throws Exception {
            //logger.entering("renderMergedOutputModel");
            // Purposely empty, it should never get called
        }
    }
}

----------------------------------------------------------------------------
@EnableWebMvc
@Configuration
@ComponentScan({ "com.*" })
public class ApplicationConfig extends WebMvcConfigurerAdapter {

    //Be careful while changing here
    private static final String VIEW_DIR_HTML = "/WEB-INF/static/";
    private static final String VIEW_EXTN_HTML = ".html";

    private static final String VIEW_DIR_JSP = "/WEB-INF/";
    private static final String VIEW_EXTN_JSP = ".jsp";

    private static final String RESOURCE_URL_PATTERN_1 = "/resources/**";
    private static final String RESOURCE_URL_PATTERN_2 = "/WEB-INF/static/**";
    private static final String RESOURCE_PATH_1 = "/resources/";
    private static final String RESOURCE_PATH_2 = "/WEB-INF/static/";

    private static Logger logger = LoggerFactory.getLogger(ApplicationConfig.class);

    /**
     * 
     * @return
     */
    @Bean
    public ViewResolver htmlViewResolver() {
        logger.info(" htmlViewResolver method ");
        InternalResourceViewResolver viewResolver= new ChainableInternalResourceViewResolver();
        viewResolver.setPrefix(VIEW_DIR_HTML);
        viewResolver.setSuffix(VIEW_EXTN_HTML);
        viewResolver.setOrder(0);
        return viewResolver;
    }

    @Bean
    public ViewResolver jspViewResolver() {
        logger.info(" jspViewResolver method ");
        InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
        viewResolver.setPrefix(VIEW_DIR_JSP);
        viewResolver.setSuffix(VIEW_EXTN_JSP);
        viewResolver.setOrder(1);
        return viewResolver;
    }

--------------------------------------------------------------------------------
return "pages/login"; // for login.html resides inside /WEB-INF/static/pages/login.html

return "jsp/login"; // for login.jsp resides inside /WEB-INF/jsp/login.jsp

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-12
    • 1970-01-01
    • 1970-01-01
    • 2012-08-14
    • 2015-12-05
    • 1970-01-01
    相关资源
    最近更新 更多