java sitemesh 和 spring MVC 装饰器模式问题
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2859014/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
sitemesh and spring MVC decorator pattern problems
提问by atomsfat
I have sitemesh with spring working, this is the configuration: decorator.xml
我有 spring 工作的站点网格,这是配置:decorator.xml
<?xml version="1.0" encoding="UTF-8"?>
<decorators defaultdir="/styles">
<excludes>
<pattern>/exclude.jsp</pattern>
<pattern>/exclude/*</pattern>
</excludes>
<decorator page="application/themeManager/theme.jsp" name="dos">
<pattern>/*</pattern>
</decorator>
</decorators>
And this is my web.xml
这是我的web.xml
<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app 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"
version="2.4">
<!-- The master configuration file for this Spring web application -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/config/web-application-config.xml
</param-value>
</context-param>
<!-- Enables Spring Security -->
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- Agregamos el filtro de sitemesh que permite interceptar todas las llamadas que necesitamos -->
<filter>
<filter-name>sitemesh</filter-name>
<filter-class>com.opensymphony.sitemesh.webapp.SiteMeshFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>sitemesh</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
<dispatcher>ERROR</dispatcher>
</filter-mapping>
<!-- Loads the Spring web application context -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- Serves static resource content from .jar files such as spring-faces.jar -->
<servlet>
<servlet-name>Resources Servlet</servlet-name>
<servlet-class>org.springframework.js.resource.ResourceServlet</servlet-class>
<load-on-startup>0</load-on-startup>
</servlet>
<!-- Map all /resources requests to the Resource Servlet for handling -->
<servlet-mapping>
<servlet-name>Resources Servlet</servlet-name>
<url-pattern>/resources/*</url-pattern>
</servlet-mapping>
<!-- The front controller of this Spring Web application, responsible for handling all application requests -->
<servlet>
<servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value></param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<!-- Map all *.spring requests to the DispatcherServlet for handling -->
<servlet-mapping>
<servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
<url-pattern>/spring/*</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
</web-app>
This work, but when I change the pattern in decorator.xml for something like
这项工作,但是当我更改decorator.xml中的模式时
<decorator page="application/themeManager/theme.jsp" name="dos">
<pattern>/spring/cliente/index</pattern>
</decorator>
it doesn't work, I try a lot of combination and nothing. Then I change the mapping for the spring servlet in the web.xml like this
它不起作用,我尝试了很多组合,但一无所获。然后我像这样更改 web.xml 中 spring servlet 的映射
Spring MVC Dispatcher Servlet *.htm
Spring MVC Dispatcher Servlet *.htm
and define a new patternlike this:
并定义一个这样的新模式:
<decorator page="application/themeManager/theme.jsp" name="dos">
<pattern>/cliente/index.htm</pattern>
</decorator>
And it works, so is there any way to make this to work with this mapping for the spring servlet ?
它可以工作,那么有什么方法可以使它与 spring servlet 的映射一起工作?
<servlet-mapping>
<servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
<url-pattern>/spring/*</url-pattern>
</servlet-mapping>
回答by fargraph
The problem is that SiteMesh uses Request.getServletPath() which in your spring mvc application will return "/spring" for everything. I found this by implementing the com.opensymphony.module.sitemesh.DecoratorMapper interface and using it in place of the normal ConfigDecoratorMapper. Then I was able to inspect the various arguments used to map decorators to requests. Unfortunately, I think this leaves you with the only option being to use the *.html suffix in the DispatcherServelet mapping or some variant thereof.
问题是 SiteMesh 使用 Request.getServletPath() ,它在您的 spring mvc 应用程序中将为所有内容返回“/spring”。我通过实现 com.opensymphony.module.sitemesh.DecoratorMapper 接口并使用它代替普通的 ConfigDecoratorMapper 发现了这一点。然后我能够检查用于将装饰器映射到请求的各种参数。不幸的是,我认为这让您唯一的选择是在 DispatcherServelet 映射或其某些变体中使用 *.html 后缀。
Another option would be to configure a PageDecoratorMapper and use this tag in your original undecorated page to specify which layout to use:
另一种选择是配置 PageDecoratorMapper 并在原始未装饰页面中使用此标记来指定要使用的布局:
<meta name="decorator" content="layoutName" />
Although then you void the benefits of url mappings.
虽然那样你就失去了 url 映射的好处。
回答by Inf-root
Maybe it will be useful for someone, I have got the same problem, and after research in google and stading sitemesh sources, solve the problem, by extending ConfigDecoratorMapping. Here is it:
也许它对某人有用,我遇到了同样的问题,经过对 google 和 stading sitemesh 源的研究,通过扩展 ConfigDecoratorMapping 解决了这个问题。就这个:
/**
* Created by IntelliJ IDEA.
* User: Inf-root
* Date: 30.06.11
* Time: 1:00
*
*/
public class ConfigDecoratorMapperSpringMvcSupport extends ConfigDecoratorMapper {
private static final Logger LOG = Logger.getLogger(ConfigDecoratorMapperSpringMvcSupport.class);
private ConfigLoader configLoader = null;
/** Create new ConfigLoader using '/WEB-INF/decorators.xml' file. */
public void init(Config config, Properties properties, DecoratorMapper parent) throws InstantiationException {
LOG.debug("init()...");
super.init(config, properties, parent);
try {
String fileName = properties.getProperty("config", "/WEB-INF/decorators.xml");
configLoader = new ConfigLoader(fileName, config);
}
catch (Exception e) {
throw new InstantiationException(e.toString());
}
}
/** Retrieve {@link com.opensymphony.module.sitemesh.Decorator} based on 'pattern' tag. */
public Decorator getDecorator(HttpServletRequest request, Page page) {
LOG.debug("getDecorator()...");
String thisPath = request.getServletPath();
LOG.debug("\tThisPath: " + thisPath);
String requestURI = request.getRequestURI();
LOG.debug("\t\tGet request URI: " + requestURI);
//TODO check indexes
thisPath = "/springURITemplate" + requestURI.substring(request.getContextPath().length(), requestURI.length() - 1);
LOG.debug("\t\t\tThisPath: " + thisPath);
String name = null;
try {
name = configLoader.getMappedName(thisPath);
}
catch (ServletException e) {
e.printStackTrace();
}
LOG.debug("\tResolved decorator name: " + name);
Decorator result = getNamedDecorator(request, name);
LOG.debug("Decorator is null ? " + (result == null));
return result == null ? super.getDecorator(request, page) : result;
}
}
and my decorators.xml contains something like this
我的decorators.xml包含这样的东西
<?xml version="1.0" encoding="ISO-8859-1"?>
<decorators defaultdir="/web/decorators">
<decorator name="admin_decorator" page="admin_decorator.jsp">
<pattern>/springURITemplate/a/administration*</pattern>
</decorator>
</decorators>
Tested on tomcat 7 with Spring 3.0.5
在带有 Spring 3.0.5 的 tomcat 7 上测试
回答by GMK
I've had that exact problem. What's happening is that any part of the url path you specify in the web.xml gets stripped out by the web server before it gets passed to Spring, but only if you put the wildcard at the end. You have already discovered that when your url is www.myapp.com/spring/cliente/index.html, if you put this in your web.xml
我遇到了那个确切的问题。发生的情况是,您在 web.xml 中指定的 url 路径的任何部分在传递给 Spring 之前都会被 Web 服务器剥离,但前提是您将通配符放在最后。你已经发现,当你的 url 是 www.myapp.com/spring/cliente/index.html 时,如果你把它放在你的 web.xml 中
<servlet-mapping>
<servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
<url-pattern>/spring/*</url-pattern>
</servlet-mapping>
Spring will only see the part of the request path after the /spring. In that case you need to specify your RequestMapping as "/cliente/index.html".
Spring 只会看到 /spring 之后的请求路径部分。在这种情况下,您需要将 RequestMapping 指定为“/cliente/index.html”。
You can also specify your servlet mapping this way.
您还可以通过这种方式指定 servlet 映射。
<servlet-mapping>
<servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
<url-pattern>*.html</url-pattern>
</servlet-mapping>
Then Spring will see the entire request path and you can specify your request mappings like this "/spring/cliente/index.html". The same goes for Sitemesh. It only sees what the web server passes through.
然后 Spring 将看到整个请求路径,您可以像这样“/spring/cliente/index.html”指定您的请求映射。Sitemesh 也是如此。它只看到 Web 服务器通过的内容。
回答by ballmw
Did you try doing /spring/cliente/index* or /spring/cliente/index/*?
您是否尝试过 /spring/cliente/index* 或 /spring/cliente/index/*?

