Struts2-疑难杂症之Validator返回input视图

本文详细解析struts2验证原理及解决验证返回input视图的方法,包括通过实现ValidationWorkflowAware接口动态设置返回视图名称,提供实例演示。
 在这里我不说struts2的验证原理以及语法,我只讲一下关于struts2验证返回input视图的解决办法。
      当然如果你是使用一个方法对一个类,则不存在上面的问题,当然一个方法对应一个类,这种方式虽然可读性很高但是实际开发确实不可取,因为他会使类极具增加。如果你是使用一个类对应多个方法,你肯定碰到过这样一个问题,那就是验证时返回input视图,struts2默认验证失败返回input视图,但是我们在写程序中经常会有多个方法需要验证,打个比方如:create、update这两个操作一般情况下都会验证,但是我们把它写在一个类中,我们如果区分验证失败后,到底是create失败了还是update失败了呢?这个时候有没有怀疑过struts2,呵呵。
      当然struts2其时已经给了我们解决办法,如果你是一个细心的人读过struts2源码便过发现struts2是如何解决问题的,在这里我也简单的分析一下struts2的源码,大家请看下面这个类。
<!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--> package  com.opensymphony.xwork2.interceptor;

import  com.opensymphony.xwork2.Action;
import  com.opensymphony.xwork2.ActionInvocation;
import  com.opensymphony.xwork2.ValidationAware;
import  com.opensymphony.xwork2.interceptor.annotations.InputConfig;
import  com.opensymphony.xwork2.util.logging.Logger;
import  com.opensymphony.xwork2.util.logging.LoggerFactory;

import  java.lang.reflect.Method;

public   class  DefaultWorkflowInterceptor  extends  MethodFilterInterceptor {

    
private   static   final   long  serialVersionUID  =   7563014655616490865L ;

    
private   static   final  Logger LOG  =  LoggerFactory.getLogger(DefaultWorkflowInterceptor. class );

    
private   static   final  Class[] EMPTY_CLASS_ARRAY  =   new  Class[ 0 ];

    
// 默认返回input视图,是在这里定义的
     private  String inputResultName  =  Action.INPUT;
    
    
// 可以在这里更改,一般没有人会这么做
     public   void  setInputResultName(String inputResultName) {
        
this .inputResultName  =  inputResultName;
    }

    @Override
    
protected  String doIntercept(ActionInvocation invocation)  throws  Exception {
        Object action 
=  invocation.getAction();

        
if  (action  instanceof  ValidationAware) {
            ValidationAware validationAwareAction 
=  (ValidationAware) action;

            
if  (validationAwareAction.hasErrors()) {
                
if  (LOG.isDebugEnabled()) {
                    LOG.debug(
" Errors on action  "   +  validationAwareAction  +   " , returning result name 'input' " );
                }
                
// one
                String resultName  =  inputResultName;
                
/*
                在这里大家读一下源码即可明白,当前处理的Action如果是一个ValidationWorkflowAware类型的,
                则调用他的getInputResultName作用返回值
                为了方便我直接把ValidationWorkflowAware放在下面的注释中,大家看他是一个接口,
                也就是说如果我们的Action实现了ValidationWorkflowAware接口
                他则会调用getInputResultName方法返回的值,而非input,而默认的ActionSupport没有实现这个接口,我们需要手动实现

                
*/
                
// package com.opensymphony.xwork2.interceptor;
                
// public interface ValidationWorkflowAware {
                    
//  String getInputResultName();
                
// }

                
if  (action  instanceof  ValidationWorkflowAware) {
                    resultName 
=  ((ValidationWorkflowAware) action).getInputResultName();
                }
                
// 这里不做讲述
                InputConfig annotation  =  action.getClass().getMethod(invocation.getProxy().getMethod(), EMPTY_CLASS_ARRAY).getAnnotation(InputConfig. class );
                
if  (annotation  !=   null ) {
                    
if  ( ! annotation.methodName().equals( "" )) {
                        Method method 
=  action.getClass().getMethod(annotation.methodName());
                        resultName 
=  (String) method.invoke(action);
                    } 
else  {
                        resultName 
=  annotation.resultName();
                    }
                }
                
return  resultName;
            }
        }

        
return  invocation.invoke();
    }

}
      大家看到上面是不是已经恍然大悟了,呵呵,是的我们实现了ValidationWorkflowAware接口之后,只需要定义一个inputResultName属性生成了对应的get、set方法是不是就对应有了getInputResultName,而这个属性的值我们可以动态传入一个值进来,呵呵,大家看下面这个实例。

<!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

-->
public   abstract   class  ActionSupport  extends
        com.opensymphony.xwork2.ActionSupport 
