Adoiyai, masalah besar gak ni. Sitemesh tak gunakan mapping untuk pattern yang disytiharkan.
<decorator name="default" page="deco-default.jsp">
<pattern>*/main*</pattern>
<pattern>*/list*</pattern>
<pattern>*/marking/*</pattern>
</decorator>
Kesemua pattern di atas tidak dikenali, sebaliknya sitemesh hanya kenal pattern "/app".
Baca punya baca, rupa-rupanya kerana hanya "/app" sahaja yang ditunjukkan kepada Sitemesh oleh Spring.
Rujuk blog ini untuk keterangan:
http://fahadshaon.wordpress.com/2012/07/24/sitemesh-2-with-spring-mvc-3-multiple-layout-for-multiple-controller/.
Namun solution gunakan "*.html" agak drastik maka solution lain perlu dicari. Akhirnya tiba ke forum berikut:
http://stackoverflow.com/questions/2859014/sitemesh-and-spring-mvc-decorator-pattern-problems.
Setelah buat class ConfigDecoratorMapperSpringMvcSupport yang extend ConfigDecoratorMapper
/**
*
*/
package apr.external;
import java.util.Properties;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import org.apache.log4j.Logger;
import com.opensymphony.module.sitemesh.Config;
import com.opensymphony.module.sitemesh.Decorator;
import com.opensymphony.module.sitemesh.DecoratorMapper;
import com.opensymphony.module.sitemesh.Page;
import com.opensymphony.module.sitemesh.mapper.ConfigDecoratorMapper;
import com.opensymphony.module.sitemesh.mapper.ConfigLoader;
/**
* 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;
}
}
modify sitmesh.xml untuk override Decorator Mapper yang digunakan.
<mapper class="apr.external.ConfigDecoratorMapperSpringMvcSupport">
<param name="config" value="${decorators-file}" />
</mapper>
hasilnya pattern yang disebut tadi telah berjaya dikenali. :)