码迷,mamicode.com
首页 > 其他好文 > 详细

Params 拦截器

时间:2015-04-07 15:14:43      阅读:140      评论:0      收藏:0      [点我收藏+]

标签:

parameters 拦截器将把表单字段映射到 ValueStack 栈的栈顶对象的各个属性中. 如果某个字段在模型里没有匹配的属性, Param 拦截器将尝试 ValueStack 栈中的下一个对象
技术分享
ParametersInterceptor 拦截器源码:
public class ParametersInterceptor extends MethodFilterInterceptor {
  
    @Override
    public String doIntercept(ActionInvocation invocation) throws Exception {
        Object action = invocation.getAction();
        if (!(action instanceof NoParameters)) { 
            if (parameters != null) {
                
                try {
                     
                    ValueStack stack = ac.getValueStack();
                    //设置值栈的对象属性值
                    setParameters(action, stack, parameters);
                } finally {
                      ReflectionContextState.setCreatingNullObjects(contextMap, false);
                    ReflectionContextState.setDenyMethodExecution(contextMap, false);
               //如果发生转换异常错误就去设置通知这个类型转换错误消息 去  ConversionErrorInterceptor拦截器
                    ReflectionContextState.setReportingConversionErrors(contextMap, false);
                }
            }
        }
        return invocation.invoke();
    }
 
    protected void setParameters(Object action, ValueStack stack, final Map<String, Object> parameters) {
        
        for (Map.Entry<String, Object> entry : acceptableParameters.entrySet()) {
            String name = entry.getKey();
            Object value = entry.getValue();
            try {
               //设置name属性对应的value
                newStack.setParameter(name, value);
            } catch (RuntimeException e) {
                if (devMode ) { 
                }
            }
        }

        if (clearableStack && (stack.getContext() != null) && (newStack.getContext() != null))
          //如果发生类型转换错误就值栈中添加类型转换CONVERSION_ERRORS
            stack.getContext().put(ActionContext.CONVERSION_ERRORS , newStack.getContext().get(ActionContext.CONVERSION_ERRORS));

        addParametersToContext(ActionContext.getContext(), acceptableParameters);
    }
  
}


在 class OgnlValueStack中

private void setValue (String expr, Object value, boolean throwExceptionOnFailure, boolean evalExpression) {
        Map<String, Object> context = getContext();
        try {
            //尝试为属性赋值调用trySetValue
            trySetValue(expr, value, throwExceptionOnFailure, context, evalExpression);
        } catch (OgnlException e) {
            handleOgnlException(expr, value, throwExceptionOnFailure, e);
        } catch (RuntimeException re) { //XW-281
            handleRuntimeException(expr, value, throwExceptionOnFailure, re);
        } finally {
            cleanUpContext(context);
        }
    }


 private void trySetValue(String expr, Object value, boolean throwExceptionOnFailure, Map<String, Object> context, boolean evalExpression) throws OgnlException {
        context.put(XWorkConverter.CONVERSION_PROPERTY_FULLNAME , expr);
        context.put( REPORT_ERRORS_ON_NO_PROP, (throwExceptionOnFailure) ? Boolean.TRUE : Boolean.FALSE);
        ognlUtil.setValue(expr, context, root, value, evalExpression);
    }



Class ognlUtil类中 调用ognlUtil.setValue(expr, context, root, value, evalExpression);

 protected void setValue(String name, Map<String, Object> context, Object root, Object value, boolean evalName) throws OgnlException {
        Object tree = compile(name);
        if (!evalName && isEvalExpression(tree, context)) {
            throw new OgnlException("Eval expression cannot be used as parameter name");
        }
        //最终为属性设置值的还是ognl的setValue 如果方式类型转换异常就会向上抛出OgnlException 
        //会被OgnlValueStack中setValue 方法捕获异常 然后设置到handleOgnlException中,这时会在控制台打印异常信息
        Ognl. setValue(tree, context, root, value);
    }


 private void handleOgnlException(String expr, Object value, boolean throwExceptionOnFailure, OgnlException e) {
        String msg = "Error setting expression ‘" + expr + "‘ with value ‘" + value + "‘";
     在控制台打印异常信息
        if (LOG .isWarnEnabled()) {
            LOG.warn(msg, e);
        }
        if (throwExceptionOnFailure) {
            throw new XWorkException(msg, e);
        }
    }



当发生异常的情况下会调用ConversionErrorInterceptor
以下是ConversionErrorInterceptor拦截器 源码:
    public String intercept(ActionInvocation invocation) throws Exception {

        ActionContext invocationContext = invocation.getInvocationContext();
        Map<String, Object> conversionErrors = invocationContext.getConversionErrors();
        ValueStack stack = invocationContext.getValueStack();

        HashMap<Object, Object> fakie = null;

        for (Map.Entry<String, Object> entry : conversionErrors.entrySet()) {
            String propertyName = entry.getKey();
            Object value = entry.getValue();

            if (shouldAddError(propertyName, value)) {
               //去资源文件中查找对应的(由TextProvider提供) 错误消息设置(主要是为了提示用户错误信息)
                String message = XWorkConverter.getConversionErrorMessage(propertyName, stack);

                Object action = invocation.getAction();
                if (action instanceof ValidationAware) {
                    这里是判断请求的action是否实现了ValidationAware接口
                    ValidationAware va = (ValidationAware) action;
                    如果实现了,就向这个action添加一条错误消息
                    va.addFieldError(propertyName, message);
                }

                if (fakie == null) {
                    fakie = new HashMap<Object, Object>();
                }

                fakie.put(propertyName, getOverrideExpr(invocation, value));
            }
        }
 
        return invocation.invoke();
    }
补充:
在xwork包定义的错误信息显示

xwork.error.action.execution=Error during Action invocation
xwork.exception.missing-action=There is no Action mapped for action name {0}.
xwork.exception.missing-package-action=There is no Action mapped for namespace {0} and action name {1}.
xwork.default.invalid.fieldvalue=Invalid field value for field "{0}".

Params 拦截器

标签:

原文地址:http://www.cnblogs.com/lflx/p/4398162.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!