【问题标题】:sitemesh and spring MVC decorator pattern problemssitemesh 和 spring MVC 装饰器模式问题
【发布时间】:2011-02-20 23:42:59
【问题描述】:

我有使用 spring 工作的 sitemesh,这是配置: 装饰器.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>

这是我的 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>

这项工作,但是当我将 decorator.xml 中的模式更改为类似

<decorator page="application/themeManager/theme.jsp" name="dos">
    <pattern>/spring/cliente/index</pattern>
</decorator>

它不起作用,我尝试了很多组合,但什么也没有。 然后我像这样更改 web.xml 中 spring servlet 的映射

Spring MVC 调度程序 Servlet *.htm

并像这样定义一个新模式:

<decorator page="application/themeManager/theme.jsp" name="dos">
    <pattern>/cliente/index.htm</pattern>
</decorator>

它可以工作,那么有什么方法可以使它与 spring servlet 的映射一起工作?

<servlet-mapping>
    <servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
    <url-pattern>/spring/*</url-pattern>
</servlet-mapping>

【问题讨论】:

标签: java spring spring-mvc sitemesh


【解决方案1】:

也许它对某人有用,我遇到了同样的问题,在谷歌研究和 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;
    }
}

我的 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>

使用 Spring 3.0.5 在 tomcat 7 上测试

【讨论】:

    【解决方案2】:

    问题是 SiteMesh 使用 Request.getServletPath() ,它在你的 spring mvc 应用程序中将为所有内容返回“/spring”。我通过实现 com.opensymphony.module.sitemesh.DecoratorMapper 接口并使用它代替普通的 ConfigDecoratorMapper 发现了这一点。然后我能够检查用于将装饰器映射到请求的各种参数。不幸的是,我认为这让您唯一的选择是在 DispatcherServelet 映射或其某些变体中使用 *.html 后缀。

    另一种选择是配置一个 PageDecoratorMapper 并在原始未装饰页面中使用此标记来指定要使用的布局:

     <meta name="decorator" content="layoutName" /> 
    

    虽然这样你就失去了 url 映射的好处。

    【讨论】:

      【解决方案3】:

      我遇到过这个问题。发生的情况是,您在 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 只会看到 /spring 之后的请求路径部分。在这种情况下,您需要将 RequestMapping 指定为“/cliente/index.html”。

      您也可以通过这种方式指定您的 servlet 映射。

      <servlet-mapping>
         <servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
         <url-pattern>*.html</url-pattern>
      </servlet-mapping>
      

      然后Spring会看到整个请求路径,你可以像这样“/spring/cliente/index.html”指定你的请求映射。 Sitemesh 也是如此。它只看到 Web 服务器经过的内容。

      【讨论】:

        【解决方案4】:

        您是否尝试过 /spring/cliente/index* 或 /spring/cliente/index/*?

        【讨论】:

        • 在查看我的 decorators.xml 时,我发现我在开始时使用了 /。你可以试试 */spring/client/index 或 /spring/cliente/index/
        • 您使用的是什么应用服务器。因为这在 OAS 中实际上是不同的。
        猜你喜欢
        • 2013-08-02
        • 2016-10-05
        • 1970-01-01
        • 2011-08-19
        • 1970-01-01
        • 2011-05-21
        • 2013-08-25
        • 2011-05-19
        相关资源
        最近更新 更多