zoukankan      html  css  js  c++  java
  • Tapestry5.3使用总结

    1.Tapestry框架的加载是通过Filter来完成的,需要在web.xml中加入以下配置:

    <filter>
    	<filter-name>app</filter-name>
    	<filter-class>org.apache.tapestry5.TapestryFilter</filter-class>
    </filter>
    <filter-mapping>
    	<filter-name>app</filter-name>
    	<url-pattern>/*</url-pattern>
    </filter-mapping>

    2.这里面,过滤器拦截了所有的URL,某些时候可能希望有一些URL不被拦截(比如Servlet的mapping-url)
    这时候需要通过构建IgnoredPathsFilter服务,把不需要拦截的url添加到配置中去
    在Module类中,添加以下方法:

    public static void contributeIgnoredPathsFilter(Configuration<String> configuration){
        configuration.add("/topic");//添加后/topic路径不被Tapestry过滤器拦截
    }

    除了上述方式,还可以为应用程序单独指定一个context

    public void contributeApplicationDefaults(MappedConfiguration<String, String> configuration){
    	configuration.add(SymbolConstants.APPLICATION_FOLDER, "myApp");
    }

    同时修改filter的url

    <filter-mapping>
    	<filter-name>app</filter-name>
    	<url-pattern>/myApp/*</url-pattern>
    </filter-mapping>
    

    这样,便不会影响其他Filter和Servlet的使用

    3.Tapestry遵循"约定大于配置"的开发原则,以contribute为前缀的方法会自动被框架识别(比如上面的contributeIgnoredPathsFilter方法),除此之外还有其他一些约定:
    以decorate开头的方法 使用装饰器模式对现有Service进行包装,并且加入新的功能

    4.Tapestry和JQuery在功能上存在兼容性的问题,如果想要两个框架协作运行,需要引入tapestry5-jquery组件,
    组件在Tapestry上做了一些JQuery的功能扩展,具体可参考:http://tapestry5-jquery.com/
    maven依赖如下:

    <dependency>
    	<groupId>org.got5</groupId>
    	<artifactId>tapestry5-jquery</artifactId>
    	<version>3.3.1</version>
    </dependency>
    <repository>
    	<id>devlab722-repo</id>
    	<url>http://nexus.devlab722.net/nexus/content/repositories/releases</url>
    	<snapshots>
    		<enabled>false</enabled>
    	</snapshots>
    </repository>
    <repository>
    	<id>devlab722-snapshot-repo</id>
    	<url>http://nexus.devlab722.net/nexus/content/repositories/snapshots</url>
    	<releases>
    		<enabled>false</enabled>
    	</releases>
    </repository>

    引入该框架后,jquery语句便可以被解析,因此无需在手动引入JQuery框架

    5.Tapestry框架提供了面向组件的编程方法,其内部封装了很多组件,参考: http://tapestry.apache.org/component-reference.html
    Tree组件的使用
    视图:

    <t:tree t:model="model" t:node="treeNode" t:value="topic">
    	<p:label>
    		<t:if test="treeNode.leaf">
    			<a id="${topic.href}" style="cursor:pointer">${treeNode.label}</a>
    		</t:if>
    		<t:if test="!treeNode.leaf">
    			${treeNode.label}
    		</t:if>
    	</p:label>
    </t:tree>
    

    控制器:

    @Property
    private TreeNode<Topic> treeNode;
    @Property
    private Topic topic;
    public TreeModel<Topic> getModel(){
        return new TopicTreeModel();
    }
    


    6.除了内置的组件之外,Tapestry还有一个比较特殊的组件:Layout布局组件,该组件是由开发人员来编写的
    组件功能:声明界面的布局框架,供其他界面继承使用
    组件使用场景:界面之间存在共同的元素(菜单导航、版权信息等),将这些共同的元素提取出来作为模版使用,功能类似于JSP的include标签
    视图:

    <html xmlns="http://www.w3.org/1999/xhtml"
          xmlns:t="http://tapestry.apache.org/schema/tapestry_5_3.xsd"
          xmlns:p="tapestry:parameter">
        <head>
            <meta http-equiv="content-type" content="text/html; charset=utf-8"/>
            <title>${title}</title>
        </head>
        <body>
    		<div>header<div>
            <t:body/><!--相当于java中的抽象方法,需要子界面去实现-->
    		<div>footer<div>
        </body>
    </html>
    

    控制器:

    public class Layout{
        @Property
        @Parameter(required = true, defaultPrefix = BindingConstants.LITERAL)
        private String title;
    }
    


    7.组件的控制器类中经常会看到以@Parameter标注的属性用来描述组件参数
    如同功能函数需要方法参数一样,组件也需要参数来决定其行为
    如上面的Layout组件,其对外声明了一个'title'参数,使用该组件时可通过t前缀来指定title的值

    <html t:type="layout" t:title="index page" 
    		xmlns:t="http://tapestry.apache.org/schema/tapestry_5_3.xsd"
            xmlns:j="tapestry-library:jquery">
        <div>content<div>
    </html>
    

    同时也看到,由于使用了Layout组件,界面无需在处理header和footer信息,只需覆盖<t:body/>标签中内容便可

    组件在使用时,组件参数和类属性是双向绑定的,修改一方会级联影响到另一方,比如这里如果修改title属性值界面会发生变化,反之亦然

    @Parameter标签对外提供了一些属性,作用分别如下:
    required:参数是否必须指定
    autoconnect:将属性值和Component的Id值绑定,如果类型一致
    value:指定默认值(可绑定属性表达式)
    cache:是否缓存参数值
    defaultPrefix:默认绑定约束

    8.在界面指定组件参数值时,只能是String形式的表达式,而组件属性可能是其他类型,因此需要进行语义转换
    Tapestry提供了几种内置的转换方法,通过前缀的方式触发
    asset:查找资源文件转换成Asset对象
    context:查找webapp根目录下资源(<img src="${context:images/icon.png}"/>)
    literal:绑定字符串文本
    message:加载properties文件中对应的key值
    prop:绑定属性表达式( http://tapestry.apache.org/property-expressions.html)
    var:绑定界面临时变量(<li t:type="loop" source="1..10" value="var:index">${var:index}</li>)


    9.在使用Layout组件时,或许会有个疑问。由于界面继承了Layout模版,因此只需要重写<t:body/>标签便可,但是如何才能引入额外的脚本和样式呢?
    平时写界面,脚本都是在<head>里引入的,而通过Tapestry开发界面,脚本和样式的引入可在控制器类中进行声明

    @Import(stylesheet="context:styles/layout-default-latest.css", //引入CSS样式
    	library={"context:javascripts/vendor/jquery.layout-latest.js","Layout.js"}) //引入js脚本,如不指定context前缀则表示相对路径
    public class IndexPage{
    	......
    }
    


    10.Tapestry在界面端遵循的是面向组件的开发方法,通常将不同的组件按模块进行划分,打包放入到不同的jar中
    主程序如何才能识别这些jar,并调用其封装的组件?主要是通过manifest.mf配置文件来完成的。
    文件中封装了这样一条元数据:Tapestry-Module-Classes: com.yourcompany.services.yourModule
    Module类是每个模块的入口,主程序通过它来完成模块的加载,为了将Module中的组件暴露出去供其他Module使用,需要在Module类中声明如下方法:

    public static void contributeComponentClassResolver(Configuration<LibraryMapping> configuration){
    	configuration.add(new LibraryMapping("moduleName", "com.yourcompany"));
    }

    自此,模块中的组件便可被其他Module使用,通过如下声明:

    <html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_1_0.xsd"
      xmlns:m="tapestry-library:moduleName">
      ...
      <m:yourComp/>
      ...
    </html>

    详细参考: http://tapestry.apache.org/component-libraries.html

  • 相关阅读:
    H5调用本地摄像头[转]
    [转]把树莓派配置成无线路由器
    [转]Raspberry Pi做成路由器
    websocket for python
    HRMS(人力资源管理系统)-SaaS架构设计-概要设计实践
    HRMS(人力资源管理系统)-从单机应用到SaaS应用-架构分析(功能性、非功能性、关键约束)-下篇
    HRMS(人力资源管理系统)-从单机应用到SaaS应用-架构分析(功能性、非功能性、关键约束)-上篇
    系统架构-设计模式(适配器、观察者、代理、抽象工厂等)及架构模式(C/S、B/S、分布式、SOA、SaaS)(干货)
    HRMS(人力资源管理系统)-从单机应用到SaaS应用-系统介绍
    2018,全新出发(全力推动实现住有所居)
  • 原文地址:https://www.cnblogs.com/jiangu66/p/3196498.html
Copyright © 2011-2022 走看看