Reputation: 1173
I cannot get spring mvc to resolve .html view files.
I have the following view folder structure:
WEB-INF
`-views
|- home.jsp
`- home.html
I have a simple hello world controller method that just prints a message and returns the view name "home". I have a home.jsp file, but would like to use the home.html instead.
<!-- 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>
When I hit spaceships/home the controller prints the hello world message and I see the home.jsp view without a problem.
The problem is when I change the suffix to .html.
After changing the suffix and navigating to /home, the controller prints the message however I see a 404 error in the browser and the following in the console: WARNING: No mapping found for HTTP request with URI [/spaceships/WEB-INF/views/home.html]
To clarify:
<!-- 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>
I have checked in the exploded war folder and can confirm that both home files are present.
Has anyone encountered something like this before?
Last chunk of console message:
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'
Thanks for reading.
=========== SOLUTION ============
The following (ugly) configuration solved the issue. There are probably ways to clean this up, but if you are experiencing the same problem you may be able to piece together a solution from this.
Folder structure:
WEB-INF
`-static
|-html
`-home.html
|-css
`-img
Controller method:
@RequestMapping(value = "/home")
public String goHome() {
System.out.println("lolololololol");
return "static/html/home";
}
Spring config:
<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>
Upvotes: 21
Views: 53298
Reputation: 11
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
Upvotes: 0
Reputation: 1
//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
Upvotes: -1
Reputation: 2991
Check this out for mapping html files in Spring mvc (Details step is given in Answer):
Which spring view resolver plays nice with angularjs?
In simple:
In order to use static resource(html,css,img,js) in spring, use a directory structure that looks like the following:
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"/>
Upvotes: 10
Reputation: 49935
This is because normally *.jsp
style uri patterns are handled by the servlet container and in this specific instance *.html
is not being handled by the container and instead the path is being delegated to Spring MVC which does not know how to render these extensions.
As an example, if you are using tomcat, you would see these entries under conf/web.xml
file:
<servlet-mapping>
<servlet-name>jsp</servlet-name>
<url-pattern>*.jsp</url-pattern>
<url-pattern>*.jspx</url-pattern>
</servlet-mapping>
i.e jsp servlet handles *.jsp, *.jspx extension.
So given this, a potential fix will be to add .html to be added to be handled by jsp servlet, as in this link:
or even better ,leave the extension as .jsp and use .html as a controller pattern instead?
Upvotes: 3