放到session中进行,
session.setAttribute()和session.getAttribute()

解决方案 »

  1.   

    只需要你声明一下getCity()就足够了,并不要求你声明一个属性吧
      

  2.   

    用session就可以,session.setAttribute()和session.getAttribute()来设置就可以
      

  3.   

    楼上的兄弟,请你先想想,这是Tapestry,是Html,不是JSP,你明白吗,那样不行吧!
      

  4.   

    页面的传值显得有点乱,用SESSION会有安全性或者系统资源的问题,但是我觉得还是直接传好一些。
      

  5.   

    急人,CSDN中居然没人会Tapestry吗?
      

  6.   

    兄弟,给你一篇文章看看吧,我觉得还可以!这也是俺最近学习找的,大家一起学习!Tapestry是一个开源的基于servlet的应用程序框架,它使用组件对象模型来创建动态的,交互的web应用。一个组件就是任意一个带有jwcid属性的html标记。其中jwc的意思是Java Web Component。Tapestry使得java代码与html完全分离,利用这个框架开发大型应用变得轻而易举。并且开发的应用很容易维护和升级。Tapestry支持本地化,其错误报告也很详细。Tapestry主要利用javabean和xml技术进行开发。 
      

  7.   

    第一个应用程序 在介绍第一个应用之前,先介绍一下Tapestry的安装。从sourceforge下载其最新版,解压后,将lib目录下的jar文件放到CLASSPATH中,将其中的war文件放到tomcat的webapp目录下。然后就可以通过http://localhost:8080/tutorial访问其tutorial应用。在Tapestry中一个应用程序有以下几部分组成,我们以其自身带的HelloWorld程序为例介绍: Servlet: 
    这是一个应用的主体部分:servlet类,这个类必须是ApplicationServlet的子类,并且必须实现getApplicationSpecificationPath()方法。示例如下: import com.primix.tapestry.*; 
    public class HelloWorldServlet extends ApplicationServlet 

         protected String getApplicationSpecificationPath() 
         { 
               return "/tutorial/hello/HelloWorld.application"; 
         } 
    } /tutorial/hello/HelloWorld.application是一个应用的说明文件。 
    Application Specification: 
         其实就是描述这个应用的一个xml文件,在这个应用中有许多参数需要设置,engine-class将在下面介绍,page中的name属性指定html文件名,specification-path指定对这个页面的说明文件。在一个应用中可以有很多个page,但必须有一个page的name为"Home",因为当访问你的应用时,首先显示的就是这个page。 <?xml version="1.0" encoding="UTF-8"?> 
    <!DOCTYPE application PUBLIC "-//Howard Ship//Tapestry Specification 1.1//EN" "http://tapestry.sf.net/dtd/Tapestry_1_1.dtd"> 
    <application name="Hello World Tutorial" engine-class="com.primix.tapestry.engine.SimpleEngine"> 
    <page name="Home" specification-path="/tutorial/hello/Home.jwc"/> 
    </application> Application Engine:      当客户连接到Tapestry应用时,Tapestry将会创建一个Engine对象(类似于session)。通常我们程序中的application engine 一般是SimpleEngine类的一个实例,当然这个类的子类也可以。 Page Specification:   
        跟应用说明相似,页说明也是一个xml描述文件: <?xml version="1.0" encoding="UTF-8"?> 
    <!DOCTYPE specification PUBLIC "-//Howard Ship//Tapestry Specification 1.1//EN" "http://tapestry.sf.net/dtd/Tapestry_1_1.dtd"> 
    <specification class="com.primix.tapestry.BasePage"/>      因为这个应用是静态的,所以使用com.primix.tapestry.BasePage即可,如果是动态的应用,则需在这个文件中定义一些component,当然使用BasePage为基类的派生类也可以。 html页面:   
         这个应用的html页面非常简单: <html> 
    <head> 
    <title>Hello World</title> 
    </head> 
    <body> 
    <b>HelloWorld</b> 
    </body> 
    </html> 
        注意:上面所讲到的各种文件都要放到放在WAR的WEB-INF/classes目录下。 一个复杂的应用   在这个应用中我们以一个简单的学生管理系统为例介绍一下Tapestry的常用功能。我们要实现学生的增加和显示,因此我们需要两个html页面。至于StudentServlet类和Student.application我们就不描述了,在Student.application中定义了两个page:Home和EditStudent,具体看附件。学生数据存放在数据库中,我们用Student类表示数据中的一条记录,用StudentFactory类检索学生数据,这两个类用到了一个JDBC包装器,关于这个JDBC包装器可以见我的另外一篇文章<<对一个简单的 JDBC 包装器的扩展及应用>>。 
    首先看一下Home.html 
    <html> 
    <head> 
    <title>学生管理</title> 
    <meta http-equiv="Content-Type" content="text/html; charset=gb2312"> 
    </head> 
    <body bgcolor="#FFFFFF"> 
    <p align="center">学生列表</p> 
    <table width="100%" border="1"> 
    <tr> 
    <td >学号</td> 
    <td >姓名</td> 
    <td >性别</td> 
    <td >班级</td> 
    </tr> 
    <span jwcid="liststudent"> 
    <tr> 
    <td><span jwcid="id">20012400</span></td> 
    <td><span jwcid="sname">宗锋</span></td> 
    <td><span jwcid="gender">男</span></td> 
    <td><span jwcid="department">计算机研一</span></td> 
    </tr> 
    </span> 
    <tr jwcid="$remove$"> 
    <td>20011389</td> 
    <td>桑一珊</td> 
    <td>男</td> 
    <td>计算机研一</td> 
    </tr> 
    </table> 
    <a jwcid="add">添加学生</a> 
    </body> 
    </html> 与前面的简单应用不同,我们在这个页面中定义了七个组件,下面看一下部分Home.jwc文件,我们将详细讲述一下怎样描述这些组件。 
    <specification class="test.ListStudent"> 
    <component id="liststudent" type="Foreach"> 
    <binding name="source" property-path="student"/> 
    <binding name="value" property-path="eachstudent"/> 
    </component> 
    <component id="id" type="Insert"> 
    <binding name="value" property-path="eachstudent.id"/> 
    </component> 
    <component id="add" type="Page"> 
    <static-binding name="page">EditStudent</static-binding> 
    </component> 
    </specification> 在这里,我们的specification的class属性值不再是BasePage,而是其派生类ListStudent。对于每一个组件,id属性指定唯一的标识符,这个值与html文件中的jwcid值相对应,type 指定组件名,binding指定组件怎得到数据,property-path是一系列属性的集合,这些属性一般定义在javabean中,例如上面的property-path="student",则在相应的javabean类ListStudent中应该有个函数getStudent。liststudent是一个Foreach组件,这个组件其实是一个for循环,它从source中读入一个数组,将其一个一个的赋值给value参数指定的属性。id,name,gender,department四个是Insert组件,这个组件用来插入文本数据,参数value指定要插入的值,property-path指定怎样获取这些值,eachstudent.id相当于调用javabean的getEachstudent().getId()。add是一个Page组件,page属性指定页面名(定义在application文件中),static-binding表明要绑定的数据是不可修改的。$remove$组件没有在这个文件中描述,因为Tapestry运行时会自动删除这种组件。 
    下面看一下ListStudent类: package test; 
    import com.primix.tapestry.*; 
    import sun.jdbc.odbc.JdbcOdbcDriver ; 
    /** 
    * 返回每个学生的数据 

    */ public class ListStudent extends BasePage 

    private Student eachstudent; 
    private Student[] student; 
    public void detach() 

    eachstudent=null; 
    student=null; 
    super.detach(); 
    } public Student getEachstudent() 

    return eachstudent; 

    public void setEachstudent(Student value) 

    eachstudent = value; 

    public Student[] getStudent() 

    try{ 
    Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); 
    student=StudentFactory.findAllStudents(); 
    }catch(Exception e){ 
    e.printStackTrace(); 

    return student; } } 
      

  8.   

    这个类有四个函数,其中detach函数是将页面放入缓冲池时执行的操作,getStudent函数返回所有的学生记录,这是给jwc文件中liststudent组件的source参数赋值,getEachstudent给这个组件的value参数赋值,因为source是一个数组,每次循环需要从中取出一条记录赋值给eachstudent,所以还有一个函数为setEachstudent,你会注意到这个函数很简单,其实是Tapestry帮你做了大部分工作。 
    至此,显示学生的部分已经完成,下面看一下EditStudent.html <html> 
    <head> 
    <title>增加学生</title> 
    <meta http-equiv="Content-Type" content="text/html; charset=gb2312"> 
    </head> 
    <body> 
    <p><img src="student.gif" width="32" height="32"/> 学生管理系统</p> 
    <form jwcid="form"> 
    <span jwcid="ifError"> 
    <font size=+2 color=red><span jwcid="insertError"/></font> 
    </span> 
    <p>学号: 
    <input jwcid="id"/> 
    </p> 
    <p>姓名: 
    <input jwcid="name"/> 
    </p> 
    <span jwcid="gender"> 
    <p>性别: 
    <input jwcid="male"/> 
    男 
    <input jwcid="female"/> 
    女 
    </p> 
    </span> 
    <p>班级: 
    <input jwcid="department"/> 
    </p> 
    <p> 
    <input type="submit" value="确定"> 
    </p> 
    </form> 
    </body> 
    </html> 
    在这个文件中,用到了另外一些常用的组件,先看一下EditStudent.jwc中的这些组件的描述: 
    <specification class="test.EditStudent"> 
    <component id="form" type="Form"> 
    <binding name="listener" property-path="listeners.formSubmit"/> 
    </component> 
    <component id="gender" type="RadioGroup"> 
    <binding name="selected" property-path="gender"/> 
    </component> 
    <component id="ifError" type="Conditional"> 
    <binding name="condition" property-path="error"/> 
    </component> 
    <component id="insertError" type="Insert"> 
    <binding name="value" property-path="error"/> 
    </component> 
    <component id="id" type="TextField"> 
    <binding name="value" property-path="id"/> 
    </component> 
    <component id="male" type="Radio"> 
    <field-binding name="value" field-name="test.EditStudent.MALE"/> 
    </component> 
    </specification> 
    form是一个Form组件,它的参数listener指定submit这个form时有那个函数处理。ifError是一个Conditional组件,这个组件指定当condition满足时才会显示,在本例中,如果error不为空,则condition满足。在这个组件中,有嵌套了一个Insert类型的组件,用于将错误显示。这是Tapestry中经常用到的处理错误的方式。gender是一个RadioGroup组件,它绑定了javabean中的gender属性,selected参数指定那个radio被选中,在这个组件中,又嵌套了两个Radio组件,分别用来表示男,女。Radio的value参数指定当用户选定这个radio时,RadioGroup绑定的属性值将会等于field-name中指定的值(这个值必须是static的),在本例中,gender=test.EditStudent.MALE。id是一个TextField组件,其参数value绑定到javabean中的id属性。 
    下面是相应的EditStudent类: package test; 
    import com.primix.tapestry.*; public class EditStudent extends BasePage 

    public static final int MALE = 1; 
    public static final int FEMALE = 2; private int gender; 
    private String error; 
    private String id; 
    private String sname; 
    private String department; public void detach() 

    error = null; 
    id=null; 
    sname=null; 
    gender=0; 
    department=null; 
    super.detach(); 
    } public int getGender() 

    return gender; 

    public String getId() 

    return id; 

    public String getSname() 

    return sname; 

    public String getDepartment() 

    return department; 

    public void setGender(int value) 

    gender = value; 
    fireObservedChange("gender", value); 

    public void setId(String value) 

    id = value; 
    fireObservedChange("id", value); 

    public String getError() 

    return error; 

    public void setSname(String value) 

    sname = value; 
    fireObservedChange("sname", value); 

    public void setDepartment(String value) 

    department = value; 
    fireObservedChange("department", value); 

    public void formSubmit(IRequestCycle cycle) 

    //判断用户是否添完了所有数据 
    if (gender== 0||id==null||id.equals("")||sname==null||sname.equals("")|| 
    department==null||department.equals("")) 

    error = "请填充完所有选项"; 
    return; 

    //将学生保存 
    try{ 
    Student student=new Student(); 
    student.setId(id); 
    student.setName(sname); 
    if(gender==1) 
    student.setGender("男"); 
    else 
    student.setGender("女"); 
    student.setDepartment(department); 
    student.save(null); 
    }catch(Exception e){ 
    e.printStackTrace(); 

    //清空当前的各个属性,以免再次进入此页面时,各属性仍旧保留原来的值 
    setSname(null); 
    setDepartment(null); 
    setId(null); 
    setGender(0); 
    //重定向到Home页面 
    cycle.setPage("Home"); 
    } } 在本类的一些设置属性的函数中使用了fireObservedChange这个函数,这个函数激发一个改变事件,通知当前的属性的值已经改变。 其他应用 
         Tapestry中自带的例子中的Workbench中的localization例子演示了怎样使用本地化,你只需要创建不同语言的html模板,还有图形等其它一些html中用到的资源。例如创建一个法语版的EditStudent.html,则相应的html文件名为EditStudent_fr.html,而jwc中定义的组件的描述不用有多个版本。这里要介绍一下Tapestry本地化中经常用到的一个概念:assets。assets是一些web应用中用到的资源,如图象,视频。assets有三种:external, internal 和private。External类型的assets来源于任意的URL。Internal类型的assets来源于和Tapestry应用在同一个服务器上的URL。Private 类型的assets允许部署在WAR的WEB-INF/classes目录下(同上面的html模板,jwc文件一样),这个目录对于web服务器来说是不可见的。 
        看一下Workbench中localization例子中的localization.jwc文件的片断: <component id="changeButton" type="ImageSubmit"> 
    <binding name="image" property-path="assets.change-button"/> 
    </component> <private-asset name="change-button" resource-path="/tutorial/workbench/localization/Change.gif"/>      在changeButton组件中就使用了private assets,而这些图像文件就放在WAR的WEB-INF/classes下,注意图像跟html一样也有多个语言的版本。 
         注意:jwc文件中的inputLocale这个组件,其实localization应用就是通过这个组件来实现本地化。具体参数请看其Developer guide。 <component id="inputLocale" type="PropertySelection"> 
    <binding name="value" property-path="page.engine.locale"/> 
    <binding name="model" property-path="localeModel"/> 
    </component>      Tapestry还支持创建自己的可重用组件,其自身带了一个这样的例子:Border。同时它还有其它一些例子:Inspector展示了怎样监视你的应用程序。vlib是一个用tapestry作表示层的j2ee应用程序(用jboss作为应用服务器)。      Tapestry的功能非常强大,本文只是介绍了其一小部分,还有很多方面没有涉及到,例如javascript在Tapestry中的应用。具体可以看其文档,相信如果你用一下这个框架,你就会被它深深吸引。Tapestry的文档做的不是很全,不过经过不断的摸索,相信你会很快掌握它。
      

  9.   

    anyteam() ,刚看完这个例子,还是没有解决我的要求,我要解决的是不同的页面之间传值的问题,比如说用属性,用session,应该怎么做呢?
    不过还是很感谢你的!
      

  10.   

    每个Tapestry 有一个重要的对象是visit,它用于在page之间传递appcation内部专用的数据和逻辑.
    在engine和visit的封装之下,我们可以完全不管request.response和session!
      

  11.   

    你需要使用OO的思维解决这个问题。在调用.activate之前,需要对已定义在目标Page中的某参数赋值,而不是基于session.比如,Xx xx = (Xx)cycle.getPage("Xx");
    xx.setSize(12);
    cycle.activate(xx);
      

  12.   

    你给我发个邮件:[email protected],我给你一个教程,应该可以解决你的问题!