struts2源码分析1(part2)
转: http://blog.csdn.net/accpsz/archive/2010/12/31/6108917.aspx
//returnaboveandflowthroughagain
if(!executed){
//在Result返回之前调用preResultListeners
if(preResultListeners!=null){
for(Iteratoriterator=preResultListeners.iterator();
iterator.hasNext();){
PreResultListenerlistener=(PreResultListener)iterator.next();
String_profileKey="preResultListener:";
try{
UtilTimerStack.push(_profileKey);
listener.beforeResult(this,resultCode);
}
finally{
UtilTimerStack.pop(_profileKey);
}
}
}
//nowexecutetheresult,ifwe'resupposedto
if(proxy.getExecuteResult()){
executeResult();
}
executed=true;
}
returnresultCode;
}
finally{
UtilTimerStack.pop(profileKey);
}
}StringmethodName=proxy.getMethod();
StringtimerKey="invokeAction:"+proxy.getActionName();
try{
UtilTimerStack.push(timerKey);
booleanmethodCalled=false;
ObjectmethodResult=null;
Methodmethod=null;
try{
//获得需要执行的方法
method=getAction().getClass().getMethod(methodName,newClass[0]);
}catch(NoSuchMethodExceptione){
//如果没有对应的方法,则使用do+Xxxx来再次获得方法
try{
StringaltMethodname="do"+methodName.substring(0,1).toUpperCase()+methodName.substring(1);
method=getAction().getClass().getMethod(altMethodName,newClass[0]);
}catch(NoSuchMethodExceptione1){
//well,givetheunknownhandlerashot
if(unknownHandler!=null){
try{
methodResult=unknownHandler.handleUnknownActionMethod(action,methodName);
methodCalled=true;
}catch(NoSuchMethodExceptione2){
//throwtheoriginalone
throwe;
}
}else{
throwe;
}
}
}
if(!methodCalled){
methodResult=method.invoke(action,newObject[0]);
}
//根据不同的Result类型返回不同值
//如输出流Result
if(methodResultinstanceofResult){
this.explicitResult=(Result)methodResult;
returnnull;
}else{
return(String)methodResult;
}
}catch(NoSuchMethodExceptione){
thrownewIllegalArgumentException("The"+methodName+"()isnotdefinedinaction"+getAction().getClass()+"");
}catch(InvocationTargetExceptione){
//Wetrytoreturnthesourceexception.
Throwablet=e.getTargetException();
if(actionEventListener!=null){
Stringresult=actionEventListener.handleException(t,getStack());
if(result!=null){
returnresult;
}
}
if(tinstanceofException){
throw(Exception)t;
}else{
throwe;
}
}finally{
UtilTimerStack.pop(timerKey);
}
}//根据ResultConfig创建Result
result=createResult();
StringtimerKey="executeResult:"+getResultCode();
try{
UtilTimerStack.push(timerKey);
if(result!=null){
//这儿正式执行:)
//可以参考Result的实现,如用了比较多的ServletDispatcherResult,ServletActionRedirectResult,ServletRedirectResult
result.execute(this);
}elseif(resultCode!=null&&!Action.NONE.equals(resultCode)){
thrownewConfigurationException("Noresultdefinedforaction"+getAction().getClass().getName()
+"andresult"+getResultCode(),proxy.getConfig());
}else{
if(LOG.isDebugEnabled()){
LOG.debug("Noresultreturnedforaction"+getAction().getClass().getName()+"at"+proxy.getConfig().getLocation());
}
}
}finally{
UtilTimerStack.pop(timerKey);
}
}
publicResultcreateResult()throwsException{
if(explicitResult!=null){
Resultret=explicitResult;
explicitResult=null;;
returnret;
}
ActionConfigconfig=proxy.getConfig();
Mapresults=config.getResults();
ResultConfigresultConfig=null;
synchronized(config){
try{
//根据result名称获得ResultConfig,resultCode就是result的name
resultConfig=(ResultConfig)results.get(resultCode);
}catch(NullPointerExceptione){
}
if(resultConfig==null){
//如果找不到对应name的ResultConfig,则使用name为*的Result
resultConfig=(ResultConfig)results.get("*");
}
}
if(resultConfig!=null){
try{
//参照StrutsObjectFactory的代码
Resultresult=objectFactory.buildResult(resultConfig,invocationContext.getContextMap());
returnresult;
}catch(Exceptione){
LOG.error("Therewasanexceptionwhileinstantiatingtheresultoftype"+resultConfig.getClassName(),e);
thrownewXWorkException(e,resultConfig);
}
}elseif(resultCode!=null&&!Action.NONE.equals(resultCode)&&unknownHandler!=null){
returnunknownHandler.handleUnknownResult(invocationContext,proxy.getActionName(),proxy.getConfig(),resultCode);
}
returnnull;
}
//StrutsObjectFactory
publicResultbuildResult(ResultConfigresultConfig,MapextraContext)throwsException{
StringresultClassName=resultConfig.getClassName();
if(resultClassName==null)
returnnull;
//创建Result,因为Result是有状态的,所以每次请求都新建一个
Objectresult=buildBean(resultClassName,extraContext);
//这句很重要,后面将会谈到,reflectionProvider参见OgnlReflectionProvider;
//resultConfig.getParams()就是result配置文件里所配置的参数<param></param>
//setProperties方法最终调用的是Ognl类的setValue方法
//这句其实就是把param名值设置到根对象result上
reflectionProvider.setProperties(resultConfig.getParams(),result,extraContext);
if(resultinstanceofResult)
return(Result)result;
thrownewConfigurationException(result.getClass().getName()+"doesnotimplementResult.");
}privateUseruser;
privateMapcontext;
@Before
publicvoidsetUp()throwsException{
}
@Test
publicvoidognlGetValue()throwsException{
reset();
Assert.assertEquals("myyate",Ognl.getValue("name",user));
Assert.assertEquals("cares",Ognl.getValue("dept.name",user));
Assert.assertEquals("myyate",Ognl.getValue("name",context,user));
Assert.assertEquals("contextmap",Ognl.getValue("#name",context,user));
Assert.assertEquals("parker",Ognl.getValue("#pen",context,user));
}
@Test
publicvoidognlSetValue()throwsException{
reset();
Ognl.setValue("name",user,"myyateC");
Assert.assertEquals("myyateC",Ognl.getValue("name",user));
Ognl.setValue("dept.name",user,"caresC");
Assert.assertEquals("caresC",Ognl.getValue("dept.name",user));
Assert.assertEquals("contextmap",Ognl.getValue("#name",context,user));
Ognl.setValue("#name",context,user,"contextmapC");
Assert.assertEquals("contextmapC",Ognl.getValue("#name",context,user));
Assert.assertEquals("parker",Ognl.getValue("#pen",context,user));
Ognl.setValue("#name",context,user,"parkerC");
Assert.assertEquals("parkerC",Ognl.getValue("#name",context,user));
}
publicstaticvoidmain(String[]args)throwsException{
JUnitCore.runClasses(TestOgnl.class);
}
privatevoidreset(){
user=newUser("myyate",newDept("cares"));
context=newOgnlContext();
context.put("pen","parker");
context.put("name","contextmap");
}
}
classUser{
publicUser(Stringname,Deptdept){
this.name=name;
this.dept=dept;
}
Stringname;
privateDeptdept;
publicDeptgetDept(){
returndept;
}
publicStringgetName(){
returnname;
}
publicvoidsetDept(Deptdept){
this.dept=dept;
}
publicvoidsetName(Stringname){
this.name=name;
}
}
classDept{
publicDept(Stringname){
this.name=name;
}
privateStringname;
publicStringgetName(){
returnname;
}
publicvoidsetName(Stringname){
this.name=name;
}
}