implements  Result,
        ValidationWorkflowAware {

    
private   static   final   long  serialVersionUID  =   799075559195465128L ;

    
public   static   final   int  ERROR_MSG  =   - 1 ;
    
public   static   final   int  WARN_MSG  =   0 ;
    
public   static   final   int  SUCCESS_MSG  =   1 ;

    
public   static   long  getSerialversionuid() {
        
return  serialVersionUID;
    }

    
private  ActionContext actionContext;
    
private  Object id;
    
private  Pagination pagn  =   new  Pagination();
    
private  QueryResult <?>  results;
    
private  String inputResultName;

    
/**
     * 初始化ActionContext对象
     
*/
    
public  ActionSupport() {
        actionContext 
=  ActionContext.getContext();
    }

    
/**
     * 
     * 
@return  ActionContext对象
     
*/
    
public  ActionContext getActionContext() {
        
return  actionContext;
    }

    
/**
     * 
     * 
@return  Struts封装后的ServletContext对象。
     
*/
    
public  Map < String, Object >  getApplication() {
        
return  actionContext.getApplication();
    }

    
/**
     * 
     * 
@return  取得标识。
     
*/
    
public  Object getId() {
        
return  id;
    }

    
/**
     * 取得指定类型的标识。
     * 
     * 
@param  <E>
     * 
@param  c
     * 
@return
     
*/
    @SuppressWarnings(
" unchecked " )
    
public   < E >  E getId(Class < E >  c) {
        
return  (E) id;
    }

    
/**
     * 
     * 
@return  输出对象。
     * 
@throws  IOException
     
*/
    
public  PrintWriter getOut()  throws  IOException {
        
return  getResponse().getWriter();
    }

    
/**
     * 
     * 
@return  分页参数对象。
     
*/
    
public  Pagination getPagn() {
        
return  pagn;
    }

    
/**
     * 
     * 
@return  HttpServletRequest对象。
     
*/
    
public  HttpServletRequest getRequest() {
        
return  ServletActionContext.getRequest();
    }

    
/**
     * 
     * 
@return  HttpServletResponse对象。
     
*/
    
public  HttpServletResponse getResponse() {
        
return  ServletActionContext.getResponse();
    }

    
/**
     * 
     * 
@return  查询结果集。
     
*/
    
public  QueryResult <?>  getResults() {
        
return  results;
    }

    
/**
     * 
     * 
@return  ServletContext对象。
     
*/
    
public  ServletContext getServletContext() {
        
return  (ServletContext)  this .actionContext
                .get(StrutsStatics.SERVLET_CONTEXT);
    }

    
/**
     * 
     * 
@return  Struts封装后的HttpSession对象。
     
*/
    
public  Map < String, Object >  getSession() {
        
return  actionContext.getSession();
    }

    
/**
     * 
     * 
@return  Struts的ValueStack对象。
     
*/
    
public  ValueStack getValueStack() {
        
return  ServletActionContext.getValueStack(getRequest());
    }

    
/**
     * 向ActionContext中添加一个信息,此信息会保存到HttpServletRequest中。
     * 
     * 
@param  key
     *            键。
     * 
@param  value
     *            值。
     
*/
    
public   void  put(String key, Object value) {
        actionContext.put(key, value);
    }

    
public   void  setActionContext(ActionContext actionContext) {
        
this .actionContext  =  actionContext;
    }

    
/**
     * 
     * 
@param  id
     *            设置标识。
     
*/
    
public   void  setId(Object id) {
        
this .id  =  id;
    }

    
/**
     * 
     * 
@param  pagn
     *            设置分页参数对象。
     
*/
    
public   void  setPagn(Pagination pagn) {
        
this .pagn  =  pagn;
    }

    
/**
     * 
     * 
@param  results
     *            设置返回的结果集。
     
*/
    
protected   void  setResults(QueryResult <?>  results) {
        
this .results  =  results;
    }

    
public  String getInputResultName() {
        
return  inputResultName;
    }

    
public   void  setInputResultName(String inputResultName) {
        
this .inputResultName  =  inputResultName;
    }

    
public   abstract  String show()  throws  Exception;

    
public   abstract  String edit()  throws  EditFailureException;

    
public   abstract  String destroy()  throws  DestroyFailureException;

    
public   abstract  String create()  throws  CreateFailureException;

    
public   abstract  String deleteConfirm()  throws  DeleteFailureException;

    
public   abstract  String index()  throws  Exception;

    
public   abstract  String update()  throws  UpdateFailureException;

    
public   abstract  String editNew()  throws  EditFailureException;
}
      上面是我自定义一个ActionSupport类,该类实现了ValidationWorkflowAware,并重写了getInputResultName方法。然后我再定义一个Action继承了该类。
<!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--> @Namespace(value  =   " /test " )
@Action(params 
=  {  " actionName " " demo "  })
@Results( {
        @Result(name 
=   " xx " , type  =   " redirect " , location  =   " http://www.google.com " ),
        @Result(name 
=   " hello " , type  =   " redirect " , location  =   " http://www.baidu.com " ) })
@SuppressWarnings(
" serial " )
public   class  DownloadController  extends  ActionSupport {

    
public  String index() {
        System.out.println(
" -------index----------- " );
        
return   " xx " ;
    }

    
public   void  validateIndex() {
        addFieldError(
" hell " " .my hello. " );
        System.out.println(
" ok " );
    }
    
// ..省略了其它无关方法
}
      在上面我就只是做了一个简单了模拟验证然后跳转到指定的页面。这里你可以这样请求,测试一个最终struts2是否调用了getInputResultName方法并使用其返回值,作为返回视图的名称:http://地址:端口/project/test/demo!index.action?inputResultName=hello,大家测试如果跳转到了baidu就说明成功了。
      至此,有问题可以留言。


转载地址,onlyeffort.QQ:501276913  http://www.blogjava.net/grasszring/archive/2010/06/08/323092.html
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值