sitemesh and spring MVC decorator pattern problems

后端 未结 4 1326
借酒劲吻你
借酒劲吻你 2021-01-03 13:15

I have sitemesh with spring working, this is the configuration: decorator.xml




        
相关标签:
4条回答
  • 2021-01-03 13:36

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

    0 讨论(0)
  • 2021-01-03 13:37

    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.

    0 讨论(0)
  • 2021-01-03 13:39

    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

    0 讨论(0)
  • 2021-01-03 13:47

    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.

    0 讨论(0)
提交回复
热议问题