sitemesh和spring MVC装饰器模式问题

发布于 2024-09-01 20:26:55 字数 4840 浏览 11 评论 0原文

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

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

I have sitemesh with spring working, this is the configuration:
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

<?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 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

Spring MVC Dispatcher Servlet
*.htm

and define a new pattern like 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 ?

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

寂寞美少年 2024-09-08 20:26:55

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

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

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

尽管这样您就失去了 url 映射的好处。

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.

Another option would be to configure a PageDecoratorMapper and use this tag in your original undecorated page to specify which layout to use:

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

Although then you void the benefits of url mappings.

秋意浓 2024-09-08 20:26:55

我也遇到过这个问题。发生的情况是,您在 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 服务器通过的内容。

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

<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".

You can also specify your servlet mapping this way.

<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.

我家小可爱 2024-09-08 20:26:55

也许这对某人有用,我也遇到了同样的问题,经过谷歌和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上测试

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:

/**
 * 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

<?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

情绪失控 2024-09-08 20:26:55

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

Did you try doing /spring/cliente/index* or /spring/cliente/index/*?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文