Tapestry 5提供了一个非常方便的特性,通过使用@Secure 注释,可以让你的页面能够被安全的浏览,也就是说,从其他没有@Secure注释的页面切换到有@Secure的页面(从浏览器角度说,从http切换到 https),几乎不费任何力气。废话少说,看一下用户登入的例子:
| 开发环境 | Windows sp3, firefox 3.6,myeclipse 8.0 (使用eclipse3.4以上也行), JDK 1.6 |
| 所需类库 | tapestry 5.1.0.5 |
| web服务器 | jetty-6.1.3 |
此例子使用了maven管理depencies, 因此pom.xml应该看起来像这样:
pom.xml dependency代码片段
…… <dependency> <groupId>org.apache.tapestry</groupId> <artifactId>tapestry-ioc</artifactId> <version>5.1.0.5</version> <type>jar</type> <scope>compile</scope> </dependency> <dependency> <groupId>org.apache.tapestry</groupId> <artifactId>tapestry-core</artifactId> <version>5.1.0.5</version> <type>jar</type> <scope>compile</scope> </dependency> ……
实际上此例子只用到了tapestry-core 而已,IOC用于服务注入,有时候配置module的时候需要到tapestry-ioc包,建议两个都导入。
下一步骤,修改WEB-INF下的web.xml,使用tapestry接管http请求:
web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> <context-param> <param-name>tapestry.app-package</param-name> <param-value>tapestry5.https</param-value> </context-param> <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> </web-app>
紧接着创建两个包:
- tapestry5.https.pages:用来创建页面类
- tapestry5.https.services:配置module或者application等
在包tapestry5.https.pages下创建4个页面,一个是Start.java, Login.java,Welcome.java 和 Error.java, 其中Login.java 必须使用Https连接(使用了@Secure注释),其余的可以通过普通http方式访问;在包tapestry5.https.services下创建AppModule.java用来配置整个应用程序。
tapestry5.https.pages包下的文件:
- Start.java 初始页面,使用非安全连接页面
- Login.java 用户登入界面,必须使用https连接
- Welcome.java 登入成功页面
- Error.java 登入失败页面
紧接着在Webroot(web应用程序根目录)下对应tapestry5.https.pages包中的页面,分别创建start.tml,login.tml, welcome.tml和error.tml文件(名称大小写不敏感,但要和tapestry5.https.pages中的java页面文件同名)。看以下截图:
Start.java,Welcome.java以及Error.java是空类,不包含任何逻辑(用于展示目的),只需编辑对应的start.tml, error.tml以及welcome.tml文件即可:
start.tml
<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_1_0.xsd" > <head> <title> this is a normal page accessed by HTTP</title></head> <body> <p> this is a normal page accessed by HTTP</p> </body> </html>
error.tml
<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_1_0.xsd"> <head> <title> this page should be accessed automatically by HTTPS</title> </head> <body> <p>User name or password error!</p> </body> </html>
最后是Login.tml,最重要的一个page:welcome.tml
<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_1_0.xsd" > <head> <title> this is a normal page accessed by HTTP</title></head> <body> <p> welcome!</p> </body> </html>
login.tml
<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_1_0.xsd"> <head> <title> this page should be accessed automatically by HTTPS</title> </head> <body> <t:form t:id="loginForm"> <t:label t:for="name" /> <t:textfield t:id="name" value="name" /> <t:label t:for="pwd" /> <t:passwordfield t:id="pwd" value="pwd" /> <input type="submit" value="go" /> </t:form> <t:actionlink t:id="gotostart">return to start</t:actionlink> </body> </html>
Login.java主要有两个操作,一个是用户登入,登入成功返回welcome页面,否则返回error页面; 另外一个是点击链接“return to start”返回start页面,由此编辑Login.java如下:
Login.java
package tapestry5.https.pages; import org.apache.tapestry5.annotations.InjectPage; import org.apache.tapestry5.annotations.Property; import org.apache.tapestry5.annotations.Secure; // here used @Secure annotation, //therefore this page will be forced to be visited under https @Secure public class Login { @Property @Property @InjectPage private Start start; @InjectPage private Welcome welcome; @InjectPage if (name.equals("admin") && pwd.equals("123456")) { return welcome; } return error; } return start; } }
所有页面编辑完毕,在部署此project到jetty之前,还需要配置整个应用程序,修改tapestry5.https.services下的AppModule.java文件如下:
最后一步是部署我们的Web程序。为了测试的方便,修改了jetty.xml和jetty-ssl.xml中的端口,即修改端口8080为80, 修改安全端口8443为443,这样测试的的url就从http://localhost:8080//…变成了http://localhost//… 注意端口号没有明确指定,jetty会自动映射的;同时不要忘记启动jetty服务器之前,要添加参数etc/jetty.xml etc/jetty-ssl.xml,否则的话默认只会加载etc/jetty.xml (在etc目录下,jetty自带一个keystore,你可以自己替换成自己的证书,详细请看http://docs.codehaus.org/display/JETTY/How+to+configure+SSL)AppModule.java
package tapestry5.https.services; import org.apache.tapestry5.SymbolConstants; import org.apache.tapestry5.ioc.MappedConfiguration; public class AppModule { public static void contributeApplicationDefaults( MappedConfiguration<String, String> configuration) { // you must enable production mode to access page with @secure annotation under HTTPS mode, // otherwise it won't work; if you want to switch back to development mode, just set it "false" configuration.add(SymbolConstants.PRODUCTION_MODE, "true"); // use utf-8 as default encoding configuration.add(SymbolConstants.CHARSET, "UTF-8"); } }
部署完项目启动jetty之后,打开浏览器firefox,键入http://localhost/LoginExample/start 会显示如下:
然后我们把url中的start改成login,回车:
Opps,由于jetty自带的是一个用于测试https的过期的keystore,因此可以不用理会firefox的安全警告,选择信任此网站即可。
显然自动进入安全Login页面成功!(当从http页面到此页面时,会自动转入https), 如上所示,此Login页面只能在https下访问,普通http会被自动转入https(本质上是一个http redirect)。
接下来,我们点击return to start返回普通http页面,来验证是否会一直在https模式下浏览普通页面呢?
点击链接,成功返回谱图http页面start!
总结: tapestry5的@Secure注释功能非常强大,隐藏了从http到https,以及https到http切换的繁琐的实现,提高了开发效率。