webwork2入门(二.1)

这一节,我们要掌握的东西

webwork操作session

webwork的验证

webwork两种驱动方式:

  • Property-Driven
  • Model-Driven

前面我们已经学会了webwork的第一个例子,我们发现webwork中的Action是完全和Sevlet解耦合的,在web开发中,我们很多时候都要对Session,Application,Parameter进行操作,那么在webwork中我们该怎么做呢?

我们可以通过两种方式对它们进行操作,一种是通过com.opensymphony.xwork.ActionContext进行操作,另外一种是通过实现com.opensymphony.webwork.interceptor.SessionAware接口,这一节我们只关注第一种方式

参考webwork的API,ActionContext是一个执行中的Action的上下文(Context),里面存放了Action,Session,Application,Parameter等信息,通过ActionContext我们就可以很方便的实现上述我们想要的功能啦!那么你可能会问ActionContext又是如何得到这些信息的呢?还记得上个教程中配置文件web.xml里的过滤器(filter)吗? 当一个浏览器产生一个请求到达webwork的时候,首先是被过滤器获得,过滤器通过询问com.opensymphony.webwork.dispatcher.mapper.ActionMapper接口,是否要响应这次请求(实际上就是看我们的配置文件里面是不是有这个action 名字),如果是,过滤器就负责把Session,Parameter,ServletContext等信息转化成一个map对象

然后在通过com.opensymphony.xwork.ActionProxyFactory 的createActionProxy(String namespace,String actionName, Map extraContext,boolean executeResult,boolean cleanupContext)创建ActinoProxy,注意它的参数,第一个是Action的名字空间,第一个是Action的名字,第三个map这里面就是包含的就是上面的信息了.通过ActionProxy,就已经解耦合了面向Servlet的webwork和xwork拉!

在ActionProxy通过一系列的方法之后会创建com.opensymphony.xwork.ActionInvocation接口,这个接口表示的是一次Action执行的状态,ActionContext实际上就是在这个接口的实现类DefaultActionInvocation被初始化的, 查看API,可以看到ActionInvocation有一个getInvocationContext()的方法,所以ActionContext就是这样来的

理论说了这么多,还是来点实际的吧:

类:

Domain Object: User

Action :SimpleAction

页面:

index.jsp

success.jsp

先看index.jsp

  1. <%@taglib prefix="ww" uri="/webwork" %>  
  2. <html>  
  3. <body>  
  4. <form action="simple.action">  
  5. <input type="text" name="user.username"><br>  
  6. <input type="password" name="user.password"><br>  
  7. <input type="submit" value="submit">  
  8. </form>  
  9. </body>  
  10. </html>  

和第一个教程是一样的,我就不再重复

User:

java 代码
  1. package mypackage;   
  2.   
  3. import java.util.ArrayList;   
  4. import java.util.List;   
  5.   
  6. public class User {   
  7.     String username;   
  8.   
  9.     String password;   
  10.   
  11.     List message = new ArrayList();   
  12.   
  13.     public List getMessage() {   
  14.         return message;   
  15.     }   
  16.   
  17.     public void setMessage(List message) {   
  18.         this.message = message;   
  19.     }   
  20.   
  21.     public String getPassword() {   
  22.         return password;   
  23.     }   
  24.   
  25.     public void setPassword(String password) {   
  26.         this.password = password;   
  27.     }   
  28.   
  29.     public String getUsername() {   
  30.         return username;   
  31.     }   
  32.   
  33.     public void setUsername(String username) {   
  34.         this.username = username;   
  35.     }   
  36.   
  37. }   

SimpleAction:

java 代码
  1. package mypackage;   
  2.   
  3. import java.util.Map;   
  4. import com.opensymphony.xwork.Action;   
  5. import com.opensymphony.xwork.ActionContext;   
  6.   
  7. public class SimpleAction implements Action {   
  8.   
  9.     private User user = new User();   
  10.        
  11.     public String execute() throws Exception {   
  12.         System.out.println(Thread.currentThread().getName());   
  13.         ActionContext context = ActionContext.getContext();   
  14.         Map session = context.getSession();   
  15.         session.put("user", user);   
  16.         user.getMessage().add("msg1");   
  17.         user.getMessage().add("msg2");   
  18.         user.getMessage().add("msg3");   
  19.         return SUCCESS;   
  20.     }   
  21.   
  22.     public User getUser() {   
  23.         return user;   
  24.     }   
  25.   
  26.     public void setUser(User user) {   
  27.         this.user = user;   
  28.     }   
  29.        
  30.   
  31. }   

其实代码比较简单

ActionContext通过静态方法返回自身的实例,然后可以看到context有很多方法,包括getApplication(),getSession(),getParameter(),它们返回的都是map.然后分别对这个map进行操作就可以拉

