Wednesday 12 December 2012

Sitemesh: Pattern tidak dikenali Spring framework

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

No comments: