传智播客struts2学习笔记(二)

四.流程

 

4.1    Struts2的处理流程

 

用户请求——>strutspreparedandexecutefilter——>interceptor(struts2内置的一些拦截器或用户自定义拦截器)

 

——>action(用户编写的action类,类似struts1中的action)——>result(类似struts1中的forward)

 

——>jsp/html——>响应

 

 

StrutsPrepareAndExecuteFilterStruts 2框架的核心控制器,它负责拦截由<url-pattern>/*</url-pattern>指定的所有用户请求,当用户请求到达时,该Filter会过滤用户的请求。默认情况下,如果用户请求的路径不带后缀或者后缀以.action结尾,这时请求将被转入Struts 2框架处理,否则Struts 2框架将略过该请求的处理。当请求转入Struts 2框架处理时会先经过一系列的拦截器,然后再到ActionStruts1不同,Struts2对用户的每一次请求都会创建一个Action,所以Struts2中的Action是线程安全的。
 
 
4.2  为应用指定多个struts配置文件
 
 
在大部分应用里,随着应用规模的增加,系统中Action的数量也会大量增加,导致struts.xml配置文件变得非常臃肿。为了避免struts.xml文件过于庞大、臃肿,提高struts.xml文件的可读性,我们可以将一个struts.xml配置文件分解成多个配置文件,然后在struts.xml文件中包含其他配置文件。下面的struts.xml通过<include>元素指定多个配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
    "http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<include file="struts-user.xml"/>
<include file="struts-order.xml"/>
</struts>
通过这种方式,我们就可以将Struts 2Action按模块添加在多个配置文件中。
 
 
 
 
4.3   动态方法调用
 
 
如果Action中存在多个方法时,我们可以使用!+方法名调用指定方法。如下:
public class HelloWorldAction{
private String message;
....
public String execute() throws Exception{
this.message = " 我的第一个struts2应用";
return "success";
}
public String other() throws Exception{
this.message = " 第二个方法";
return "success";
}
}
假设访问上面actionURL路径为: /struts/test/helloworld.action
要访问actionother() 方法,我们可以这样调用:
/struts/test/helloworld!other.action
如果不想使用动态方法调用,我们可以通过常量struts.enable.DynamicMethodInvocation关闭动态方法调用。
<constant name="struts.enable.DynamicMethodInvocation" value="false"/>
 
4.4使用通配符定义action
 
<package name="itcast" namespace="/test" extends="struts-default">
<action name=" helloworld_*" class="cn.itcast.action.HelloWorldAction" method="{1}">
<result name="success">/WEB-INF/page/hello.jsp</result>
</action>
</package>
public class HelloWorldAction{
private String message;
....
public String execute() throws Exception{
this.message = " 我的第一个struts2应用";
return "success";
}
public String other() throws Exception{
this.message = " 第二个方法";
return "success";
}
}
要访问other()方法,可以通过这样的URL访问:/test/helloworld_other.action
 
 
 
 
 
4.5  接收请求参数
 
采用基本类型接收请求参数(get/post)
Action类中定义与请求参数同名的属性,struts2便能自动接收请求参数并赋予给同名属性。
请求路径: http://localhost:8080/test/view.action?id=78
public class ProductAction {
      private Integer id;
      public void setId(Integer id) {//struts2通过反射技术调用与请求参数同名的属性的setter方法来获取请求参数值
             this.id = id;
      }
      public Integer getId() {return id;}
  }
采用复合类型接收请求参数
请求路径: http://localhost:8080/test/view.action?product.id=78
 public class ProductAction {
   private Product product;
   public void setProduct(Product product) {  this.product = product;  }
   public Product getProduct() {return product;}
}
Struts2首先通过反射技术调用Product的默认构造器创建product对象,然后再通过反射技术调用product中与请求参数同名的属性的setter方法来获取请求参数值。
 
 
 
 
4.6   自定义类型转换器
 
 
java.util.Date类型的属性可以接收格式为2009-07-20的请求参数值。但如果我们需要接收格式为20091221的请求参数,我们必须定义类型转换器,否则struts2无法自动完成类型转换。
import java.util.Date;
public class HelloWorldAction {
private Date createtime;
public Date getCreatetime() {
return createtime;
}
public void setCreatetime(Date createtime) {
this.createtime = createtime;
}
}
 
 
 
public class DateConverter extends DefaultTypeConverter {
                @Override  public Object convertValue(Map context, Object value, Class toType) {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
try {
if(toType == Date.class){// 当字符串向Date类型转换时
String[] params = (String[]) value; // Request.getParameterValues()
return dateFormat.parse(params[0]);
}else if(toType == String.class){// Date转换成字符串时
Date date = (Date) value;
return dateFormat.format(date);
}
} catch (ParseException e) {}
return null;
}
}
将上面的类型转换器注册为局部类型转换器
Action类所在的包下放置ActionClassName-conversion.properties文件,ActionClassNameAction的类名,后面的-conversion.properties是固定写法,对于本例而言,文件的名称应为HelloWorldAction-conversion.properties 。在properties文件中的内容为:
属性名称=类型转换器的全类名
对于本例而言, HelloWorldAction-conversion.properties文件中的内容为:
createtime= cn.itcast.conversion.DateConverter
 
 
4.7  自定义全局类型转换器
 
将上面的类型转换器注册为全局类型转换器:
WEB-INF/classes下放置xwork-conversion.properties文件 。在properties文件中的内容为:
待转换的类型=类型转换器的全类名
对于本例而言, xwork-conversion.properties文件中的内容为:
java.util.Date= cn.itcast.conversion.DateConverter
 
 
4.8 访问或添加request/session/application属性
 
 
public String scope() throws Exception{
   ActionContext ctx = ActionContext.getContext();
   ctx.getApplication().put("app", "应用范围");//ServletContext里放入app
   ctx.getSession().put("ses", "session范围");//session里放入ses
   ctx.put("req", "request范围");//request里放入req
   return "scope";
}
JSP:
 <body>
    ${applicationScope.app} <br>
    ${sessionScope.ses}<br>
    ${requestScope.req}<br>
 </body>
 
 
4.9   获取HttpServletRequest / HttpSession / ServletContext / HttpServletResponse对象
 
 
方法一,通过ServletActionContext.类直接获取:
public String rsa() throws Exception{
HttpServletRequest request = ServletActionContext.getRequest();
ServletContext servletContext = ServletActionContext.getServletContext();
request.getSession()
HttpServletResponse response = ServletActionContext.getResponse();
return "scope";
}
方法二,实现指定接口,由struts框架运行时注入:
public class HelloWorldAction implements ServletRequestAware, ServletResponseAware, ServletContextAware{
private HttpServletRequest request;
private ServletContext servletContext;
private HttpServletResponse response;
public void setServletRequest(HttpServletRequest req) {
this.request=req;
}
public void setServletResponse(HttpServletResponse res) {
this.response=res;
}
public void setServletContext(ServletContext ser) {
this.servletContext=ser;
}
}
 
 
五.拦截器
 
5.1 自定义拦截器
 
要自定义拦截器需要实现com.opensymphony.xwork2.interceptor.Interceptor接口:
public class PermissionInterceptor implements Interceptor {
   private static final long serialVersionUID = -5178310397732210602L;
   public void destroy() {
   }
   public void init() {
   }
   public String intercept(ActionInvocation invocation) throws Exception {
  System.out.println(" 进入拦截器 ");
if(session 里存在用户){
String result = invocation.invoke();
}else{
return logon;
}
//System.out.println(" 返回值:"+ result);
//return result;
    }
}
 
 
 
 
package name="itcast" namespace="/test" extends="struts-default">
<interceptors>
           <interceptor name=“permission" class="cn.itcast.aop.PermissionInterceptor" />
           <interceptor-stack name=" permissionStack">
   <interceptor-ref name=" defaultStack" />
  <interceptor-ref name=" permission " />
            </interceptor-stack>
  </interceptors>
<action name="helloworld_*" class="cn.itcast.action.HelloWorldAction" method="{1}">
<result name="success">/WEB-INF/page/hello.jsp</result>
<interceptor-ref name="permissionStack"/>
</action>
</package>
因为struts2中如文件上传,数据验证,封装请求参数到action等功能都是由系统默认的defaultStack中的拦截器实现的,所以我们定义的拦截器需要引用系统默认的defaultStack,这样应用才可以使用struts2框架提供的众多功能。
如果希望包下的所有action都使用自定义的拦截器,可以通过<default-interceptor-ref name=“permissionStack”/>把拦截器定义为默认拦截器。注意:每个包只能指定一个默认拦截器。另外,一旦我们为该包中的某个action式指定了某个拦截器,则默认拦截器不会起作用。
 
 
 
 
 
 
 
 
 
 
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值