如何在 Spring MVC 中处理对静态页面的寻址
How to handle addressing to static pages in Spring MVC
我有一个 Spring MVC 应用程序正在使用 Tile3。我有很多静态页面需要将它们嵌入到tile3当前提供的网站模板中。 (我需要在所有页面上使用相同的页脚和页眉,无论是动态页面还是静态页面,但不确定如何对静态页面进行寻址)。
静态页面的示例是 index.jsp 和 aboutus.jsp。如何访问这些静态页面?我应该通过控制器来做吗?
我知道我可以使用 jsp:include 但这是一个好的做法吗?我使用的是瓷砖,没有其他选择吗? tutorial 建议使用单独的控制器,但我不确定这是否是最佳解决方案。因为它向服务器发送不必要的请求。
如果有比 Tiles 更好的选择,请告诉我
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<listener>
<listener-class>org.apache.tiles.extras.complete.CompleteAutoloadTilesListener</listener-class>
</listener>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>springapp</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springapp</servlet-name>
<url-pattern>*.htm</url-pattern>
</servlet-mapping>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/springapp-servlet.xml</param-value>
</context-param>
</web-app>
tiles.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE tiles-definitions PUBLIC
"-//Apache Software Foundation//DTD Tiles Configuration 2.1//EN"
"http://tiles.apache.org/dtds/tiles-config_2_1.dtd">
<tiles-definitions>
<definition name="baseLayout" template="/WEB-INF/templates/baseLayout.jsp">
<put-attribute name="title" value="Title is here (Tile)"/>
<put-attribute name="header" value="header.jsp"/>
<put-attribute name="menu" value="Title is here (Tile)"/>
<put-attribute name="body" value="Title is here (Tile)"/>
<put-attribute name="footer" value="footer.jsp"/>
</definition>
<definition name="hello" extends="baseLayout">
<put-attribute name="title" value="HELERE"/>
<put-attribute name="body" value="/WEB-INF/pages/pages/ewfsdfsdf.jsp"/>
</definition>
<definition name="index" extends="baseLayout">
<put-attribute name="title" value="HELERE"/>
<put-attribute name="body" value="/WEB-INF/pages/index.jsp"/>
</definition>
</tiles-definitions>
控制器
@Controller
public class HelloController {
protected final Log logger = LogFactory.getLog(getClass());
public HelloController() {
System.err.println("Constructor of HelloController");
}
@RequestMapping("/index.htm")
public String index(){
System.err.println("in index method");
return "index";
}
baseLayout.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title><tiles:insertAttribute name="title"/></title>
</head>
<body>
<div id="container">
<tiles:insertAttribute name="header"/>
<tiles:insertAttribute name="menu"/>
<tiles:insertAttribute name="body"/>
<tiles:insertAttribute name="footer"/>
</div>
</body>
</html>
index.jsp
<p>
This is the body of index page
</p>
使用JSP:include
pros
- No extra load neither on DB nor on server
cons
- To backup need to backup all static files
- Might have overwork as each page should be prepared separately rather than having a single template for all pages and just populate the template
- If need to add something to static pages need to change all pages.
您的方法应该可行,但是为每个静态页面创建一个新的 Mapper 函数并不是一个好主意。你能做的就在你的控制器中
@RequestMapping("/page/{viewName}.htm")
public String index(@PathVariable(value="viewName") String viewName, Model model){
if(isValidView(viewName)){
model.addAttribute("viewName", viewName);
return "page";
}
return null;
}
但是你必须确保 viewName 有效,否则将是安全问题。
另请阅读此article
编辑
isValidView 函数可以使用相同的 class 或 BaseController class 或调用服务来检查数据库。检查文件是否存在不是一个好主意,不是因为它占用资源,而是因为生产服务器上的路径可能不同。
如果静态页面的 body 只是 HTML 你可以加载数据库中的内容然后做
<jsp:include page="/WEB-INF/pages/header.jsp"/>
${htmlContent}
<jsp:include page="/WEB-INF/pages/footer.jsp"/>
或如果你想保持body动态。
对于tiles.xml你可以有
<definition name="pageLayout" extends="baseLayout">
<put-attribute name="title" value="HELERE"/>
<put-attribute name="body" value="/WEB-INF/page.jpg"/>
</definition>
对于page.jsp
<jsp:include page="/WEB-INF/pages/header.jsp"/>
<jsp:include page="/WEB-INF/pages/page/${viewName}.jsp"/>
<jsp:include page="/WEB-INF/pages/footer.jsp"/>
好吧,您始终可以在 baseLayout 页面上加载所有内容并创建更高级别。
我的意思是类似于以下内容:
<div id=header> <tiles:insertAttribute name="header" /></div>
<div id=header> <tiles:insertAttribute name="menu" /></div>
<iframe id='dynFrame' contenteditable="true"></iframe>'
<div id=footer> <tiles:insertAttribute name="footer" /></div>
现在,您可以使用一个简单的脚本通过菜单点击将内容加载到此 iframe,该脚本如下:
loadPage(pageLink);
而函数的内容可以是:$("#dynFrame").attr("src",pageLink);
菜单点击可以将 url 传递给 loadPage 函数,您将只有一份要加载的静态页面。
希望对您有所帮助。
我刚刚找到了一个很好的解决方案,我们可以在 servlet 中使用 <mvc:view-controller>
来处理静态页面,示例代码是 here and here,它也适用于 Tiles,只要确保你有tiles.xml
文件中每个路径的 definition
。
<mvc:view-controller path="/index" />
<mvc:view-controller path="/" view-name="index"/>
我有一个 Spring MVC 应用程序正在使用 Tile3。我有很多静态页面需要将它们嵌入到tile3当前提供的网站模板中。 (我需要在所有页面上使用相同的页脚和页眉,无论是动态页面还是静态页面,但不确定如何对静态页面进行寻址)。
静态页面的示例是 index.jsp 和 aboutus.jsp。如何访问这些静态页面?我应该通过控制器来做吗?
我知道我可以使用 jsp:include 但这是一个好的做法吗?我使用的是瓷砖,没有其他选择吗? tutorial 建议使用单独的控制器,但我不确定这是否是最佳解决方案。因为它向服务器发送不必要的请求。
如果有比 Tiles 更好的选择,请告诉我
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<listener>
<listener-class>org.apache.tiles.extras.complete.CompleteAutoloadTilesListener</listener-class>
</listener>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>springapp</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springapp</servlet-name>
<url-pattern>*.htm</url-pattern>
</servlet-mapping>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/springapp-servlet.xml</param-value>
</context-param>
</web-app>
tiles.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE tiles-definitions PUBLIC
"-//Apache Software Foundation//DTD Tiles Configuration 2.1//EN"
"http://tiles.apache.org/dtds/tiles-config_2_1.dtd">
<tiles-definitions>
<definition name="baseLayout" template="/WEB-INF/templates/baseLayout.jsp">
<put-attribute name="title" value="Title is here (Tile)"/>
<put-attribute name="header" value="header.jsp"/>
<put-attribute name="menu" value="Title is here (Tile)"/>
<put-attribute name="body" value="Title is here (Tile)"/>
<put-attribute name="footer" value="footer.jsp"/>
</definition>
<definition name="hello" extends="baseLayout">
<put-attribute name="title" value="HELERE"/>
<put-attribute name="body" value="/WEB-INF/pages/pages/ewfsdfsdf.jsp"/>
</definition>
<definition name="index" extends="baseLayout">
<put-attribute name="title" value="HELERE"/>
<put-attribute name="body" value="/WEB-INF/pages/index.jsp"/>
</definition>
</tiles-definitions>
控制器
@Controller
public class HelloController {
protected final Log logger = LogFactory.getLog(getClass());
public HelloController() {
System.err.println("Constructor of HelloController");
}
@RequestMapping("/index.htm")
public String index(){
System.err.println("in index method");
return "index";
}
baseLayout.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title><tiles:insertAttribute name="title"/></title>
</head>
<body>
<div id="container">
<tiles:insertAttribute name="header"/>
<tiles:insertAttribute name="menu"/>
<tiles:insertAttribute name="body"/>
<tiles:insertAttribute name="footer"/>
</div>
</body>
</html>
index.jsp
<p>
This is the body of index page
</p>
使用JSP:include
pros
- No extra load neither on DB nor on server
cons
- To backup need to backup all static files
- Might have overwork as each page should be prepared separately rather than having a single template for all pages and just populate the template
- If need to add something to static pages need to change all pages.
您的方法应该可行,但是为每个静态页面创建一个新的 Mapper 函数并不是一个好主意。你能做的就在你的控制器中
@RequestMapping("/page/{viewName}.htm")
public String index(@PathVariable(value="viewName") String viewName, Model model){
if(isValidView(viewName)){
model.addAttribute("viewName", viewName);
return "page";
}
return null;
}
但是你必须确保 viewName 有效,否则将是安全问题。
另请阅读此article
编辑
isValidView 函数可以使用相同的 class 或 BaseController class 或调用服务来检查数据库。检查文件是否存在不是一个好主意,不是因为它占用资源,而是因为生产服务器上的路径可能不同。
如果静态页面的 body 只是 HTML 你可以加载数据库中的内容然后做
<jsp:include page="/WEB-INF/pages/header.jsp"/>
${htmlContent}
<jsp:include page="/WEB-INF/pages/footer.jsp"/>
或如果你想保持body动态。
对于tiles.xml你可以有
<definition name="pageLayout" extends="baseLayout">
<put-attribute name="title" value="HELERE"/>
<put-attribute name="body" value="/WEB-INF/page.jpg"/>
</definition>
对于page.jsp
<jsp:include page="/WEB-INF/pages/header.jsp"/>
<jsp:include page="/WEB-INF/pages/page/${viewName}.jsp"/>
<jsp:include page="/WEB-INF/pages/footer.jsp"/>
好吧,您始终可以在 baseLayout 页面上加载所有内容并创建更高级别。 我的意思是类似于以下内容:
<div id=header> <tiles:insertAttribute name="header" /></div>
<div id=header> <tiles:insertAttribute name="menu" /></div>
<iframe id='dynFrame' contenteditable="true"></iframe>'
<div id=footer> <tiles:insertAttribute name="footer" /></div>
现在,您可以使用一个简单的脚本通过菜单点击将内容加载到此 iframe,该脚本如下:
loadPage(pageLink);
而函数的内容可以是:$("#dynFrame").attr("src",pageLink);
菜单点击可以将 url 传递给 loadPage 函数,您将只有一份要加载的静态页面。
希望对您有所帮助。
我刚刚找到了一个很好的解决方案,我们可以在 servlet 中使用 <mvc:view-controller>
来处理静态页面,示例代码是 here and here,它也适用于 Tiles,只要确保你有tiles.xml
文件中每个路径的 definition
。
<mvc:view-controller path="/index" />
<mvc:view-controller path="/" view-name="index"/>