Java之struts2框架学习

About Struts2

Struts也是一款MVC框架 , Struts2是Struts的下一代产品,是在Struts1和WebWork的技术基础上进行了合并的全新的Struts2框架
其全新的Struts2的体系结构与Struts1的体系结构差别巨大。Struts2以WebWork为核心
Struts2=Struts1+WebWork,而WebWork的核心就是XWork。

XWork提供了很多核心功能:前端拦截机(interceptor),运行时表单属性验证,类型转换,强大的表达式语言(OGNL—the Object Navigation Language),IOC(Inversion of Control 反转控制)容器等。

Struts2 路由配置方式

1、StrutsPrepareAndExecuteFilter

第一种是通过StrutsPrepareAndExecuteFilter,它是Struts2的核心控制器,也是一个Filter,配置/*会拦截所有请求,通过之后转发给Struts2框架做请求处理


        struts
        org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter


        struts
        /*

而这样就是全局都是走struts2的路由了

2、ActionServlet

还有一种配置如下,通过ActionServlet并配置*.do后缀来匹配请求,将.do的请求交给ActionServlet做处理,最终交给Struts2框架

  
    action
    *.do
  
 
    action
    org.apache.struts.action.ActionServlet
    
      config
      
      	  /WEB-INF/struts-config.xml
        	...
          
    
    
      application
      ApplicationResources
    
  

这样操作,就可以自定义一些servlet,从而不走struts2框架进行处理,同时也可以融入SpringMVC,审计时也会遇到SpringMVC+Struts2两个MVC框架做路由的处理。application的配置是说明你的资源包的名字是ApplicationResources.properties,这个一般有关于struts-config.xml文件中的message-resources标签

struts-config.xml

是struts的根元素,它主要有8个子元素,DTD定义如下:


data-sources

Data-sources元素用来配置应用程序所需要的数据源。java语言提供了javax.sql.DateSource接口,所有数据源必须实现该接口。如下配置:


  
    ………………
  

在action中访问方式如下: ataSource = getDataSource(request,"a");

javax.sql.DataSource dataSource;
java.sql.Connection myConnection;
try
{
  dataSource = getDataSource(request);
  myConnection = dataSource.getConnection();
}

form-beans

该元素主要用来配置表单验证的类。它包含如下属性:
  1. classname:一般用得少,指定和form-bean无素对应的配置类,默认为org.apache.struts.config.FormBeanConfig,如果自定义,则必须扩展FormBeanConfig类。可有可无。
  2. name:ActionForm Bean的惟一标识。必须。
  3. type:ActionForm的完整类名。必须。


  
  

像是表单名称与type指定的类进行一个绑定,一般type指定的类会继承ActionForm类,ActionForm是struts2中的核心组件之一,用来处理表单数据,本质是一个javabean。

其中自带validate()方法和reset()方法是 ActionForm中两种可以覆盖的方法。validate()方法中定义具体的 ActionForm验证规则。reset()方法则是在初始化时被调用。

action-mappings

描述从特定的请求路径到相应的Action类的映射。该元素用于将Action元素定义到ActionServlet类中,它含有0到多个元素

其格式如下:


  
  

每个action子元素可包含一个或多个forward子元素。除了path、type和name属性外,action还具有如下属性:

scope:指定ActionForm Bean的作用域(session和request),缺省为session。(可选);

input:当Bean发生错误时返回的路径,在validate验证框架中错误显示的页面(可选);

classname:指定一个调用这个Action类的ActionMapping类的全名。缺省用org.apache.struts.action.ActionMapping(可选);

include:如果没有forward的时候,它起forward的作用(可选);

validate:若为true,则会调用ActionForm的validate()方法或调用validate验证,否则不调用,缺省为true(可选)。

forward属性也是可选的。
例如


    
		
		

首先当我们访问/LoginAction.do时会找到对应的com.action.LoginAction#execute()方法做逻辑处理,一般其中以action来做为具体功能的名称来指定forward路由和功能逻辑,比如访问/LoginAction.do?action=a就会进入LoginAction#execute()方法做处理,一般会有if等逻辑,比如判断当action=a时在处理完当前逻辑后,最终会return mapping.findForward("list");会转发到在struts-config.xmlforward下配置的路由也就是path="/a/a.jsp"

global-forwards

该元素主要用来声明全局的转发关系,它具有以下四个属性:

  1. className:和forward元素对应的配置类,默认为:org.apache.struts.action.ActionForward。可有可无。
  2. contextRelative:此项为true时,表时path属性以"/"开头,相对于当前上下文的URL,默认为false.可有可无。 
  3. name:转发路径的逻辑名.必填。
  4. path:转发或重定向的URL,当contextRelative=false时,URL路径相对于当前应用(application),当为ture时,表示URL路径相对于当前上下文(context)。
  5. redirect:当此项为ture时,表示执行重定向操作。当此项为false时表示转向操作。默认为false。


  
  

和action-mappings的区别是,global是全局转发

message-resources元素

主要配置本地化消息文本,它具有以下属性。

  1. className:和message-resources元素对应的配置类,默认为org.apache.struts.config.MessageResourcesConfig。
  2. factory:指定消息资源的工厂类,默认为:org.apache.struts.util.PropertyMessageResourcesFactory类
  3. key:指定Resource Bundle存放的ServletContext对象中时采用的属性Key,默认由Globals.MESSAGES_KEY定义的字符串常量,只允许一个Resource Bundle采用默认的属性Key。
  4. null:指定MessageSources类如何处理未知消息的key,如果为true,则返回空字符串,如果为false,则返回相关字串,默认为false
  5. prameter:指定MessageSources的资源文件名,如果为:a.b.ApplicationResources,则实际对应的文件路径为:WEB-INF/classes/a/b/ApplicationResources.properties.



访问为:



Action

一个Action业务里可以实现Action接口,也可以继承ActionSupport类。在ActionSupport中提供了一些实现好的业务方法。在以后的编程中,建议全部继承ActionSupport类。
Action中的方法必须返回一个String类型的字符串,这个字符串与struts.xml中result标签的name属性相对应,struts.xml会根据返回的字符串查找对应的页面。

Action中execute方法必须返回一个String类型字符串,用于后续与struts.xml配置中的result标签的name属性对应完成对应的页面返回

默认提供了5个常用的结果常量String SUCCESS = "success"; String NONE = "none"; String ERROR = "error"; String INPUT = "input"; String LOGIN = "login";

import com.opensymphony.xwork2.Action;
  
  public class HelloWorldAction implements Action{
    //请求中传递的参数和返回给页面的值都定义成属性

    private String username;
    private String message;
    //getter/setter方法
    @0verride
    public String execute()throws Exception{
      //查看请求中传递的参数
      System.out.println(username);



      //改变这个message,会自动传递给页面	
      message="hello:"+username;
        //SUCCESS是Action中的常量,值是success 
        return SUCCESS;
    }

下面来看下在StrutsPrepareAndExecuteFilter下如何配置路由,假如有如下action类

package action;

import com.opensymphony.xwork2.Action;

public class HelloWorldAction implements Action{
    //请求中传递的参数和返回给页面的值都定义成属性
    private String username
    private String password  
//getter/setter方法
@Override
public String execute() throws Exception{
//查看请求中传递的参数
System.out.print1n(username);
//改变这个message,会自动传递给页面
    message="hello:"+username;
//SUCCESS是Action中的常量,值是success
    return SUCCESS;
}}

Struts.xml

这种配置方式一般会存在一个struts.xml的配置文件







    
    
        
        index.jsp
    


而比如在login.jsp中有如下表单,当在登陆时提交表单,action触发的事件会将请求交给HelloWorldAction#execute()处理,而如果登陆验证成功,返回success就会根据struts.xml的配置会返回index.jsp

id: username:

关于后缀,struts2默认支持.action后缀,需要配置其他后缀则需要在struts.xml进行如下配置


同时在struts.xml可以配置默认action,当找不到对应的action时则匹配默认action

对当前的package有效。
action标签的clas省略将调用ActionSupport类。result的name省略将默认为success。
注意default-action-re必须在所有的action标签上面。



error.jsp

constant标签

constant用来配置常量。name属性是常量名,value属性是常量值。

<!--设置请求后缀-->

<!--设置编码,解决中文乱码-->

<!--设置struts标签主题-->

package标签

package是包。Struts2的package与java中的package类似,可以把同一个业务模块的action和result集中到一个包中,方便管理。不同的是Struts2的包可以继承。通常都会继承struts-default。在struts-default中定义了大量的struts特性,如拦截器和参数处理的功能,如果不继承struts-default,会遇到参数无法绑定或找不到action类。

name属性是包的名字,一个struts.xml中可以有很多个package,通过name属性进行区分。

namespace是命名空间,/代表的是根目录。namespace的作用类似于SpringMVC中在Controller类上加@RequestMapping注解。相当于此包中所有的action前都加一个父路径。

比如下面第一行配置了跟路径是/而后续访问action就是/login.cation



action标签

action标签用来处理请求和响应结果。
name属性是请求的名字,此处不需要加.action。同一个package下的action不能重名。
class属性指定处理该请求的类,是类的全路径。默认的处理请求时会去类中找名为execute的方法。如果不指定class,将默认ActionSupport为处理请求的类。
result标签用来处理请求结果,name属性是Action类中返回的字符串。标签的值是要跳转的页面地址。name如果不写的话,默认是success。


<--success是Action类中返回的字符串,根据不同字符串返回不同的页面-->
index.jsp
error.jsp1ogin.jsp


Action配置自定义业务

Action默认以execute为入口方法处理,当然也可以通过struts.xml修改配置来达到不用execute方法

package action;import com.opensymphony.xwork2.ActionSupport;
/∥继承ActionSupport类
public class UserAction extends ActionSupport{
//处理登录
public String 1ogin(){
//参数和业务略
System.out.println("我是登录");
    return SUCCESS;
//处理注册
public String regist(){
//参数和业务略
System.out.println("我是注册");
        return SUCCESS;
}

Struts.xml配置,method="login"表示要调用类中的login方法处理请求。如果找不到login0方法,Struts2会在类中查找doLogin)方法。如果都找不到,将会报错。




index.jsp<!--登录成功去首页-->
1ogin.jsp<!--登录失败回登录页-->


index.jsp<!--注册成功去首页-->
regist.jsp<!--注册失败回登录页-->


Action动态方法与通配符

如果一个类中有多个业务方法,又不想给每个业务方法都配置一个action标签,可以使用动态党法调用,

语法:请求名!方法名.action

当请求的格式是user!login.action时,代表调用UserAction中的login方法处理当前请求。

<!--允许调用动态方法-->

action配置

<!--允许动态调用的方法,新版里新增的设置-->
1ogin,regist

/index.jsp<!--成功去首页-->
/error.jsp<!--失败去错误-->

通配符

<!--设置useraction中允许通配符匹配的方法-->
login,regist
  <!--method属性中匹配方法名-->

/index.jsp
{1}.jsp<!--失败了就返回原来的页面-->

User匹配所有以User结尾的请求,method={1}中的{1}匹配的就是 User中的。如果请求的地址是loginUser.action,那么{1}匹配的就是login,就会去类中调用login方法,并返回相应的结果。

Result

类型有dispatcher、redirect、redirectAction、chain

dispatcher

result的默认类型就是dispatcher。就是转发,在result标签的type属性中设置

index.jsp
index.jsp

redirect

redirect是重定向,重定向之后,当前请求中的参数和属性在下一个页面或请求中将不能使用。

index.jsp

redirectAction

redirectAction与redirect类似,不过redirectAction是重定向到某一个action


1ogin.action
regist.jsp

如果要调用不同package下的action,需要在result中传参数:



<!--调用不同package下的action-->
/
hel1o.action
<!--传递其它参数-->
123

    login.jsp

chain

chain类型可以共享当前request


<!--注意chain的action后面没有后缀-->
login
regist.jsp

动态获取返回结果

private String username;private String page;
//getter/setter方法略
public String 1ogin(){
//参数和业务略
System.out.print1n("我是登录")
  if("admin".equals(username))
{
    //管理员去管理页
    page="admin-page";
    
    }else{//其他人去用户页
    page="user-page";
    return SUCCESS;
}

result配置


<!--读取action中的属性值,返回不同页面-->
${page}.jsp
login.jsp

validate方法

ActionSupport,ActionSupport中有一个validate方法可以进行校验操作,只需要重写该方法即可实现校验功能。

public class ValidateAction extends ActionSupport {
    private String username;//用户名不能为空,并且长度要大于6

    @Override
    public void validate() {
        System.out.println("validate()");
        if (username == null || username.trim().length() < 6) {
            addFieldError("username", "必须输入用户名,长度大于6");
        }
    }
}

addFieldError要求必须给result配置一个input类型的结果。所以在调用logout方法时,会报找不到result input。


  main.jsp
  val.jsp

validate方法会验证当前Action类中所有的方法,如果只想验证其中的一个方法,可以使用validatexxx方法,其中xxx是被验证的方法名,首字母大写。

//只验证1ogin方法,不验证其它方法
public void validatelogin(){
if(username==nul1 ll username.1ength()==0){
//向页面中添加错误信息
addFieldError("username",“用户名不能为空”);

对某一个Action类进行校验会用到验证框架

验证框架是把验证信息都写在xm文件中,对某一个Action类进行验证,需要在Action类的同一个包下创建xml文件,文件命名为Action类的类名validation.xml

validators标签:在校验框架中,所有的验证都写在validators标签中field标签:每一个需要验证的属性都是一个field标签,name指定要验证那个属性。
field-validator标签:代表一种验证规则,通过type指定规则。






    
        
            必须输入用户名
        
        
            6
            长度必须大于${minLength}
        
    

interceptor拦截器

类似于filter在请求进入action前作预处理

自定义拦截器类需要实现Interceptor接口或者继承AbstractIntercepter,拦截逻辑主要在intercept方法中,该方法返回一个字符串作为逻辑视图,系统根据返回的字符串跳转到对应的视图资源。每拦截一个动作请求,该方法就会被调用一次。

import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.Interceptor;

public class TimeInterceptor implements Interceptor {

    @Override
    public void destroy() {

    }

    @Override
    public void init() {

    }

    @Override
    public String intercept(ActionInvocation actionInvocation) throws Exception {
        		//前处理
            System.out.println("MyInterceptor3 的前处理!");
            //放行
            String result = invocation.invoke();
            //后处理
            System.out.println("MyInterceptor3 的后处理!");
        return result;
    }

在struts.xml中配置拦截器


  
    定义拦截器
    
    
    定义拦截器栈
    将多个拦截器绑定到一起,只需要引用拦截器栈即可。
    
      
      
      
    
  
  
    /login.jsp
  

给action添加拦截器饮用



index.jsp

使用自定义拦截器会造成参数无法读取,这时候可以引入struts自带的拦截器。

你可能感兴趣的:(java,struts,java)