你可能会觉的奇怪,ActionContext通过一个简单的map如何区分两个不同的会话(Session)呢?

答案在于ActionContext是一个线程本地变量(thread local),webwork对于每一个不同的线程,都会把ActionContext放在他们的ThreadLocal中,而我们底层(Tomcat服务器,也是Servlet规范)对于每一个浏览器请求都会产生一个唯一的线程,这样一个线程对应一个浏览器会话,同时也对应了一个ActionContext.

我们可以给一个简单的Servlet 例子来帮助理解:

java 代码
  1. package mypackage;   
  2.   
  3. import java.io.IOException;   
  4. import java.io.PrintWriter;   
  5.   
  6. import javax.servlet.http.HttpServlet;   
  7. import javax.servlet.http.HttpServletRequest;   
  8. import javax.servlet.http.HttpServletResponse;   
  9.   
  10. public class ThreadLocalServlet extends HttpServlet {   
  11.     public void service(HttpServletRequest request,HttpServletResponse response) throws IOException{   
  12.         response.setContentType("text/html");   
  13.         PrintWriter out = response.getWriter();   
  14.         out.println(Thread.currentThread().getName()); //得到当前线程的名字   
  15.     }   
  16. }   

以下三个不同的浏览器窗口访问这个Servlet的一种结果:

http-8080-Processor24

http-8080-Processor25

http-8080-Processor26

webwork会通过三个不同的线程(同时对应了三个不同的浏览器窗口)产生三个不同的ActionContext实例 ,这样就起到了回话的作用了

好了,这个问题搞清楚之后,继续前面的的Action,

来看Action的配置文件xwork.xml

xml 代码
  1. <!---->>  
  2. <xwork>  
  3.     <include file="webwork-default.xml" />  
  4.     <package name="default" extends="webwork-default">  
  5.         <action name="simple" class="mypackage.SimpleAction">  
  6.             <result name="success" type="redirect">success.jspresult>  
  7.             <interceptor-ref name="params" />  
  8.         action>  
  9.     package>  
  10. xwork>  

 

这个配置文件和上篇文件的配置文件是一样的

1.把默认webwork-default.xml包含在我们的配置文件里,webwork-default.xml放在webwork.jar文件中,里面定义了拦截器(inteceptor),和返回(result),这里是一个代码片段

  1. <!---->>  
  2. <xwork>  
  3. <package name="webwork-default">  
  4. <result-types>  
  5.  ......   
  6.  <result-type name="dispatcher" class="com.opensymphony.webwork.dispatcher.ServletDispatcherResult" default="true"/>  
  7.  <result-type name="redirect" class="com.opensymphony.webwork.dispatcher.ServletRedirectResult"/>  
  8.  result-types>    
  9. <interceptors>  
  10. ......   
  11. <interceptor name="params" class="com.opensymphony.xwork.interceptor.ParametersInterceptor"/>  
  12. ......             
  13. interceptors>  
  14. <package name="webwork-default">    
  15. xwork>  
  16.       

2.定义一个package,相当于java里面的的package关键字,起到一个命名空间的作用

3.在pakcage里面定义action,一个package里面可以定义多个action,这里主义的是name 要和 index.jsp 表单中action的名字相同。

4.在action中定义result,默认的返回方式(type)是dispater,我们把它改为重定向redirect

5.定义我们引用的 拦截器params

最后来看我们的success.jsp

xml 代码
  1. <%@taglib prefix="ww" uri="/webwork"%>  
  2. <html>  
  3. <body>  
  4.   
  5. <ww:property value="#session.user.username"/>  
  6. <ww:property value="#session['user'].password"/>  
  7. <ww:iterator value="#session.user.message">  
  8. <div style="color: red"><ww:property/>div>  
  9. ww:iterator>  
  10.   
  11. body>  
  12. html>  
  13.   
  14.   

1.声明了我们要使用的webwork标签库

2.通过

  1. <ww:property value=""/>  

的形式,得到我们想要获取的值,

访问session可以通过两种方式

  1. #session.user.username   
  2. #session['user'].password  

我个人觉得第一种更简单一些。注意这样访问

  1. #session['user.password']  

是得不到正确值的.

3.以下代码

  1. <ww:iterator value="#session.user.message">  
  2. <div style="color: red"><ww:property/></div>  
  3. </ww:iterator>  

声明了一个迭代器标签它,它可以方便的取出一个容器里面的值,

 

ok,通过webwrok操作session就此结束,希望这篇文章能对您有所帮助,

还有很多的朋友在讲解webwork2,他们的教程比我写的更好

http://webwork.javascud.org/

你可能感兴趣的:(多线程,jsp,struts,JSF,Webwork)